From 6df388aad79dcf5702effece5c13cf0f077bb161 Mon Sep 17 00:00:00 2001 From: JFronny Date: Thu, 25 Apr 2024 20:42:31 +0200 Subject: [PATCH] feat: rewrite config/network IO for 1.20.5 --- .../io/gitlab/jfronny/resclone/Resclone.java | 24 ++++---- .../jfronny/resclone/RescloneConfig.java | 56 +++++++++++-------- .../resclone/RescloneResourcePack.java | 36 ++++++------ .../resclone/data/PackMetaUnloaded.java | 19 +------ .../data/curseforge/GetModFilesResponse.java | 4 ++ .../data/curseforge/GetModResponse.java | 4 ++ .../jfronny/resclone/data/github/Release.java | 4 ++ .../resclone/data/github/Repository.java | 3 + .../resclone/data/modrinth/Version.java | 7 ++- .../resclone/fetchers/CurseforgeFetcher.java | 17 ++++-- .../resclone/fetchers/GitHubFetcher.java | 16 ++++-- .../resclone/fetchers/ModrinthFetcher.java | 19 +++++-- .../mixin/FileResourcePackProviderMixin.java | 20 +++++-- .../jfronny/resclone/util/ListAdaptation.java | 31 ++++++++++ 14 files changed, 168 insertions(+), 92 deletions(-) create mode 100644 src/main/java/io/gitlab/jfronny/resclone/util/ListAdaptation.java diff --git a/src/main/java/io/gitlab/jfronny/resclone/Resclone.java b/src/main/java/io/gitlab/jfronny/resclone/Resclone.java index 998ffc5..cb89053 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/Resclone.java +++ b/src/main/java/io/gitlab/jfronny/resclone/Resclone.java @@ -1,7 +1,6 @@ package io.gitlab.jfronny.resclone; -import io.gitlab.jfronny.commons.logging.Logger; -import io.gitlab.jfronny.commons.serialize.gson.api.v2.GsonHolders; +import io.gitlab.jfronny.commons.logger.SystemLoggerPlus; import io.gitlab.jfronny.resclone.data.PackMetaLoaded; import io.gitlab.jfronny.resclone.data.PackMetaUnloaded; import io.gitlab.jfronny.resclone.fetchers.*; @@ -26,7 +25,7 @@ public class Resclone implements ModInitializer { public static final Set NEW_PACKS = new LinkedHashSet<>(); // Client-only! public static final String MOD_ID = "resclone"; - public static final Logger LOGGER = Logger.forName(MOD_ID); + public static final SystemLoggerPlus LOGGER = SystemLoggerPlus.forName(MOD_ID); public static final String USER_AGENT = "jfmods/" + MOD_ID + "/" + FabricLoader.getInstance() .getModContainer(MOD_ID).orElseThrow() .getMetadata() @@ -40,7 +39,6 @@ public class Resclone implements ModInitializer { @Override public void onInitialize() { LOGGER.info("Initialising Resclone."); - GsonHolders.registerSerializer(); urlCache = new PackUrlCache(getConfigPath().resolve("urlCache.properties")); FETCHER_INSTANCES.clear(); @@ -58,7 +56,7 @@ public class Resclone implements ModInitializer { } reload(); - LOGGER.info("Installed {} resource pack{}.", packCount, packCount == 1 ? "" : "s"); + LOGGER.info("Installed {0} resource pack{1}.", packCount, packCount == 1 ? "" : "s"); } public void addFetcher(PackFetcher fetcher) { @@ -87,9 +85,7 @@ public class Resclone implements ModInitializer { LOGGER.info("No resclone pack was specified, add one"); } else { - try { - //TODO migrate this to try-with-resources once JVM is updated - ExecutorService pool = Executors.newFixedThreadPool(RescloneConfig.packs.size()); + try (ExecutorService pool = Executors.newFixedThreadPool(RescloneConfig.packs.size())) { for (PackMetaUnloaded s : RescloneConfig.packs) { pool.submit(generateTask(s, metas)); } @@ -111,15 +107,15 @@ public class Resclone implements ModInitializer { private Runnable generateTask(PackMetaUnloaded meta, Set metas) { return () -> { try { - if (!FETCHER_INSTANCES.containsKey(meta.fetcher)) - throw new Exception("Invalid fetcher: " + meta.fetcher); + if (!FETCHER_INSTANCES.containsKey(meta.fetcher())) + throw new Exception("Invalid fetcher: " + meta.fetcher()); Path cacheDir = getConfigPath().resolve("cache"); PackMetaLoaded p; try { - boolean isNew = !urlCache.containsKey(meta.source); + boolean isNew = !urlCache.containsKey(meta.source()); //Download - PackFetcher.Result fr = FETCHER_INSTANCES.get(meta.fetcher).get(meta.source, cacheDir, meta.forceDownload); - p = new PackMetaLoaded(fr.downloadPath(), meta.name, meta.forceEnable); + PackFetcher.Result fr = FETCHER_INSTANCES.get(meta.fetcher()).get(meta.source(), cacheDir, meta.forceDownload()); + p = new PackMetaLoaded(fr.downloadPath(), meta.name(), meta.forceEnable()); metas.add(p); if (isNew && FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) NEW_PACKS.add(p); if (fr.freshDownload()) { @@ -139,7 +135,7 @@ public class Resclone implements ModInitializer { throw new Exception("Failed to download pack", e); } } catch (Throwable e) { - LOGGER.error("Encountered issue while preparing " + meta.name, e); + LOGGER.error("Encountered issue while preparing " + meta.name(), e); } }; } diff --git a/src/main/java/io/gitlab/jfronny/resclone/RescloneConfig.java b/src/main/java/io/gitlab/jfronny/resclone/RescloneConfig.java index f311385..92c1c3b 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/RescloneConfig.java +++ b/src/main/java/io/gitlab/jfronny/resclone/RescloneConfig.java @@ -1,15 +1,18 @@ package io.gitlab.jfronny.resclone; import com.google.gson.reflect.TypeToken; -import io.gitlab.jfronny.commons.serialize.gson.api.v2.GsonHolders; -import io.gitlab.jfronny.gson.JsonParseException; -import io.gitlab.jfronny.gson.stream.*; +import io.gitlab.jfronny.commons.serialize.MalformedDataException; +import io.gitlab.jfronny.commons.serialize.Token; +import io.gitlab.jfronny.commons.serialize.json.JsonReader; +import io.gitlab.jfronny.commons.serialize.json.JsonWriter; +import io.gitlab.jfronny.libjf.LibJf; import io.gitlab.jfronny.libjf.config.api.v2.JfCustomConfig; import io.gitlab.jfronny.libjf.config.api.v2.dsl.DSL; +import io.gitlab.jfronny.resclone.data.GC_PackMetaUnloaded; import io.gitlab.jfronny.resclone.data.PackMetaUnloaded; +import io.gitlab.jfronny.resclone.util.ListAdaptation; import java.io.*; -import java.lang.reflect.Type; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashSet; @@ -26,7 +29,6 @@ public class RescloneConfig implements JfCustomConfig { private static final String PRUNE_UNUSED = "pruneUnused"; private static final String FILTER_PACKS = "filterPacks"; private static final String LOG_PROCESSING = "logProcessing"; - private static final Type META_SET = new TypeToken>(){}.getType(); private static void load(Path path) throws IOException { if (!Files.exists(path)) { @@ -40,42 +42,46 @@ public class RescloneConfig implements JfCustomConfig { boolean updateRequired = false; try (BufferedReader br = Files.newBufferedReader(path); - JsonReader reader = GsonHolders.CONFIG.getGson().newJsonReader(br)) { - if (reader.peek() == JsonToken.BEGIN_ARRAY) { + JsonReader reader = LibJf.LENIENT_TRANSPORT.createReader(br)) { + if (reader.peek() == Token.BEGIN_ARRAY) { // Legacy format compatibility - packs = GsonHolders.CONFIG.getGson().fromJson(reader, META_SET); + packs = ListAdaptation.deserializeSet(reader, GC_PackMetaUnloaded::deserialize); updateRequired = true; - } else if (reader.peek() == JsonToken.BEGIN_OBJECT) { + } else if (reader.peek() == Token.BEGIN_OBJECT) { // New format reader.beginObject(); Set packs = null; Boolean pruneUnused = null; Boolean filterPacks = null; Boolean logProcessing = null; - while (reader.peek() != JsonToken.END_OBJECT) { + while (reader.peek() != Token.END_OBJECT) { final String name = reader.nextName(); switch (name) { case PACKS -> { - if (packs != null) throw new JsonParseException(ERR_DUPLICATE.formatted(PACKS)); - packs = GsonHolders.CONFIG.getGson().fromJson(reader, META_SET); + if (packs != null) throw new MalformedDataException(ERR_DUPLICATE.formatted(PACKS)); + if (reader.peek() == Token.BEGIN_ARRAY) { + packs = ListAdaptation.deserializeSet(reader, GC_PackMetaUnloaded::deserialize); + } else { + packs = Set.of(GC_PackMetaUnloaded.deserialize(reader)); + } } case PRUNE_UNUSED -> { - if (pruneUnused != null) throw new JsonParseException(ERR_DUPLICATE.formatted(PRUNE_UNUSED)); + if (pruneUnused != null) throw new MalformedDataException(ERR_DUPLICATE.formatted(PRUNE_UNUSED)); pruneUnused = reader.nextBoolean(); } case FILTER_PACKS -> { - if (filterPacks != null) throw new JsonParseException(ERR_DUPLICATE.formatted(FILTER_PACKS)); + if (filterPacks != null) throw new MalformedDataException(ERR_DUPLICATE.formatted(FILTER_PACKS)); filterPacks = reader.nextBoolean(); } case LOG_PROCESSING -> { - if (logProcessing != null) throw new JsonParseException(ERR_DUPLICATE.formatted(LOG_PROCESSING)); + if (logProcessing != null) throw new MalformedDataException(ERR_DUPLICATE.formatted(LOG_PROCESSING)); logProcessing = reader.nextBoolean(); } - default -> throw new JsonParseException("Unexpected element: \"" + name + "\" in Resclone config"); + default -> throw new MalformedDataException("Unexpected element: \"" + name + "\" in Resclone config"); } } reader.endObject(); - if (packs == null) throw new JsonParseException("Expected Resclone config object to contain packs"); + if (packs == null) throw new MalformedDataException("Expected Resclone config object to contain packs"); if (pruneUnused == null) { pruneUnused = true; updateRequired = true; @@ -92,19 +98,23 @@ public class RescloneConfig implements JfCustomConfig { RescloneConfig.pruneUnused = pruneUnused; RescloneConfig.filterPacks = filterPacks; RescloneConfig.logProcessing = logProcessing; - } else throw new JsonParseException("Expected Resclone config to be an object or array"); + } else throw new MalformedDataException("Expected Resclone config to be an object or array"); } if (updateRequired) write(path); } private static void write(Path path) throws IOException { try (BufferedWriter bw = Files.newBufferedWriter(path); - JsonWriter writer = GsonHolders.CONFIG.getGson().newJsonWriter(bw)) { + JsonWriter writer = LibJf.LENIENT_TRANSPORT.createWriter(bw)) { writer.beginObject() .comment("The packs to be loaded by resclone") - .name(PACKS); - GsonHolders.CONFIG.getGson().toJson(packs, META_SET, writer); - writer.comment("Automatically remove all downloaded packs that are not in the config to free up unneeded space") + .name(PACKS) + .beginArray(); + for (PackMetaUnloaded pack : packs) { + GC_PackMetaUnloaded.serialize(pack, writer); + } + writer.endArray() + .comment("Automatically remove all downloaded packs that are not in the config to free up unneeded space") .name(PRUNE_UNUSED) .value(pruneUnused) .comment("Whether to filter packs to remove files unchanged from vanilla and empty directories") @@ -133,7 +143,7 @@ public class RescloneConfig implements JfCustomConfig { Resclone.LOGGER.error("Could not write config", e); } }).setPath(path) - .>value(PACKS, new HashSet<>(), Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, io.gitlab.jfronny.libjf.config.api.v2.type.Type.ofClass(META_SET), 100, () -> packs, p -> packs = p) + .>value(PACKS, new HashSet<>(), Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, io.gitlab.jfronny.libjf.config.api.v2.type.Type.ofClass(new TypeToken>(){}.getType()), 100, () -> packs, p -> packs = p) .value(PRUNE_UNUSED, pruneUnused, () -> pruneUnused, p -> pruneUnused = p) .value(FILTER_PACKS, filterPacks, () -> filterPacks, p -> filterPacks = p) .value(LOG_PROCESSING, logProcessing, () -> logProcessing, p -> logProcessing = p) diff --git a/src/main/java/io/gitlab/jfronny/resclone/RescloneResourcePack.java b/src/main/java/io/gitlab/jfronny/resclone/RescloneResourcePack.java index 7532341..d6039ac 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/RescloneResourcePack.java +++ b/src/main/java/io/gitlab/jfronny/resclone/RescloneResourcePack.java @@ -11,16 +11,13 @@ import java.util.List; public class RescloneResourcePack extends ZipResourcePack implements ModResourcePack { private static final ModMetadata METADATA = FabricLoader.getInstance().getModContainer(Resclone.MOD_ID).orElseThrow().getMetadata(); - private final String name; + private final ResourcePackInfo info; + private final ZipFileWrapper file; - RescloneResourcePack(ZipFileWrapper file, String name, String overlay) { - super(name, file, true, overlay); - this.name = name; - } - - @Override - public String getName() { - return name; + RescloneResourcePack(ZipFileWrapper file, ResourcePackInfo info, String overlay) { + super(info, file, overlay); + this.info = info; + this.file = file; } @Override @@ -28,29 +25,34 @@ public class RescloneResourcePack extends ZipResourcePack implements ModResource return METADATA; } + @Override + public ModResourcePack createOverlay(String overlay) { + return new RescloneResourcePack(this.file, this.info, overlay); + } + public static class Factory implements ResourcePackProfile.PackFactory { private final File file; - private final String name; + private final ResourcePackInfo info; - public Factory(File file, String name) { + public Factory(File file, ResourcePackInfo info) { this.file = file; - this.name = name; + this.info = info; } @Override - public ResourcePack open(String name) { + public ResourcePack open(ResourcePackInfo info) { ZipFileWrapper zipFileWrapper = new ZipFileWrapper(this.file); - return new RescloneResourcePack(zipFileWrapper, this.name, ""); + return new RescloneResourcePack(zipFileWrapper, this.info, ""); } @Override - public ResourcePack openWithOverlays(String name, ResourcePackProfile.Metadata metadata) { + public ResourcePack openWithOverlays(ResourcePackInfo info, ResourcePackProfile.Metadata metadata) { ZipFileWrapper zipFileWrapper = new ZipFileWrapper(this.file); - ZipResourcePack resourcePack = new RescloneResourcePack(zipFileWrapper, this.name, ""); + ZipResourcePack resourcePack = new RescloneResourcePack(zipFileWrapper, this.info, ""); List overlays = metadata.overlays(); if (overlays.isEmpty()) return resourcePack; List overlayPacks = new ArrayList<>(overlays.size()); - for (String string : overlays) overlayPacks.add(new RescloneResourcePack(zipFileWrapper, this.name, string)); + for (String string : overlays) overlayPacks.add(new RescloneResourcePack(zipFileWrapper, this.info, string)); return new OverlayResourcePack(resourcePack, overlayPacks); } } diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaUnloaded.java b/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaUnloaded.java index c7a2915..0f212fd 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaUnloaded.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaUnloaded.java @@ -1,20 +1,7 @@ package io.gitlab.jfronny.resclone.data; -// Represents a pack as present in the config -// Can't be a record since it'll need to be parsed by Gson -@SuppressWarnings("ClassCanBeRecord") -public class PackMetaUnloaded { - public final String fetcher; - public final String source; - public final String name; - public final boolean forceDownload; - public final boolean forceEnable; +import io.gitlab.jfronny.commons.serialize.generator.annotations.GSerializable; - public PackMetaUnloaded(String fetcher, String source, String name, boolean forceDownload, boolean forceEnable) { - this.fetcher = fetcher; - this.source = source; - this.name = name; - this.forceDownload = forceDownload; - this.forceEnable = forceEnable; - } +@GSerializable +public record PackMetaUnloaded(String fetcher, String source, String name, boolean forceDownload, boolean forceEnable) { } diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/curseforge/GetModFilesResponse.java b/src/main/java/io/gitlab/jfronny/resclone/data/curseforge/GetModFilesResponse.java index 39cb195..7429a75 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/curseforge/GetModFilesResponse.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/curseforge/GetModFilesResponse.java @@ -1,11 +1,15 @@ package io.gitlab.jfronny.resclone.data.curseforge; +import io.gitlab.jfronny.commons.serialize.generator.annotations.GSerializable; + import java.util.Date; import java.util.List; +@GSerializable public class GetModFilesResponse { public List data; + @GSerializable public static class Data { public String downloadUrl; public Date fileDate; diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/curseforge/GetModResponse.java b/src/main/java/io/gitlab/jfronny/resclone/data/curseforge/GetModResponse.java index 63207e6..a45c6eb 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/curseforge/GetModResponse.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/curseforge/GetModResponse.java @@ -1,8 +1,12 @@ package io.gitlab.jfronny.resclone.data.curseforge; +import io.gitlab.jfronny.commons.serialize.generator.annotations.GSerializable; + +@GSerializable public class GetModResponse { public Data data; + @GSerializable public static class Data { public Boolean allowModDistribution; } diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/github/Release.java b/src/main/java/io/gitlab/jfronny/resclone/data/github/Release.java index f6f9beb..538afd4 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/github/Release.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/github/Release.java @@ -1,11 +1,15 @@ package io.gitlab.jfronny.resclone.data.github; +import io.gitlab.jfronny.commons.serialize.generator.annotations.GSerializable; + import java.util.List; +@GSerializable public class Release { public List assets; public String zipball_url; + @GSerializable public static class Asset { public String name; public String content_type; diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/github/Repository.java b/src/main/java/io/gitlab/jfronny/resclone/data/github/Repository.java index 5c4961b..c9dee13 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/github/Repository.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/github/Repository.java @@ -1,5 +1,8 @@ package io.gitlab.jfronny.resclone.data.github; +import io.gitlab.jfronny.commons.serialize.generator.annotations.GSerializable; + +@GSerializable public class Repository { public String default_branch; } diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/modrinth/Version.java b/src/main/java/io/gitlab/jfronny/resclone/data/modrinth/Version.java index a8b7752..1786333 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/modrinth/Version.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/modrinth/Version.java @@ -1,11 +1,13 @@ package io.gitlab.jfronny.resclone.data.modrinth; -import io.gitlab.jfronny.gson.annotations.SerializedName; +import io.gitlab.jfronny.commons.serialize.annotations.SerializedName; +import io.gitlab.jfronny.commons.serialize.generator.annotations.GSerializable; import org.jetbrains.annotations.Nullable; import java.util.Date; import java.util.List; +@GSerializable public class Version { public String name; public String version_number; @@ -24,6 +26,7 @@ public class Version { public Integer downloads; public List files; + @GSerializable public static class Dependency { @Nullable public String version_id; @Nullable public String project_id; @@ -43,6 +46,7 @@ public class Version { listed, archived, draft, unlisted, scheduled, unknown } + @GSerializable public static class File { public Hashes hashes; public String url; @@ -51,6 +55,7 @@ public class Version { public Integer size; @Nullable public Type file_type; + @GSerializable public static class Hashes { public String sha512; public String sha1; diff --git a/src/main/java/io/gitlab/jfronny/resclone/fetchers/CurseforgeFetcher.java b/src/main/java/io/gitlab/jfronny/resclone/fetchers/CurseforgeFetcher.java index 0da1513..d6f35cf 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/fetchers/CurseforgeFetcher.java +++ b/src/main/java/io/gitlab/jfronny/resclone/fetchers/CurseforgeFetcher.java @@ -1,13 +1,19 @@ package io.gitlab.jfronny.resclone.fetchers; import io.gitlab.jfronny.commons.http.client.HttpClient; +import io.gitlab.jfronny.commons.serialize.json.JsonReader; +import io.gitlab.jfronny.commons.throwable.ThrowingFunction; +import io.gitlab.jfronny.libjf.LibJf; import io.gitlab.jfronny.resclone.Resclone; +import io.gitlab.jfronny.resclone.data.curseforge.GC_GetModFilesResponse; +import io.gitlab.jfronny.resclone.data.curseforge.GC_GetModResponse; 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.io.Reader; import java.net.URISyntaxException; import java.util.Date; import java.util.Random; @@ -33,7 +39,7 @@ public class CurseforgeFetcher extends BasePackFetcher { @Override public String getDownloadUrl(String baseUrl) throws Exception { try { - GetModResponse response = GET(baseUrl, GetModResponse.class); + GetModResponse response = GET(baseUrl, GC_GetModResponse::deserialize); if (!response.data.allowModDistribution) throw new Exception("The author of " + baseUrl + " disabled access to this pack outside of the curseforge launcher"); @@ -43,7 +49,7 @@ public class CurseforgeFetcher extends BasePackFetcher { Date latestDate = null; boolean foundMatchingVersion = false; - for (GetModFilesResponse.Data addon : GET(baseUrl + "/files", GetModFilesResponse.class).data) { + for (GetModFilesResponse.Data addon : GET(baseUrl + "/files", GC_GetModFilesResponse::deserialize).data) { if (foundMatchingVersion && !addon.gameVersions.contains(version)) continue; if (!foundMatchingVersion && addon.gameVersions.contains(version)) { foundMatchingVersion = true; @@ -63,8 +69,11 @@ public class CurseforgeFetcher extends BasePackFetcher { } } - private static T GET(String suffix, Class klazz) throws URISyntaxException, IOException { - return HttpClient.get("https://api.curseforge.com/v1/mods/" + suffix).header("x-api-key", API_KEY).sendSerialized(klazz); + private static T GET(String suffix, ThrowingFunction klazz) throws URISyntaxException, IOException { + try (Reader r = HttpClient.get("https://api.curseforge.com/v1/mods/" + suffix).header("x-api-key", API_KEY).sendReader(); + JsonReader jr = LibJf.LENIENT_TRANSPORT.createReader(r)) { + return klazz.apply(jr); + } } private static byte[] unsalt(byte[] data, int salt) { diff --git a/src/main/java/io/gitlab/jfronny/resclone/fetchers/GitHubFetcher.java b/src/main/java/io/gitlab/jfronny/resclone/fetchers/GitHubFetcher.java index 917d8a0..a187357 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/fetchers/GitHubFetcher.java +++ b/src/main/java/io/gitlab/jfronny/resclone/fetchers/GitHubFetcher.java @@ -1,12 +1,16 @@ package io.gitlab.jfronny.resclone.fetchers; import io.gitlab.jfronny.commons.http.client.HttpClient; +import io.gitlab.jfronny.commons.serialize.json.JsonReader; +import io.gitlab.jfronny.libjf.LibJf; import io.gitlab.jfronny.resclone.Resclone; +import io.gitlab.jfronny.resclone.data.github.GC_Release; +import io.gitlab.jfronny.resclone.data.github.GC_Repository; import io.gitlab.jfronny.resclone.data.github.Release; -import io.gitlab.jfronny.resclone.data.github.Repository; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.io.Reader; import java.net.URISyntaxException; public class GitHubFetcher extends BasePackFetcher { @@ -39,8 +43,9 @@ public class GitHubFetcher extends BasePackFetcher { //"user/repo/release" - Gets from the latest release. else if (parts[2].equalsIgnoreCase("release")) { - try { - Release latestRelease = HttpClient.get("https://api.github.com/repos/" + parts[0] + "/" + parts[1] + "/releases/latest").sendSerialized(Release.class); + try (Reader r = HttpClient.get("https://api.github.com/repos/" + parts[0] + "/" + parts[1] + "/releases/latest").sendReader(); + JsonReader jr = LibJf.LENIENT_TRANSPORT.createReader(r)) { + Release latestRelease = GC_Release.deserialize(jr); String res = null; for (Release.Asset asset : latestRelease.assets) { @@ -73,8 +78,9 @@ public class GitHubFetcher extends BasePackFetcher { private String getFromBranch(String repo, @Nullable String branch) { if (branch == null) { - try { - branch = HttpClient.get("https://api.github.com/repos/" + repo).sendSerialized(Repository.class).default_branch; + try (Reader r = HttpClient.get("https://api.github.com/repos/" + repo).sendReader(); + JsonReader jr = LibJf.LENIENT_TRANSPORT.createReader(r)) { + branch = GC_Repository.deserialize(jr).default_branch; } catch (IOException | URISyntaxException e) { Resclone.LOGGER.error("Failed to fetch branch for " + repo + ". Choosing \"main\"", e); branch = "main"; diff --git a/src/main/java/io/gitlab/jfronny/resclone/fetchers/ModrinthFetcher.java b/src/main/java/io/gitlab/jfronny/resclone/fetchers/ModrinthFetcher.java index 7fd4999..6c2d019 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/fetchers/ModrinthFetcher.java +++ b/src/main/java/io/gitlab/jfronny/resclone/fetchers/ModrinthFetcher.java @@ -1,19 +1,21 @@ package io.gitlab.jfronny.resclone.fetchers; -import com.google.common.reflect.TypeToken; import io.gitlab.jfronny.commons.http.client.HttpClient; +import io.gitlab.jfronny.commons.serialize.json.JsonReader; +import io.gitlab.jfronny.libjf.LibJf; import io.gitlab.jfronny.resclone.Resclone; +import io.gitlab.jfronny.resclone.data.modrinth.GC_Version; import io.gitlab.jfronny.resclone.data.modrinth.Version; +import io.gitlab.jfronny.resclone.util.ListAdaptation; import net.minecraft.MinecraftVersion; import java.io.FileNotFoundException; import java.io.IOException; -import java.lang.reflect.Type; +import java.io.Reader; import java.util.Date; import java.util.List; public class ModrinthFetcher extends BasePackFetcher { - private static final Type versionType = new TypeToken>() {}.getType(); @Override public String getSourceTypeName() { return "modrinth"; @@ -28,9 +30,14 @@ public class ModrinthFetcher extends BasePackFetcher { Date latestDate = null; boolean foundMatchingVersion = false; - for (Version ver : HttpClient.get("https://api.modrinth.com/v2/project/" + baseUrl + "/version") + List versions; + try (Reader r = HttpClient.get("https://api.modrinth.com/v2/project/" + baseUrl + "/version") .userAgent(Resclone.USER_AGENT) - .>sendSerialized(versionType)) { + .sendReader(); + JsonReader jr = LibJf.LENIENT_TRANSPORT.createReader(r)) { + versions = ListAdaptation.deserializeList(jr, GC_Version::deserialize); + } + for (Version ver : versions) { if (foundMatchingVersion && !ver.game_versions.contains(version)) continue; if (ver.files.isEmpty()) continue; if (!foundMatchingVersion && ver.game_versions.contains(version)) { @@ -54,7 +61,7 @@ public class ModrinthFetcher extends BasePackFetcher { if (file.file_type == Version.File.Type.REQUIRED_RESOURCE_PACK) return file.url; } Resclone.LOGGER.error("Identification failed, using first file of " + baseUrl); - return latest.files.get(0).url; + return latest.files.getFirst().url; } catch (Throwable e) { throw new IOException("Could not get Modrinth download for " + baseUrl, e); } diff --git a/src/main/java/io/gitlab/jfronny/resclone/mixin/FileResourcePackProviderMixin.java b/src/main/java/io/gitlab/jfronny/resclone/mixin/FileResourcePackProviderMixin.java index d2eae55..2377732 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/mixin/FileResourcePackProviderMixin.java +++ b/src/main/java/io/gitlab/jfronny/resclone/mixin/FileResourcePackProviderMixin.java @@ -10,6 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.Optional; import java.util.function.Consumer; @Mixin(FileResourcePackProvider.class) @@ -20,14 +21,21 @@ public class FileResourcePackProviderMixin { @Inject(at = @At("TAIL"), method = "register(Ljava/util/function/Consumer;)V") public void registerExtra(Consumer consumer, CallbackInfo info) { for (PackMetaLoaded meta : Resclone.DOWNLOADED_PACKS) { + ResourcePackInfo ifo = new ResourcePackInfo( + "resclone/" + meta.name(), + Text.literal(meta.name()), + source, + Optional.empty() + ); ResourcePackProfile resourcePackProfile = ResourcePackProfile.create( - "resclone/" + meta.name(), - Text.literal(meta.name()), - meta.forceEnable(), - new RescloneResourcePack.Factory(meta.zipPath().toFile(), meta.name()), + ifo, + new RescloneResourcePack.Factory(meta.zipPath().toFile(), ifo), type, - ResourcePackProfile.InsertionPosition.TOP, - source + new ResourcePackPosition( + meta.forceEnable(), + ResourcePackProfile.InsertionPosition.TOP, + false + ) ); if (resourcePackProfile != null) { consumer.accept(resourcePackProfile); diff --git a/src/main/java/io/gitlab/jfronny/resclone/util/ListAdaptation.java b/src/main/java/io/gitlab/jfronny/resclone/util/ListAdaptation.java new file mode 100644 index 0000000..429696f --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/resclone/util/ListAdaptation.java @@ -0,0 +1,31 @@ +package io.gitlab.jfronny.resclone.util; + +import io.gitlab.jfronny.commons.serialize.SerializeReader; +import io.gitlab.jfronny.commons.throwable.ThrowingFunction; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +public class ListAdaptation { + public static > List deserializeList(Reader reader, ThrowingFunction deserializeOne) throws TEx { + List result = new ArrayList<>(); + reader.beginArray(); + while (reader.hasNext()) { + result.add(deserializeOne.apply(reader)); + } + reader.endArray(); + return result; + } + + public static > Set deserializeSet(Reader reader, ThrowingFunction serializeOne) throws TEx { + Set result = new LinkedHashSet<>(); + reader.beginArray(); + while (reader.hasNext()) { + result.add(serializeOne.apply(reader)); + } + reader.endArray(); + return result; + } +}