Inceptum/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModrinthModSource.java

133 lines
4.5 KiB
Java

package io.gitlab.jfronny.inceptum.launcher.system.source;
import io.gitlab.jfronny.commons.HashUtils;
import io.gitlab.jfronny.commons.cache.MemoryOperationResultCache;
import io.gitlab.jfronny.commons.tuple.Tuple;
import io.gitlab.jfronny.inceptum.common.Net;
import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.api.ModrinthApi;
import io.gitlab.jfronny.inceptum.launcher.model.modrinth.*;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
public final class ModrinthModSource implements ModSource {
private static final MemoryOperationResultCache<Tuple<String, String>, Optional<ModSource>> UPDATE_CACHE = new MemoryOperationResultCache<>(Utils.CACHE_SIZE);
private static final MemoryOperationResultCache<String, Set<ModSource>> DEPENDENCIES_CACHE = new MemoryOperationResultCache<>(Utils.CACHE_SIZE);
private final String versionId;
private final ModrinthVersion current;
private final ModrinthProject mod;
public ModrinthModSource(String versionId) throws IOException {
this.versionId = versionId;
this.current = ModrinthApi.getVersion(versionId);
this.mod = ModrinthApi.getMod(getModId());
}
@Override
public ModDownload download() throws IOException {
ModrinthVersion.File file = current.files().get(0);
Path path = getJarPath();
try {
Net.downloadFile(file.url(), file.hashes().sha1(), path);
} catch (URISyntaxException e) {
throw new IOException("Could not download file", e);
}
return new ModDownload(file.hashes().sha1(), HashUtils.murmur2(Files.readAllBytes(path)), path);
}
@Override
public Set<ModSource> getDependencies(String gameVersion) throws IOException {
return DEPENDENCIES_CACHE.get(versionId, () -> {
Set<ModSource> deps = new HashSet<>();
for (ModrinthVersion.Dependency dependency : current.dependencies()) {
//TODO show optional dependencies
if (dependency.dependency_type() == ModrinthVersion.Dependency.DependencyType.required)
deps.add(new ModrinthModSource(dependency.version_id()));
}
return Set.copyOf(deps);
});
}
@Override
public Optional<ModSource> getUpdate(String gameVersion) throws IOException {
return UPDATE_CACHE.get(Tuple.of(versionId, gameVersion), () -> {
ModrinthVersion next = ModrinthApi.getLatestVersions(getModId(), gameVersion).get(current.version_type());
if (next == null) return Optional.empty();
if (next.version_number().equals(current.version_number())) return Optional.empty();
return Optional.of(new ModrinthModSource(next.id()));
});
}
@Override
public String getVersion() {
return current.version_number();
}
@Override
public String getName() {
return "modrinth/" + getShortName() + '/' + current.version_number();
}
@Override
public String getShortName() {
return (mod.slug() == null ? mod.id() : mod.slug());
}
@Override
public String getFileName() {
return current.files().get(0).filename();
}
@Override
public String getDescription() {
return mod.body();
}
@Override
public String getSummary() {
return mod.description();
}
@Override
public boolean equals(Object obj) {
return obj instanceof ModSource ms && equals(ms);
}
@Override
public boolean equals(ModSource other) {
return other instanceof ModrinthModSource ms && ms.getModId().equals(getModId()) && ms.versionId.equals(versionId);
}
@Override
public boolean projectMatches(ModSource other) {
return other instanceof ModrinthModSource ms && ms.getModId().equals(getModId());
}
public String getVersionId() {
return versionId;
}
public String getModId() {
return current.project_id();
}
public ModrinthModpackManifest.File toManifest() throws IOException {
ModrinthVersion.File orig = current.files().get(0);
return new ModrinthModpackManifest.File(
"mods/" + orig.filename(),
new ModrinthHashes(
orig.hashes().sha1(),
orig.hashes().sha512()
),
null, // env
List.of(orig.url()),
Files.size(getJarPath())
);
}
}