If the resolved download url stayes the same, use the downloaded file. If it can't be resolved, use a cached entry

This commit is contained in:
JFronny 2021-03-03 08:05:21 +01:00
parent 0fb768a90e
commit 239a8ff856
No known key found for this signature in database
GPG Key ID: BEC5ACBBD4EE17E5
3 changed files with 96 additions and 36 deletions

View File

@ -0,0 +1,44 @@
package io.gitlab.jfronny.resclone;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
public class PackUrlCache {
Properties properties = new Properties();
private Path file;
public PackUrlCache(Path file) {
this.file = file;
if (Files.exists(file)) {
try (BufferedReader r = Files.newBufferedReader(file)) {
properties.load(r);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void save() {
try (BufferedWriter w = Files.newBufferedWriter(file)) {
properties.store(w, "This is an internal file used for offline pack loading, do not edit");
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean containsKey(String key) {
return properties.containsKey(key);
}
public String get(String key) {
return properties.getProperty(key);
}
public void set(String key, String value) {
properties.setProperty(key, value);
}
}

View File

@ -28,10 +28,12 @@ public class Resclone implements ModInitializer, RescloneApi {
public static final Set<PackMetaLoaded> downloadedPacks = new LinkedHashSet<>(); public static final Set<PackMetaLoaded> downloadedPacks = new LinkedHashSet<>();
public static final Gson gson = new Gson(); public static final Gson gson = new Gson();
public static final String MOD_ID = "resclone"; public static final String MOD_ID = "resclone";
public static PackUrlCache urlCache;
@Override @Override
public void onInitialize() { public void onInitialize() {
System.out.println("[resclone] Beginning init, will download packs"); System.out.println("[resclone] Beginning init, will download packs");
urlCache = new PackUrlCache(getConfigPath().resolve("urlCache.properties"));
conf.clear(); conf.clear();
fetcherInstances.clear(); fetcherInstances.clear();
processors.clear(); processors.clear();
@ -67,58 +69,44 @@ public class Resclone implements ModInitializer, RescloneApi {
@Override @Override
public void reload() { public void reload() {
//Get paths from patchers. Downloading is implemented in PackFetcher to allow for unconsidered sources //Get paths from patchers. Downloading is implemented in PackFetcher to allow for unconsidered sources
//TODO implement downloading again after a set time if downloadable
Set<PackMetaLoaded> metas = new LinkedHashSet<>(); Set<PackMetaLoaded> metas = new LinkedHashSet<>();
//Download //Download
for (PackMetaUnloaded s : conf) { for (PackMetaUnloaded s : conf) {
try { try {
if (!fetcherInstances.containsKey(s.fetcher)) if (!fetcherInstances.containsKey(s.fetcher))
throw new RescloneException("Invalid fetcher: " + s.fetcher); throw new RescloneException("Invalid fetcher: " + s.fetcher);
String fileName = ""; Path cacheDir = getConfigPath().resolve("cache");
fileName += Integer.toHexString(s.fetcher.hashCode()); PackMetaLoaded p;
fileName += Integer.toHexString(s.source.hashCode());
PackMetaLoaded p = new PackMetaLoaded(getConfigPath().resolve("cache").resolve(fileName), s.name);
//If file is not present: download and process pack
Path p1 = p.zipPath;
if (Files.exists(p.zipPath)) {
p1 = p.zipPath.getParent().resolve(p.zipPath.getFileName() + ".bak");
Files.deleteIfExists(p1);
Files.move(p.zipPath, p1);
}
try { try {
//Download //Download
fetcherInstances.get(s.fetcher).get(s.source, p.zipPath); PackFetcher.FetcherResult fr = fetcherInstances.get(s.fetcher).get(s.source, cacheDir);
//Process p = new PackMetaLoaded(fr.downloadPath, s.name);
Map<String, String> props = new HashMap<>(); metas.add(p);
props.put("create", "false"); if (fr.freshDownload) {
URI zipfile = URI.create("jar:" + p.zipPath.toUri().toString()); //Process
try (FileSystem zipfs = FileSystems.newFileSystem(zipfile, props)) { Map<String, String> props = new HashMap<>();
for (PackProcessor processor : processors) { props.put("create", "false");
processor.process(zipfs); URI zipfile = URI.create("jar:" + p.zipPath.toUri().toString());
} try (FileSystem zipfs = FileSystems.newFileSystem(zipfile, props)) {
for (PackProcessor processor : processors) {
processor.process(zipfs);
}
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
}
} }
} }
catch (Throwable e) { catch (Throwable e) {
if (!p1.equals(p.zipPath)) { throw new RescloneException("Failed to download pack", e);
e.printStackTrace();
System.err.println("Failed to download, using cache");
Files.deleteIfExists(p.zipPath);
Files.move(p1, p.zipPath);
} else
throw new RescloneException("Failed to download initial", e);
} }
if (!p1.equals(p.zipPath))
Files.deleteIfExists(p1);
metas.add(p);
} catch (Throwable e) { } catch (Throwable e) {
System.err.println("Encountered issue while preparing " + s.name); System.err.println("Encountered issue while preparing " + s.name);
e.printStackTrace(); e.printStackTrace();
} }
} }
//Set variable //Set variable
urlCache.save();
downloadedPacks.clear(); downloadedPacks.clear();
downloadedPacks.addAll(metas); downloadedPacks.addAll(metas);
} }

View File

@ -11,6 +11,7 @@ import java.io.InputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Scanner; import java.util.Scanner;
import java.util.Set; import java.util.Set;
@ -47,11 +48,27 @@ public abstract class PackFetcher {
return gson.fromJson(readStringFromURL(requestUrl), TypeToken.getParameterized(Set.class, classOfT).getType()); return gson.fromJson(readStringFromURL(requestUrl), TypeToken.getParameterized(Set.class, classOfT).getType());
} }
public void get(String baseUrl, Path targetPath) throws RescloneException { public FetcherResult get(String baseUrl, Path targetDir) throws RescloneException {
String url = getDownloadUrl(baseUrl); String url;
try {
url = getDownloadUrl(baseUrl);
Resclone.urlCache.set(baseUrl, url);
}
catch (RescloneException e) {
if (Resclone.urlCache.containsKey(baseUrl)) {
e.printStackTrace();
url = Resclone.urlCache.get(baseUrl);
}
else {
throw e;
}
}
Path p = targetDir.resolve(Integer.toHexString(url.hashCode()));
if (Files.exists(p))
return new FetcherResult(p, false);
System.out.println("Downloading pack " + url); System.out.println("Downloading pack " + url);
try (InputStream is = new URL(url).openStream()) { try (InputStream is = new URL(url).openStream()) {
FileOutputStream os = new FileOutputStream(targetPath.toFile()); FileOutputStream os = new FileOutputStream(p.toFile());
byte[] dataBuffer = new byte[1024]; byte[] dataBuffer = new byte[1024];
int bytesRead; int bytesRead;
while ((bytesRead = is.read(dataBuffer, 0, 1024)) != -1) { while ((bytesRead = is.read(dataBuffer, 0, 1024)) != -1) {
@ -62,5 +79,16 @@ public abstract class PackFetcher {
catch (Throwable e) { catch (Throwable e) {
throw new RescloneException("Could not download pack", e); throw new RescloneException("Could not download pack", e);
} }
return new FetcherResult(p, true);
}
public class FetcherResult {
public final Path downloadPath;
public final boolean freshDownload;
public FetcherResult(Path downloadPath, boolean freshDownload) {
this.downloadPath = downloadPath;
this.freshDownload = freshDownload;
}
} }
} }