diff --git a/src/main/java/io/gitlab/jfronny/resclone/PackUrlCache.java b/src/main/java/io/gitlab/jfronny/resclone/PackUrlCache.java index 7f1bbc2..5cec41d 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/PackUrlCache.java +++ b/src/main/java/io/gitlab/jfronny/resclone/PackUrlCache.java @@ -8,8 +8,9 @@ import java.nio.file.Path; import java.util.Properties; public class PackUrlCache { + + private final Path file; Properties properties = new Properties(); - private Path file; public PackUrlCache(Path file) { this.file = file; @@ -41,4 +42,5 @@ public class PackUrlCache { public void set(String key, String value) { properties.setProperty(key, value); } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/Resclone.java b/src/main/java/io/gitlab/jfronny/resclone/Resclone.java index 9b7fe9a..daee486 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/Resclone.java +++ b/src/main/java/io/gitlab/jfronny/resclone/Resclone.java @@ -1,17 +1,19 @@ package io.gitlab.jfronny.resclone; import com.google.gson.Gson; -import io.gitlab.jfronny.resclone.data.PackMetaLoaded; import io.gitlab.jfronny.resclone.api.RescloneApi; import io.gitlab.jfronny.resclone.api.RescloneEntry; +import io.gitlab.jfronny.resclone.data.PackMetaLoaded; import io.gitlab.jfronny.resclone.data.PackMetaUnloaded; -import io.gitlab.jfronny.resclone.data.RescloneException; import io.gitlab.jfronny.resclone.fetchers.PackFetcher; import io.gitlab.jfronny.resclone.processors.PackProcessor; import io.gitlab.jfronny.resclone.processors.RemoveEmptyProcessor; import io.gitlab.jfronny.resclone.processors.RootPathProcessor; +import io.gitlab.jfronny.resclone.util.Result; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.io.IOException; import java.net.URI; @@ -22,33 +24,42 @@ import java.nio.file.Path; import java.util.*; public class Resclone implements ModInitializer, RescloneApi { + public static final Set conf = new LinkedHashSet<>(); public static final Map fetcherInstances = new LinkedHashMap<>(); public static final Set processors = new LinkedHashSet<>(); public static final Set downloadedPacks = new LinkedHashSet<>(); public static final Gson gson = new Gson(); + public static final String MOD_ID = "resclone"; + public static final Logger LOGGER = LogManager.getLogger(MOD_ID); + public static PackUrlCache urlCache; + public static int COUNT = 0; + @Override public void onInitialize() { - System.out.println("[resclone] Beginning init, will download packs"); + LOGGER.info("Initialising Resclone."); + urlCache = new PackUrlCache(getConfigPath().resolve("urlCache.properties")); conf.clear(); fetcherInstances.clear(); processors.clear(); downloadedPacks.clear(); + addProcessor(new RootPathProcessor()); //This should be run before any other processor to make sure the path is valid for (RescloneEntry entry : FabricLoader.getInstance().getEntrypoints(MOD_ID, RescloneEntry.class)) { try { entry.init(this); - } catch (RescloneException e) { + } catch (Exception e) { e.printStackTrace(); } } addProcessor(new RemoveEmptyProcessor()); reload(); - System.out.println("[resclone] Completed"); + + LOGGER.info("Installed {} resource pack{}.", COUNT, COUNT == 1 ? "" : "s"); } @Override @@ -79,19 +90,19 @@ public class Resclone implements ModInitializer, RescloneApi { for (PackMetaUnloaded s : conf) { try { if (!fetcherInstances.containsKey(s.fetcher)) - throw new RescloneException("Invalid fetcher: " + s.fetcher); + throw new Exception("Invalid fetcher: " + s.fetcher); Path cacheDir = getConfigPath().resolve("cache"); PackMetaLoaded p; try { //Download - PackFetcher.Result fr = fetcherInstances.get(s.fetcher).get(s.source, cacheDir, s.forceDownload); + Result fr = fetcherInstances.get(s.fetcher).get(s.source, cacheDir, s.forceDownload); p = new PackMetaLoaded(fr.downloadPath, s.name); metas.add(p); if (fr.freshDownload) { //Process Map props = new HashMap<>(); props.put("create", "false"); - URI zipfile = URI.create("jar:" + p.zipPath.toUri().toString()); + URI zipfile = URI.create("jar:" + p.zipPath.toUri()); try (FileSystem zipfs = FileSystems.newFileSystem(zipfile, props)) { for (PackProcessor processor : processors) { processor.process(zipfs); @@ -101,9 +112,8 @@ public class Resclone implements ModInitializer, RescloneApi { e.printStackTrace(); } } - } - catch (Throwable e) { - throw new RescloneException("Failed to download pack", e); + } catch (Throwable e) { + throw new Exception("Failed to download pack", e); } } catch (Throwable e) { System.err.println("Encountered issue while preparing " + s.name); @@ -128,4 +138,5 @@ public class Resclone implements ModInitializer, RescloneApi { } return configPath; } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/RescloneEntryDefault.java b/src/main/java/io/gitlab/jfronny/resclone/RescloneEntryDefault.java index 1151d64..3735800 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/RescloneEntryDefault.java +++ b/src/main/java/io/gitlab/jfronny/resclone/RescloneEntryDefault.java @@ -5,21 +5,21 @@ import io.gitlab.jfronny.resclone.api.RescloneEntry; import io.gitlab.jfronny.resclone.config.ConfigLoader; import io.gitlab.jfronny.resclone.fetchers.BasicFileFetcher; import io.gitlab.jfronny.resclone.fetchers.CurseforgeFetcher; -import io.gitlab.jfronny.resclone.fetchers.GithubMasterFetcher; -import io.gitlab.jfronny.resclone.fetchers.GithubReleaseFetcher; +import io.gitlab.jfronny.resclone.fetchers.GitHubFetcher; import io.gitlab.jfronny.resclone.processors.PruneVanillaProcessor; import net.fabricmc.api.EnvType; import net.fabricmc.loader.api.FabricLoader; public class RescloneEntryDefault implements RescloneEntry { + @Override public void init(RescloneApi api) { api.addFetcher(new BasicFileFetcher()); - api.addFetcher(new GithubMasterFetcher()); - api.addFetcher(new GithubReleaseFetcher()); + api.addFetcher(new GitHubFetcher()); api.addFetcher(new CurseforgeFetcher()); if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) api.addProcessor(new PruneVanillaProcessor()); ConfigLoader.load(api); } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/RescloneResourcePack.java b/src/main/java/io/gitlab/jfronny/resclone/RescloneResourcePack.java index e81dbe9..284e42e 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/RescloneResourcePack.java +++ b/src/main/java/io/gitlab/jfronny/resclone/RescloneResourcePack.java @@ -8,7 +8,9 @@ import net.minecraft.resource.ZipResourcePack; import java.io.File; public class RescloneResourcePack extends ZipResourcePack implements ModResourcePack { + private final String name; + public RescloneResourcePack(File file, String name) { super(file); this.name = name; @@ -23,4 +25,5 @@ public class RescloneResourcePack extends ZipResourcePack implements ModResource public ModMetadata getFabricModMetadata() { return FabricLoader.getInstance().getModContainer(Resclone.MOD_ID).get().getMetadata(); } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/api/RescloneApi.java b/src/main/java/io/gitlab/jfronny/resclone/api/RescloneApi.java index 9ddb758..edbfd2f 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/api/RescloneApi.java +++ b/src/main/java/io/gitlab/jfronny/resclone/api/RescloneApi.java @@ -6,10 +6,17 @@ import io.gitlab.jfronny.resclone.processors.PackProcessor; import java.nio.file.Path; public interface RescloneApi { + void addFetcher(PackFetcher fetcher); + void addProcessor(PackProcessor processor); + void addPack(String fetcher, String pack, String name); + void addPack(String fetcher, String pack, String name, boolean forceRedownload); + void reload(); + Path getConfigPath(); -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/api/RescloneEntry.java b/src/main/java/io/gitlab/jfronny/resclone/api/RescloneEntry.java index 0097adf..9be4593 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/api/RescloneEntry.java +++ b/src/main/java/io/gitlab/jfronny/resclone/api/RescloneEntry.java @@ -1,7 +1,5 @@ package io.gitlab.jfronny.resclone.api; -import io.gitlab.jfronny.resclone.data.RescloneException; - public interface RescloneEntry { - void init(RescloneApi api) throws RescloneException; -} + void init(RescloneApi api) throws Exception; +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/config/ConfigLoader.java b/src/main/java/io/gitlab/jfronny/resclone/config/ConfigLoader.java index 82e64d8..04f9904 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/config/ConfigLoader.java +++ b/src/main/java/io/gitlab/jfronny/resclone/config/ConfigLoader.java @@ -12,6 +12,7 @@ import java.util.HashSet; import java.util.Set; public class ConfigLoader { + public static void load(RescloneApi api) { Path configPath = api.getConfigPath().resolve("config.json"); if (!Files.exists(configPath)) { @@ -42,4 +43,5 @@ public class ConfigLoader { e.printStackTrace(); } } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/CfAddon.java b/src/main/java/io/gitlab/jfronny/resclone/data/CfAddon.java index 9f96bf9..9be88f5 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/CfAddon.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/CfAddon.java @@ -3,7 +3,9 @@ package io.gitlab.jfronny.resclone.data; import java.util.Set; public class CfAddon { + public String downloadUrl; public String fileDate; public Set gameVersion; -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaLoaded.java b/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaLoaded.java index 6490c7d..d4dca76 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaLoaded.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaLoaded.java @@ -3,6 +3,7 @@ package io.gitlab.jfronny.resclone.data; import java.nio.file.Path; public class PackMetaLoaded { + public Path zipPath; public String name; @@ -10,4 +11,5 @@ public class PackMetaLoaded { this.zipPath = zipPath; this.name = name; } -} + +} \ No newline at end of file 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 72bfcf6..668adf0 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaUnloaded.java +++ b/src/main/java/io/gitlab/jfronny/resclone/data/PackMetaUnloaded.java @@ -1,6 +1,7 @@ package io.gitlab.jfronny.resclone.data; public class PackMetaUnloaded { + public final String fetcher; public final String source; public final String name; @@ -12,4 +13,5 @@ public class PackMetaUnloaded { this.name = name; this.forceDownload = forceDownload; } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/data/RescloneException.java b/src/main/java/io/gitlab/jfronny/resclone/data/RescloneException.java deleted file mode 100644 index 2f449ec..0000000 --- a/src/main/java/io/gitlab/jfronny/resclone/data/RescloneException.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.gitlab.jfronny.resclone.data; - -public class RescloneException extends Exception { - public RescloneException(String message) { - super(message); - } - - public RescloneException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/io/gitlab/jfronny/resclone/fetchers/BasicFileFetcher.java b/src/main/java/io/gitlab/jfronny/resclone/fetchers/BasicFileFetcher.java index f52b7bb..9ae4451 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/fetchers/BasicFileFetcher.java +++ b/src/main/java/io/gitlab/jfronny/resclone/fetchers/BasicFileFetcher.java @@ -1,6 +1,7 @@ package io.gitlab.jfronny.resclone.fetchers; public class BasicFileFetcher extends PackFetcher { + @Override public String getSourceTypeName() { return "file"; @@ -10,4 +11,5 @@ public class BasicFileFetcher extends PackFetcher { public String getDownloadUrl(String baseUrl) { return baseUrl; } -} + +} \ No newline at end of file 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 3b16739..5b027fc 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/fetchers/CurseforgeFetcher.java +++ b/src/main/java/io/gitlab/jfronny/resclone/fetchers/CurseforgeFetcher.java @@ -1,20 +1,21 @@ package io.gitlab.jfronny.resclone.fetchers; import io.gitlab.jfronny.resclone.data.CfAddon; -import io.gitlab.jfronny.resclone.data.RescloneException; +import io.gitlab.jfronny.resclone.util.UrlUtils; import net.minecraft.MinecraftVersion; import java.text.SimpleDateFormat; import java.util.Date; public class CurseforgeFetcher extends PackFetcher { + @Override public String getSourceTypeName() { return "curseforge"; } @Override - public String getDownloadUrl(String baseUrl) throws RescloneException { + public String getDownloadUrl(String baseUrl) throws Exception { try { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'"); @@ -24,7 +25,7 @@ public class CurseforgeFetcher extends PackFetcher { Date latestDate = null; boolean foundMatchingVersion = false; - for (CfAddon addon : readJsonFromURLSet("https://addons-ecs.forgesvc.net/api/v2/addon/" + baseUrl + "/files", CfAddon.class)) { + for (CfAddon addon : UrlUtils.readJsonFromURLSet("https://addons-ecs.forgesvc.net/api/v2/addon/" + baseUrl + "/files", CfAddon.class)) { Date d = df.parse(addon.fileDate); if (foundMatchingVersion && !addon.gameVersion.contains(version)) continue; @@ -42,7 +43,8 @@ public class CurseforgeFetcher extends PackFetcher { System.err.println("Could not find pack for matching version, using latest"); return latest.downloadUrl; } catch (Throwable e) { - throw new RescloneException("Could not get CF download for " + baseUrl, e); + throw new Exception("Could not get CF download for " + baseUrl, e); } } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/fetchers/GitHubFetcher.java b/src/main/java/io/gitlab/jfronny/resclone/fetchers/GitHubFetcher.java new file mode 100644 index 0000000..db409ff --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/resclone/fetchers/GitHubFetcher.java @@ -0,0 +1,95 @@ +package io.gitlab.jfronny.resclone.fetchers; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.gitlab.jfronny.resclone.Resclone; +import io.gitlab.jfronny.resclone.util.UrlUtils; +import org.jetbrains.annotations.Nullable; + +public class GitHubFetcher extends PackFetcher { + + @Override + public String getSourceTypeName() { + return "github"; + } + + @Override + String getDownloadUrl(String baseUrl) throws Exception { + String[] parts = baseUrl.split("/"); + + if (parts.length < 2) { + throw new Exception("Minimum source must contain \"user/repo\"."); + } + + /* "user/repo" - Gets from latest commit of main/master branch. */ + else if (parts.length == 2) { + return getFromBranch(parts[0], parts[1], null); + } + + /* "user/repo/branch/branchName" - Gets from latest commit of specified branch. */ + else if (parts[2].equalsIgnoreCase("branch")) { + if (parts.length < 4) throw new Exception("Missing branch name in source definition."); + else { + Resclone.LOGGER.info("Getting from " + parts[3] + " branch."); + return getFromBranch(parts[0], parts[1], parts[3]); + } + } + + /* "user/repo/release" - Gets from the latest release. */ + else if (parts[2].equalsIgnoreCase("release")) { + try { + JsonObject latestRelease = UrlUtils.readJsonFromURL("https://api.github.com/repos/" + parts[0] + "/" + parts[1] + "/releases/latest", JsonObject.class); + String res = null; + + for (JsonElement element : latestRelease.get("assets").getAsJsonArray()) { + JsonObject o = element.getAsJsonObject(); + if ("application/x-zip-compressed".equals(o.get("content_type").getAsString()) || o.get("name").getAsString().endsWith(".zip")) { + res = o.get("browser_download_url").getAsString(); + break; + } + } + + Resclone.LOGGER.info("Getting from latest release."); + + if (res == null) return latestRelease.get("zipball_url").getAsString(); + else return res; + + } catch (Throwable e) { + throw new Exception("Failed to get github release asset", e); + } + } + + /* "user/repo/tag/tagNum" - Gets from a specified tag. */ + else if (parts[2].equalsIgnoreCase("tag")) { + if (parts.length < 4) throw new Exception("Missing tag number in source definition."); + else { + return getFromTag(parts[0], parts[1], parts[3]); + } + } + + return null; + } + + private String getFromBranch(String user, String repo, @Nullable String branch) { + boolean main = branch == null; + String url; + + if (main) { + url = "https://codeload.github.com/" + user + "/" + repo + "/legacy.zip/refs/heads/main"; + if (!UrlUtils.urlValid(url)) url = "https://codeload.github.com/" + user + "/" + repo + "/legacy.zip/refs/heads/master"; + Resclone.LOGGER.info("Getting from main branch."); + } + else { + url = "https://codeload.github.com/" + user + "/" + repo + "/legacy.zip/refs/heads/" + branch; + Resclone.LOGGER.info("Getting from " + branch + " branch."); + } + + return url; + } + + private String getFromTag(String user, String repo, String tag) { + Resclone.LOGGER.info("Getting from tag " + tag + "."); + return "https://codeload.github.com/" + user + "/" + repo + "/legacy.zip/refs/tags/" + tag; + } + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/fetchers/GithubMasterFetcher.java b/src/main/java/io/gitlab/jfronny/resclone/fetchers/GithubMasterFetcher.java deleted file mode 100644 index 10de409..0000000 --- a/src/main/java/io/gitlab/jfronny/resclone/fetchers/GithubMasterFetcher.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.gitlab.jfronny.resclone.fetchers; - -import io.gitlab.jfronny.resclone.data.RescloneException; - -public class GithubMasterFetcher extends PackFetcher { - @Override - public String getSourceTypeName() { - return "github-master"; - } - - @Override - public String getDownloadUrl(String baseUrl) throws RescloneException { - String[] parts = baseUrl.split("/"); - String url = ""; - if (parts.length == 2) { - url = getStr(parts[0], parts[1], "main"); - if (!urlValid(url)) - url = getStr(parts[0], parts[1], "master"); - } - else if (parts.length == 3) { - url = getStr(parts[0], parts[1], parts[2]); - } - else { - throw new RescloneException("Format for github-master is USER/REPO[/BRANCH]"); - } - return url; - } - - private String getStr(String user, String repo, String branch) { - return "https://github.com/" + user + "/" + repo + "/archive/" + branch + ".zip"; - } -} diff --git a/src/main/java/io/gitlab/jfronny/resclone/fetchers/GithubReleaseFetcher.java b/src/main/java/io/gitlab/jfronny/resclone/fetchers/GithubReleaseFetcher.java deleted file mode 100644 index 7f23124..0000000 --- a/src/main/java/io/gitlab/jfronny/resclone/fetchers/GithubReleaseFetcher.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.gitlab.jfronny.resclone.fetchers; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import io.gitlab.jfronny.resclone.data.RescloneException; - -public class GithubReleaseFetcher extends PackFetcher { - @Override - public String getSourceTypeName() { - return "github-release"; - } - - @Override - String getDownloadUrl(String baseUrl) throws RescloneException { - String[] parts = baseUrl.split("/"); - if (parts.length == 2) { - try { - JsonObject latestRelease = readJsonFromURL("https://api.github.com/repos/" + parts[0] + "/" + parts[1] + "/releases/latest", JsonObject.class); - String res = null; - for (JsonElement element : latestRelease.get("assets").getAsJsonArray()) { - JsonObject o = element.getAsJsonObject(); - if ("application/x-zip-compressed".equals(o.get("content_type").getAsString()) - || o.get("name").getAsString().endsWith(".zip")) { - res = o.get("browser_download_url").getAsString(); - break; - } - } - if (res == null) { - System.out.println("Could not find release asset for " + baseUrl + ", using zipball"); - return latestRelease.get("zipball_url").getAsString(); - } - return res; - } catch (Throwable e) { - throw new RescloneException("Failed to get github release asset", e); - } - } - else { - throw new RescloneException("Format for github-release is USER/REPO"); - } - } -} diff --git a/src/main/java/io/gitlab/jfronny/resclone/fetchers/PackFetcher.java b/src/main/java/io/gitlab/jfronny/resclone/fetchers/PackFetcher.java index 0d3fb60..21cf78d 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/fetchers/PackFetcher.java +++ b/src/main/java/io/gitlab/jfronny/resclone/fetchers/PackFetcher.java @@ -1,72 +1,42 @@ package io.gitlab.jfronny.resclone.fetchers; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; import io.gitlab.jfronny.resclone.Resclone; -import io.gitlab.jfronny.resclone.data.RescloneException; +import io.gitlab.jfronny.resclone.util.Result; import java.io.FileOutputStream; -import java.io.IOException; import java.io.InputStream; -import java.net.HttpURLConnection; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Scanner; -import java.util.Set; public abstract class PackFetcher { + abstract public String getSourceTypeName(); // The name for users to specify in the config - abstract String getDownloadUrl(String baseUrl) throws RescloneException; // Return the actual download URL for the file based on the provided string - protected final Gson gson = Resclone.gson; - protected boolean urlValid(String url) { - try { - HttpURLConnection connection = (HttpURLConnection)new URL(url).toURI().toURL().openConnection(); - connection.setRequestMethod("GET"); - connection.connect(); - return connection.getResponseCode() == 200; - } - catch (Throwable e) { - return false; - } - } - protected String readStringFromURL(String requestURL) throws IOException { - try (Scanner scanner = new Scanner(new URL(requestURL).openStream(), StandardCharsets.UTF_8.toString())) - { - scanner.useDelimiter("\\A"); - return scanner.hasNext() ? scanner.next() : ""; - } - } + abstract String getDownloadUrl(String baseUrl) throws Exception; // Return the actual download URL for the file based on the provided string - public T readJsonFromURL(String requestUrl, Class classOfT) throws IOException { - return gson.fromJson(readStringFromURL(requestUrl), classOfT); - } - - public Set readJsonFromURLSet(String requestUrl, Class classOfT) throws IOException { - return gson.fromJson(readStringFromURL(requestUrl), TypeToken.getParameterized(Set.class, classOfT).getType()); - } - - public Result get(String baseUrl, Path targetDir, boolean forceDownload) throws RescloneException { + public Result get(String baseUrl, Path targetDir, boolean forceDownload) throws Exception { String url; try { url = getDownloadUrl(baseUrl); Resclone.urlCache.set(baseUrl, url); - } - catch (RescloneException e) { + } catch (Exception e) { if (Resclone.urlCache.containsKey(baseUrl)) { e.printStackTrace(); url = Resclone.urlCache.get(baseUrl); - } - else { + } else { throw e; } } Path p = targetDir.resolve(Integer.toHexString(url.hashCode())); - if (!forceDownload && Files.exists(p)) + + if (!forceDownload && Files.exists(p)) { + Resclone.COUNT++; return new Result(p, false); - System.out.println("Downloading pack " + url); + } + + Resclone.LOGGER.info("Downloading pack: " + url); + try (InputStream is = new URL(url).openStream()) { FileOutputStream os = new FileOutputStream(p.toFile()); byte[] dataBuffer = new byte[1024]; @@ -74,21 +44,12 @@ public abstract class PackFetcher { while ((bytesRead = is.read(dataBuffer, 0, 1024)) != -1) { os.write(dataBuffer, 0, bytesRead); } - System.out.println("Completed download"); - } - catch (Throwable e) { - throw new RescloneException("Could not download pack", e); + Resclone.LOGGER.info("Finished downloading."); + } catch (Throwable e) { + throw new Exception("Could not download pack", e); } + Resclone.COUNT++; return new Result(p, true); } - public class Result { - public final Path downloadPath; - public final boolean freshDownload; - - public Result(Path downloadPath, boolean freshDownload) { - this.downloadPath = downloadPath; - this.freshDownload = freshDownload; - } - } -} +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/io/MoveDirVisitor.java b/src/main/java/io/gitlab/jfronny/resclone/io/MoveDirVisitor.java index 339b697..65f7978 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/io/MoveDirVisitor.java +++ b/src/main/java/io/gitlab/jfronny/resclone/io/MoveDirVisitor.java @@ -5,29 +5,27 @@ import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; public class MoveDirVisitor extends SimpleFileVisitor { + private final Path fromPath; private final Path toPath; private final CopyOption copyOption; - public MoveDirVisitor(Path fromPath, Path toPath, CopyOption copyOption) - { + public MoveDirVisitor(Path fromPath, Path toPath, CopyOption copyOption) { this.fromPath = fromPath; this.toPath = toPath; this.copyOption = copyOption; } @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException - { + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { Path targetPath = toPath.resolve(fromPath.relativize(dir)); - if(!Files.exists(targetPath)) + if (!Files.exists(targetPath)) Files.createDirectory(targetPath); return FileVisitResult.CONTINUE; } @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException - { + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.copy(file, toPath.resolve(fromPath.relativize(file)), copyOption); Files.delete(file); return FileVisitResult.CONTINUE; @@ -38,4 +36,5 @@ public class MoveDirVisitor extends SimpleFileVisitor { Files.delete(dir); return FileVisitResult.CONTINUE; } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/io/PathPruneVisitor.java b/src/main/java/io/gitlab/jfronny/resclone/io/PathPruneVisitor.java index 76e3fcc..76dd6f9 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/io/PathPruneVisitor.java +++ b/src/main/java/io/gitlab/jfronny/resclone/io/PathPruneVisitor.java @@ -9,7 +9,9 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.function.Predicate; public class PathPruneVisitor extends SimpleFileVisitor { + Predicate removalSelector; + public PathPruneVisitor(Predicate removalSelector) { this.removalSelector = removalSelector; } @@ -25,4 +27,5 @@ public class PathPruneVisitor extends SimpleFileVisitor { if (removalSelector.test(dir)) Files.walkFileTree(dir, new RemoveDirVisitor()); return super.postVisitDirectory(dir, exc); } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/io/RemoveDirVisitor.java b/src/main/java/io/gitlab/jfronny/resclone/io/RemoveDirVisitor.java index eb042dc..1e5c335 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/io/RemoveDirVisitor.java +++ b/src/main/java/io/gitlab/jfronny/resclone/io/RemoveDirVisitor.java @@ -1,10 +1,14 @@ package io.gitlab.jfronny.resclone.io; import java.io.IOException; -import java.nio.file.*; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; public class RemoveDirVisitor extends SimpleFileVisitor { + @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); @@ -16,4 +20,5 @@ public class RemoveDirVisitor extends SimpleFileVisitor { Files.delete(dir); return FileVisitResult.CONTINUE; } -} + +} \ No newline at end of file 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 5bf527f..dcdfb43 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/mixin/FileResourcePackProviderMixin.java +++ b/src/main/java/io/gitlab/jfronny/resclone/mixin/FileResourcePackProviderMixin.java @@ -3,7 +3,9 @@ package io.gitlab.jfronny.resclone.mixin; import io.gitlab.jfronny.resclone.Resclone; import io.gitlab.jfronny.resclone.RescloneResourcePack; import io.gitlab.jfronny.resclone.data.PackMetaLoaded; -import net.minecraft.resource.*; +import net.minecraft.resource.FileResourcePackProvider; +import net.minecraft.resource.ResourcePackProfile; +import net.minecraft.resource.ResourcePackSource; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -15,7 +17,10 @@ import java.util.function.Consumer; @Mixin(FileResourcePackProvider.class) public class FileResourcePackProviderMixin { - @Shadow @Final private ResourcePackSource field_25345; + + @Shadow + @Final + private ResourcePackSource field_25345; @Inject(at = @At("TAIL"), method = "register(Ljava/util/function/Consumer;Lnet/minecraft/resource/ResourcePackProfile$Factory;)V") public void registerExtra(Consumer consumer, ResourcePackProfile.Factory factory, CallbackInfo info) { @@ -33,4 +38,5 @@ public class FileResourcePackProviderMixin { } } } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/processors/PackProcessor.java b/src/main/java/io/gitlab/jfronny/resclone/processors/PackProcessor.java index da32494..37d2654 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/processors/PackProcessor.java +++ b/src/main/java/io/gitlab/jfronny/resclone/processors/PackProcessor.java @@ -1,9 +1,7 @@ package io.gitlab.jfronny.resclone.processors; -import io.gitlab.jfronny.resclone.data.RescloneException; - import java.nio.file.FileSystem; public abstract class PackProcessor { - public abstract void process(FileSystem p) throws RescloneException; -} + public abstract void process(FileSystem p) throws Exception; +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/processors/PruneVanillaProcessor.java b/src/main/java/io/gitlab/jfronny/resclone/processors/PruneVanillaProcessor.java index c55b3ee..8959aeb 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/processors/PruneVanillaProcessor.java +++ b/src/main/java/io/gitlab/jfronny/resclone/processors/PruneVanillaProcessor.java @@ -1,13 +1,7 @@ package io.gitlab.jfronny.resclone.processors; -import io.gitlab.jfronny.resclone.data.RescloneException; import io.gitlab.jfronny.resclone.io.PathPruneVisitor; import net.minecraft.client.MinecraftClient; -import net.minecraft.resource.ResourcePack; -import net.minecraft.resource.ResourcePackManager; -import net.minecraft.resource.ResourcePackProfile; -import net.minecraft.resource.ResourceType; -import net.minecraft.util.Identifier; import org.apache.commons.io.IOUtils; import java.io.IOException; @@ -17,8 +11,9 @@ import java.nio.file.Files; import java.nio.file.StandardOpenOption; public class PruneVanillaProcessor extends PackProcessor { + @Override - public void process(FileSystem p) throws RescloneException { + public void process(FileSystem p) throws Exception { ClassLoader cl = MinecraftClient.class.getClassLoader(); try { if (Files.isDirectory(p.getPath("/assets/minecraft"))) { @@ -32,15 +27,15 @@ public class PruneVanillaProcessor extends PackProcessor { return IOUtils.contentEquals(vn, pk); } } - } - catch (Throwable e) { + } catch (Throwable e) { e.printStackTrace(); } return false; })); } } catch (IOException e) { - throw new RescloneException("Could not prune vanilla files", e); + throw new Exception("Could not prune vanilla files", e); } } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/processors/RemoveEmptyProcessor.java b/src/main/java/io/gitlab/jfronny/resclone/processors/RemoveEmptyProcessor.java index c0351e6..56c04de 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/processors/RemoveEmptyProcessor.java +++ b/src/main/java/io/gitlab/jfronny/resclone/processors/RemoveEmptyProcessor.java @@ -1,6 +1,5 @@ package io.gitlab.jfronny.resclone.processors; -import io.gitlab.jfronny.resclone.data.RescloneException; import io.gitlab.jfronny.resclone.io.PathPruneVisitor; import java.io.IOException; @@ -10,8 +9,9 @@ import java.nio.file.Files; import java.nio.file.Path; public class RemoveEmptyProcessor extends PackProcessor { + @Override - public void process(FileSystem p) throws RescloneException { + public void process(FileSystem p) throws Exception { if (Files.exists(p.getPath("/assets"))) { try { Files.walkFileTree(p.getPath("/assets"), new PathPruneVisitor(s -> { @@ -25,8 +25,9 @@ public class RemoveEmptyProcessor extends PackProcessor { return false; })); } catch (Throwable e) { - throw new RescloneException("Failed to prune empty directories", e); + throw new Exception("Failed to prune empty directories", e); } } } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/processors/RootPathProcessor.java b/src/main/java/io/gitlab/jfronny/resclone/processors/RootPathProcessor.java index a1b56fc..0010391 100644 --- a/src/main/java/io/gitlab/jfronny/resclone/processors/RootPathProcessor.java +++ b/src/main/java/io/gitlab/jfronny/resclone/processors/RootPathProcessor.java @@ -1,14 +1,14 @@ package io.gitlab.jfronny.resclone.processors; import io.gitlab.jfronny.resclone.io.MoveDirVisitor; -import io.gitlab.jfronny.resclone.data.RescloneException; import java.io.IOException; import java.nio.file.*; public class RootPathProcessor extends PackProcessor { + @Override - public void process(FileSystem p) throws RescloneException { + public void process(FileSystem p) throws Exception { if (!Files.exists(p.getPath("/pack.mcmeta"))) { try { Path root = p.getPath("/"); @@ -20,8 +20,9 @@ public class RootPathProcessor extends PackProcessor { } } } catch (IOException e) { - throw new RescloneException("Could not fix root path", e); + throw new Exception("Could not fix root path", e); } } } -} + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/util/Result.java b/src/main/java/io/gitlab/jfronny/resclone/util/Result.java new file mode 100644 index 0000000..092fcad --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/resclone/util/Result.java @@ -0,0 +1,15 @@ +package io.gitlab.jfronny.resclone.util; + +import java.nio.file.Path; + +public class Result { + + public final Path downloadPath; + public final boolean freshDownload; + + public Result(Path downloadPath, boolean freshDownload) { + this.downloadPath = downloadPath; + this.freshDownload = freshDownload; + } + +} \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/resclone/util/UrlUtils.java b/src/main/java/io/gitlab/jfronny/resclone/util/UrlUtils.java new file mode 100644 index 0000000..e8eb113 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/resclone/util/UrlUtils.java @@ -0,0 +1,41 @@ +package io.gitlab.jfronny.resclone.util; + +import com.google.gson.reflect.TypeToken; +import io.gitlab.jfronny.resclone.Resclone; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Scanner; +import java.util.Set; + +public class UrlUtils { + + public static boolean urlValid(String url) { + try { + HttpURLConnection connection = (HttpURLConnection) new URL(url).toURI().toURL().openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + return connection.getResponseCode() == 200; + } catch (Throwable e) { + return false; + } + } + + public static String readStringFromURL(String requestURL) throws IOException { + try (Scanner scanner = new Scanner(new URL(requestURL).openStream(), StandardCharsets.UTF_8.toString())) { + scanner.useDelimiter("\\A"); + return scanner.hasNext() ? scanner.next() : ""; + } + } + + public static T readJsonFromURL(String requestUrl, Class classOfT) throws IOException { + return Resclone.gson.fromJson(readStringFromURL(requestUrl), classOfT); + } + + public static Set readJsonFromURLSet(String requestUrl, Class classOfT) throws IOException { + return Resclone.gson.fromJson(readStringFromURL(requestUrl), TypeToken.getParameterized(Set.class, classOfT).getType()); + } + +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 202312f..4868cd4 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -3,7 +3,7 @@ "id": "resclone", "version": "${version}", "name": "Resclone", - "description": "Downloads and updates resourcepacks", + "description": "Downloads and updates resourcepacks.", "authors": [ "JFronny" ],