1st iteration of updates

This commit is contained in:
JFronny 2021-11-02 17:25:34 +01:00
parent 6759d55f32
commit d60137a531
No known key found for this signature in database
GPG Key ID: BEC5ACBBD4EE17E5
6 changed files with 101 additions and 20 deletions

View File

@ -6,6 +6,7 @@ import io.gitlab.jfronny.inceptum.model.inceptum.source.DirectModSource;
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModrinthModSource;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Set;
@ -21,7 +22,11 @@ public class ModSourceTypeAdapter implements JsonSerializer<ModSource>, JsonDese
case "modrinth" -> {
if (!jo.has("id"))
throw new JsonParseException("Expected ModrinthModSource to contain a version ID");
yield new ModrinthModSource(jo.get("id").getAsString());
try {
yield new ModrinthModSource(jo.get("id").getAsString());
} catch (IOException e) {
throw new JsonParseException("Could not fetch Modrinth source", e);
}
}
case "curseforge" -> {
throw new JsonParseException("Curseforge sources are not yet supported"); //TODO
@ -45,7 +50,7 @@ public class ModSourceTypeAdapter implements JsonSerializer<ModSource>, JsonDese
JsonObject jo = new JsonObject();
if (src instanceof ModrinthModSource mo) {
jo.add("type", new JsonPrimitive("modrinth"));
jo.add("id", new JsonPrimitive(mo.versionId()));
jo.add("id", new JsonPrimitive(mo.getVersionId()));
}
else if (src instanceof DirectModSource di) {
jo.add("type", new JsonPrimitive("direct"));

View File

@ -4,6 +4,7 @@ import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.Set;
public record DirectModSource(String fileName, String url, Set<ModSource> dependencies) implements ModSource {
@ -22,4 +23,14 @@ public record DirectModSource(String fileName, String url, Set<ModSource> depend
public Set<ModSource> getDependencies() throws IOException {
return dependencies;
}
@Override
public Optional<ModSource> getUpdate(String gameVersion) throws IOException {
return Optional.empty();
}
@Override
public String getVersion() {
return "";
}
}

View File

@ -2,9 +2,12 @@ package io.gitlab.jfronny.inceptum.model.inceptum.source;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.Set;
public interface ModSource {
ModDownload download(Path modsDir) throws IOException;
Set<ModSource> getDependencies() throws IOException;
Optional<ModSource> getUpdate(String gameVersion) throws IOException;
String getVersion();
}

View File

@ -1,5 +1,6 @@
package io.gitlab.jfronny.inceptum.model.inceptum.source;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.modrinth.ModrinthVersion;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.ModrinthApi;
@ -7,14 +8,23 @@ import io.gitlab.jfronny.inceptum.util.api.ModrinthApi;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
//TODO auto-discover curseforge page
//TODO automatically install dependencies
public record ModrinthModSource(String versionId) implements ModSource {
public final class ModrinthModSource implements ModSource {
private final String versionId;
private final ModrinthVersion current;
public ModrinthModSource(String versionId) throws IOException {
this.versionId = versionId;
current = ModrinthApi.getVersion(versionId);
}
@Override
public ModDownload download(Path modsDir) throws IOException {
ModrinthVersion.File file = ModrinthApi.getVersion(versionId).files.get(0);
ModrinthVersion.File file = current.files.get(0);
Path path = modsDir.resolve(file.filename);
Utils.downloadFile(file.url, file.hashes.sha1, path);
return new ModDownload(file.hashes.sha1, path);
@ -23,11 +33,47 @@ public record ModrinthModSource(String versionId) implements ModSource {
@Override
public Set<ModSource> getDependencies() throws IOException {
Set<ModSource> deps = new HashSet<>();
for (ModrinthVersion.Dependency dependency : ModrinthApi.getVersion(versionId).dependencies) {
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 deps;
}
@Override
public Optional<ModSource> getUpdate(String gameVersion) throws IOException {
ModrinthVersion stable = null;
ModrinthVersion beta = null;
ModrinthVersion latest = null;
for (ModrinthVersion version : ModrinthApi.getVersions(current.mod_id)) {
//TODO sort versions
if (version.game_versions.contains(gameVersion) && version.loaders.contains("fabric")) {
if (latest == null) latest = version;
if (version.version_type == ModrinthVersion.VersionType.beta || version.version_type == ModrinthVersion.VersionType.release) {
beta = version;
}
if (version.version_type == ModrinthVersion.VersionType.release) {
stable = version;
}
}
}
ModrinthVersion next = switch (current.version_type) {
case alpha -> latest;
case beta -> beta;
case release -> stable;
};
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;
}
public String getVersionId() {
return versionId;
}
}

View File

@ -75,15 +75,14 @@ public class AddModWindow extends Window {
ModrinthVersion beta = null;
ModrinthVersion latest = null;
for (ModrinthVersion version : ModrinthApi.getVersions(mod.mod_id)) {
//TODO sort versions
if (version.game_versions.contains(instance.getMinecraftVersion()) && version.loaders.contains("fabric")) {
if (latest == null) latest = version;
if (version.version_type == ModrinthVersion.VersionType.beta) {
if (version.version_type == ModrinthVersion.VersionType.beta || version.version_type == ModrinthVersion.VersionType.release) {
beta = version;
break;
}
if (version.version_type == ModrinthVersion.VersionType.release) {
stable = version;
break;
}
}
}
@ -93,7 +92,7 @@ public class AddModWindow extends Window {
Inceptum.showError("No valid version could be identified for this mod", "Nov version found");
}
else {
download(new ModrinthModSource(latest.id)).write();
download(new ModrinthModSource(latest.id), modsDir).write();
}
}
ImGui.sameLine();
@ -109,7 +108,7 @@ public class AddModWindow extends Window {
}
}
private DownloadMeta download(ModSource ms) throws IOException {
public static DownloadMeta download(ModSource ms, Path modsDir) throws IOException {
ModDownload md = ms.download(modsDir);
ModDescription manifest = new ModDescription();
manifest.sources = List.of(ms); //TODO discover other sources;
@ -118,7 +117,7 @@ public class AddModWindow extends Window {
manifest.dependencies = new ArrayList<>();
for (ModSource dependency : ms.getDependencies()) {
//TODO check if an dependency for this mod already exists
DownloadMeta depMan = download(dependency);
DownloadMeta depMan = download(dependency, modsDir);
depMan.description.dependents.add(md.file().getFileName().toString());
manifest.dependencies.add(depMan.download.file().getFileName().toString());
depMan.write();
@ -126,7 +125,7 @@ public class AddModWindow extends Window {
return new DownloadMeta(md, manifest, ms);
}
private static record DownloadMeta(ModDownload download, ModDescription description, ModSource source) {
public static record DownloadMeta(ModDownload download, ModDescription description, ModSource source) {
public void write() throws IOException {
Utils.writeObject(download.file().getParent().resolve(download.file().getFileName().toString() + ".imod"), description);
}

View File

@ -9,6 +9,7 @@ import io.gitlab.jfronny.inceptum.install.Steps;
import io.gitlab.jfronny.inceptum.model.fabric.FabricModJson;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.inceptum.ModDescription;
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
import io.gitlab.jfronny.inceptum.util.JvmUtils;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.windows.control.InstanceManageControls;
@ -20,6 +21,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class InstanceEditWindow extends Window {
private final Path path;
@ -31,7 +33,7 @@ public class InstanceEditWindow extends Window {
private Path selected = null;
private boolean reDownload = false;
private static record IWModDescription(ModDescription mod, FabricModJson fmj, Path path) {
private static record IWModDescription(ModDescription mod, FabricModJson fmj, Path path, Path imod, Optional<ModSource> update) {
public String getName() {
if (fmj == null) return path.getFileName().toString();
String base;
@ -109,16 +111,25 @@ public class InstanceEditWindow extends Window {
else {
if (mods.toString().endsWith(".jar")) {
Path imod = mods.getParent().resolve(mods.getFileName() + ".imod");
//TODO prevent blocking UI thread
if (Files.exists(imod) && !descriptions.containsKey(mods)) {
try (FileSystem fs = Utils.openZipFile(mods, false)) {
ModDescription md = Utils.loadObject(imod, ModDescription.class);
Optional<ModSource> update = Optional.empty();
for (ModSource source : md.sources) {
Optional<ModSource> ms = source.getUpdate(instance.getMinecraftVersion());
if (ms.isEmpty()) continue;
if (update.isEmpty()) update = ms;
}
if (Files.exists(fs.getPath("fabric.mod.json"))) {
descriptions.put(mods, new IWModDescription(md,
Utils.loadObject(fs.getPath("fabric.mod.json"), FabricModJson.class),
mods));
mods,
imod,
update));
}
else {
descriptions.put(mods, new IWModDescription(md, null, mods));
descriptions.put(mods, new IWModDescription(md, null, mods, null, update));
}
}
}
@ -143,13 +154,19 @@ public class InstanceEditWindow extends Window {
if (md.fmj != null && md.fmj.description != null) {
ImGui.text(md.fmj.description);
}
//TODO update check
if (md.update.isPresent() && ImGui.button("Update to " + md.update.get().getVersion())) {
try {
AddModWindow.download(md.update.get(), path.resolve("mods")).write();
Files.delete(md.path);
if (md.imod != null && Files.exists(md.imod)) Files.delete(md.imod);
} catch (IOException e) {
Inceptum.showError("Update failed", e);
}
}
if (ImGui.button("Delete")) {
try {
Files.delete(md.path);
Path imod = md.path.getParent().resolve(md.path.getFileName().toString() + ".imod");
if (Files.exists(imod))
Files.delete(imod);
if (md.imod != null && Files.exists(md.imod)) Files.delete(md.imod);
} catch (IOException e) {
Inceptum.showError("Couldn't delete the file", e);
}