2020-12-29 16:14:53 +01:00
|
|
|
package io.gitlab.jfronny.resclone;
|
|
|
|
|
|
|
|
import com.google.gson.Gson;
|
2021-05-11 17:51:34 +02:00
|
|
|
import io.gitlab.jfronny.resclone.api.PackFetcher;
|
2020-12-29 16:14:53 +01:00
|
|
|
import io.gitlab.jfronny.resclone.api.RescloneApi;
|
|
|
|
import io.gitlab.jfronny.resclone.api.RescloneEntry;
|
2021-04-03 02:40:38 +02:00
|
|
|
import io.gitlab.jfronny.resclone.data.PackMetaLoaded;
|
2020-12-29 16:14:53 +01:00
|
|
|
import io.gitlab.jfronny.resclone.data.PackMetaUnloaded;
|
2021-05-11 17:51:34 +02:00
|
|
|
import io.gitlab.jfronny.resclone.api.PackProcessor;
|
2020-12-29 16:14:53 +01:00
|
|
|
import io.gitlab.jfronny.resclone.processors.RemoveEmptyProcessor;
|
|
|
|
import io.gitlab.jfronny.resclone.processors.RootPathProcessor;
|
2021-05-07 17:39:13 +02:00
|
|
|
import io.gitlab.jfronny.resclone.util.PackUrlCache;
|
2021-04-03 02:40:38 +02:00
|
|
|
import io.gitlab.jfronny.resclone.util.Result;
|
2020-12-29 22:22:23 +01:00
|
|
|
import net.fabricmc.api.ModInitializer;
|
2020-12-29 16:14:53 +01:00
|
|
|
import net.fabricmc.loader.api.FabricLoader;
|
2022-02-28 20:53:46 +01:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
2020-12-29 16:14:53 +01:00
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.URI;
|
|
|
|
import java.nio.file.FileSystem;
|
|
|
|
import java.nio.file.FileSystems;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.util.*;
|
2021-05-07 17:39:13 +02:00
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
import java.util.concurrent.Executors;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
2020-12-29 16:14:53 +01:00
|
|
|
|
2020-12-29 22:22:23 +01:00
|
|
|
public class Resclone implements ModInitializer, RescloneApi {
|
2020-12-29 16:14:53 +01:00
|
|
|
public static final Set<PackMetaUnloaded> conf = new LinkedHashSet<>();
|
|
|
|
public static final Map<String, PackFetcher> fetcherInstances = new LinkedHashMap<>();
|
|
|
|
public static final Set<PackProcessor> processors = new LinkedHashSet<>();
|
|
|
|
public static final Set<PackMetaLoaded> downloadedPacks = new LinkedHashSet<>();
|
2021-05-11 17:51:34 +02:00
|
|
|
public static final Set<PackMetaLoaded> newPacks = new LinkedHashSet<>();
|
2020-12-29 16:14:53 +01:00
|
|
|
public static final Gson gson = new Gson();
|
2021-04-03 02:40:38 +02:00
|
|
|
|
2020-12-29 16:14:53 +01:00
|
|
|
public static final String MOD_ID = "resclone";
|
2022-02-28 20:53:46 +01:00
|
|
|
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
2021-04-03 02:40:38 +02:00
|
|
|
|
2021-03-03 08:05:21 +01:00
|
|
|
public static PackUrlCache urlCache;
|
2020-12-29 16:14:53 +01:00
|
|
|
|
2021-04-03 06:34:52 +02:00
|
|
|
public static int COUNT = 0;
|
|
|
|
|
2020-12-29 16:14:53 +01:00
|
|
|
@Override
|
2020-12-29 22:22:23 +01:00
|
|
|
public void onInitialize() {
|
2021-04-03 02:40:38 +02:00
|
|
|
LOGGER.info("Initialising Resclone.");
|
|
|
|
|
2021-03-03 08:05:21 +01:00
|
|
|
urlCache = new PackUrlCache(getConfigPath().resolve("urlCache.properties"));
|
2020-12-29 16:14:53 +01:00
|
|
|
conf.clear();
|
|
|
|
fetcherInstances.clear();
|
|
|
|
processors.clear();
|
|
|
|
downloadedPacks.clear();
|
2021-04-03 02:40:38 +02:00
|
|
|
|
2020-12-29 16:14:53 +01:00
|
|
|
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);
|
2021-04-03 02:40:38 +02:00
|
|
|
} catch (Exception e) {
|
2020-12-29 16:14:53 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
addProcessor(new RemoveEmptyProcessor());
|
2020-12-29 22:22:23 +01:00
|
|
|
reload();
|
2021-04-03 02:40:38 +02:00
|
|
|
|
2021-04-03 06:34:52 +02:00
|
|
|
LOGGER.info("Installed {} resource pack{}.", COUNT, COUNT == 1 ? "" : "s");
|
2020-12-29 16:14:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void addFetcher(PackFetcher fetcher) {
|
|
|
|
fetcherInstances.put(fetcher.getSourceTypeName(), fetcher);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void addProcessor(PackProcessor processor) {
|
|
|
|
processors.add(processor);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void addPack(String fetcher, String pack, String name) {
|
2021-03-03 08:14:52 +01:00
|
|
|
addPack(fetcher, pack, name, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void addPack(String fetcher, String pack, String name, boolean forceRedownload) {
|
2021-05-11 17:51:34 +02:00
|
|
|
addPack(fetcher, pack, name, forceRedownload, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void addPack(String fetcher, String pack, String name, boolean forceRedownload, boolean forceEnable) {
|
|
|
|
conf.add(new PackMetaUnloaded(fetcher, pack, name, forceRedownload, forceEnable));
|
2020-12-29 16:14:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-12-29 22:22:23 +01:00
|
|
|
public void reload() {
|
2020-12-29 16:14:53 +01:00
|
|
|
Set<PackMetaLoaded> metas = new LinkedHashSet<>();
|
2021-05-07 17:39:13 +02:00
|
|
|
try {
|
2021-06-11 18:49:29 +02:00
|
|
|
if (conf.isEmpty()) {
|
|
|
|
LOGGER.info("No resclone pack was specified, add one");
|
2021-05-07 17:39:13 +02:00
|
|
|
}
|
2021-06-11 18:49:29 +02:00
|
|
|
else {
|
|
|
|
ExecutorService pool = Executors.newFixedThreadPool(conf.size());
|
|
|
|
for (PackMetaUnloaded s : conf) {
|
|
|
|
pool.submit(generateTask(s, metas));
|
|
|
|
}
|
|
|
|
pool.shutdown();
|
|
|
|
if (!pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS)) {
|
|
|
|
LOGGER.error("Download timed out. This shouldn't be possible");
|
|
|
|
}
|
2021-05-07 17:39:13 +02:00
|
|
|
}
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
urlCache.save();
|
|
|
|
downloadedPacks.clear();
|
|
|
|
downloadedPacks.addAll(metas);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Runnable generateTask(PackMetaUnloaded meta, Set<PackMetaLoaded> metas) {
|
|
|
|
return () -> {
|
2020-12-29 16:14:53 +01:00
|
|
|
try {
|
2021-05-07 17:39:13 +02:00
|
|
|
if (!fetcherInstances.containsKey(meta.fetcher))
|
|
|
|
throw new Exception("Invalid fetcher: " + meta.fetcher);
|
2021-03-03 08:05:21 +01:00
|
|
|
Path cacheDir = getConfigPath().resolve("cache");
|
|
|
|
PackMetaLoaded p;
|
2020-12-29 16:32:47 +01:00
|
|
|
try {
|
2021-05-11 17:51:34 +02:00
|
|
|
boolean isNew = !urlCache.containsKey(meta.source);
|
2020-12-29 16:14:53 +01:00
|
|
|
//Download
|
2021-05-07 17:39:13 +02:00
|
|
|
Result fr = fetcherInstances.get(meta.fetcher).get(meta.source, cacheDir, meta.forceDownload);
|
2021-05-11 17:51:34 +02:00
|
|
|
p = new PackMetaLoaded(fr.downloadPath, meta.name, meta.forceEnable);
|
2021-03-03 08:05:21 +01:00
|
|
|
metas.add(p);
|
2021-05-11 17:51:34 +02:00
|
|
|
if (isNew)
|
|
|
|
newPacks.add(p);
|
2021-03-03 08:05:21 +01:00
|
|
|
if (fr.freshDownload) {
|
|
|
|
//Process
|
|
|
|
Map<String, String> props = new HashMap<>();
|
|
|
|
props.put("create", "false");
|
2021-04-03 02:40:38 +02:00
|
|
|
URI zipfile = URI.create("jar:" + p.zipPath.toUri());
|
2021-03-03 08:05:21 +01:00
|
|
|
try (FileSystem zipfs = FileSystems.newFileSystem(zipfile, props)) {
|
|
|
|
for (PackProcessor processor : processors) {
|
|
|
|
processor.process(zipfs);
|
|
|
|
}
|
2020-12-29 16:14:53 +01:00
|
|
|
|
2021-03-03 08:05:21 +01:00
|
|
|
} catch (Throwable e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2020-12-29 16:14:53 +01:00
|
|
|
}
|
2021-04-03 02:40:38 +02:00
|
|
|
} catch (Throwable e) {
|
|
|
|
throw new Exception("Failed to download pack", e);
|
2020-12-29 16:32:47 +01:00
|
|
|
}
|
|
|
|
} catch (Throwable e) {
|
2021-05-07 17:39:13 +02:00
|
|
|
LOGGER.error("Encountered issue while preparing " + meta.name, e);
|
2020-12-29 16:14:53 +01:00
|
|
|
}
|
2021-05-07 17:39:13 +02:00
|
|
|
};
|
2020-12-29 16:14:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Path getConfigPath() {
|
|
|
|
Path configPath = FabricLoader.getInstance().getConfigDir().resolve("resclone");
|
|
|
|
if (!Files.isDirectory(configPath.resolve("cache"))) {
|
|
|
|
try {
|
|
|
|
Files.createDirectories(configPath.resolve("cache"));
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return configPath;
|
|
|
|
}
|
2021-04-03 02:40:38 +02:00
|
|
|
}
|