Respackopts/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java
2021-08-26 23:39:04 +02:00

166 lines
6.6 KiB
Java

package io.gitlab.jfronny.respackopts;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.gitlab.jfronny.libjf.data.WrappedPack;
import io.gitlab.jfronny.respackopts.data.DirRpo;
import io.gitlab.jfronny.respackopts.data.PackCapability;
import io.gitlab.jfronny.respackopts.data.Respackmeta;
import io.gitlab.jfronny.respackopts.data.Rpo;
import io.gitlab.jfronny.respackopts.data.entry.*;
import io.gitlab.jfronny.respackopts.filters.DirFilterProvider;
import io.gitlab.jfronny.respackopts.filters.FileFilterProvider;
import io.gitlab.jfronny.respackopts.gson.*;
import meteordevelopment.starscript.Script;
import meteordevelopment.starscript.StandardLib;
import meteordevelopment.starscript.Starscript;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.gui.FabricGuiEntry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@Environment(EnvType.CLIENT)
public class Respackopts implements ClientModInitializer {
public static final Integer META_VERSION = 5;
public static final String ID = "respackopts";
public static final Identifier CONF_ID = new Identifier(ID, "conf.json");
public static final Logger LOGGER = LogManager.getFormatterLogger(ID);
public static final String FILE_EXTENSION = ".rpo";
public static final Set<Runnable> SAVE_ACTIONS = new HashSet<>();
public static Path CONF_DIR;
public static final Map<String, ConfigBranch> CONFIG_BRANCH = new HashMap<>();
public static final Map<String, Respackmeta> PACK_METAS = new HashMap<>();
public static final Map<String, String> DISPLAY_NAME_LOOKUP = new HashMap<>();
public static final Map<String, String> PACK_NAME_LOOKUP = new HashMap<>();
public static Starscript STAR_SCRIPT;
public static final Gson GSON;
public static GuiFactory factory = new GuiFactory();
public static boolean forceRespackReload = false;
static {
GSON = new GsonBuilder()
.registerTypeAdapter(ConfigEnumEntry.class, new EnumEntrySerializer())
.registerTypeAdapter(ConfigNumericEntry.class, new NumericEntrySerializer())
.registerTypeAdapter(ConfigBooleanEntry.class, new BooleanEntrySerializer())
.registerTypeAdapter(ConfigBranch.class, new ConfigBranchSerializer())
.registerTypeAdapter(Script.class, new ScriptDeserializer())
.registerTypeAdapter(Rpo.class, new RpoDeserializer())
.registerTypeAdapter(DirRpo.class, new DirRpoDeserializer())
.setPrettyPrinting()
.create();
try {
STAR_SCRIPT = new Starscript();
} catch (Throwable e) {
FabricGuiEntry.displayCriticalError(new Exception("Respackopts could not initialize Starscript. Expect issues with packs that use it", e), false);
}
StandardLib.init(STAR_SCRIPT);
try {
CONF_DIR = FabricLoader.getInstance().getConfigDir().resolve(ID);
} catch (Throwable e) {
LOGGER.error("Could not resolve config directory", e);
}
}
public static String getId(WrappedPack pack) {
return PACK_NAME_LOOKUP.get(pack.getName());
}
public static boolean hasCapability(WrappedPack pack, PackCapability capability) {
String id = getId(pack);
if (id == null) return false;
return PACK_METAS.get(id).capabilities.contains(capability);
}
@Override
public void onInitializeClient() {
try {
Files.createDirectories(CONF_DIR);
} catch (IOException e) {
LOGGER.error("Could not initialize config directory", e);
}
if (FabricLoader.getInstance().isDevelopmentEnvironment())
SAVE_ACTIONS.add(() -> LOGGER.info("Save"));
SAVE_ACTIONS.add(() -> {
for (Map.Entry<String, ConfigBranch> e : CONFIG_BRANCH.entrySet()) {
STAR_SCRIPT.set(sanitizeString(e.getKey()), () -> e.getValue().buildStarscript());
}
});
DirFilterProvider.init();
FileFilterProvider.init();
}
public static void save() {
for (Map.Entry<String, ConfigBranch> e : CONFIG_BRANCH.entrySet()) {
try (Writer writer = Files.newBufferedWriter(CONF_DIR.resolve(e.getKey() + ".json"))) {
GSON.toJson(e.getValue(), writer);
writer.flush();
} catch (IOException ex) {
LOGGER.error("Could not save config", ex);
}
}
for (Runnable action : SAVE_ACTIONS) {
action.run();
}
}
public static void load(String id) {
Path q = CONF_DIR.resolve(id + ".json");
if (Files.exists(q)) {
try (Reader reader = Files.newBufferedReader(q)) {
ConfigBranch b = GSON.fromJson(reader, ConfigBranch.class);
if (CONFIG_BRANCH.containsKey(id))
CONFIG_BRANCH.get(id).sync(b, SyncMode.CONF_LOAD);
STAR_SCRIPT.set(sanitizeString(id), b::buildStarscript);
} catch (IOException e) {
LOGGER.error("Failed to load " + id, e);
}
}
}
public static String sanitizeString(String s) {
// This trims whitespace/underscores and removes non-alphabetical or underscore characters
// ^ = start of string
// $ = end of string
// * = zero or more times
// [\\s_] = whitespace or underscores
// | = or
// [^a-zA-Z_] = not character or underscore
return s.replaceAll("[^a-zA-Z_]|^[\\s_]*|[\\s_]*$", "");
}
public static CompletableFuture<Void> forceReloadResources() {
return CompletableFuture.allOf(MinecraftClient.getInstance().reloadResources(),
reloadData());
}
public static CompletableFuture<Void> reloadData() {
IntegratedServer is = MinecraftClient.getInstance().getServer();
if (is != null) {
is.getDataPackManager().scanPacks();
return is.reloadResources(is.getDataPackManager().getEnabledNames());
}
return CompletableFuture.completedFuture(null);
}
}