Implement a config for Respackopts

This commit is contained in:
JFronny 2021-09-15 18:37:07 +02:00
parent 1cf5f3cef8
commit 2c1fc5b414
No known key found for this signature in database
GPG Key ID: BEC5ACBBD4EE17E5
24 changed files with 208 additions and 105 deletions

View File

@ -21,5 +21,5 @@ You will then need to include this file in the places you want to access its val
## Using the values
All values respackotps exposes follow the form: `<id>_<entry>` or `<id>_<category>_<entry>`
To view the code respackotps generates for your pack, you can run the `/rpo dump frex` command in minecraft.
To view the code respackotps generates for your pack, you can run the `/rpo dump frex` command in minecraft (You must enable the `debugCommands` config option for this).
This will create a frex.frag file in your .minecraft/respackotps directory containing the generated shader code (available since 2.7.0).

View File

@ -1,32 +1,21 @@
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.condition.Condition;
import io.gitlab.jfronny.respackopts.data.*;
import io.gitlab.jfronny.respackopts.filters.DirFilterEventImpl;
import io.gitlab.jfronny.respackopts.util.RpoCommand;
import io.gitlab.jfronny.respackopts.data.DirRpo;
import io.gitlab.jfronny.respackopts.data.PackCapability;
import io.gitlab.jfronny.respackopts.data.PackMeta;
import io.gitlab.jfronny.respackopts.data.FileRpo;
import io.gitlab.jfronny.respackopts.data.entry.*;
import io.gitlab.jfronny.respackopts.filters.FileFilterEventImpl;
import io.gitlab.jfronny.respackopts.gson.*;
import io.gitlab.jfronny.respackopts.util.GuiFactory;
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;
@ -41,48 +30,25 @@ 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, PackMeta> 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 Identifier CONF_ID = new Identifier(RpoModInfo.ID, "conf.json");
public static final Set<Runnable> SAVE_ACTIONS = new HashSet<>();
public static final Gson GSON;
public static GuiFactory factory = new GuiFactory();
public static boolean forcePackReload = 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(FileRpo.class, new RpoDeserializer())
.registerTypeAdapter(DirRpo.class, new DirRpoDeserializer())
.registerTypeAdapter(Condition.class, new ConditionDeserializer())
.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) {
@ -98,12 +64,12 @@ public class Respackopts implements ClientModInitializer {
@Override
public void onInitializeClient() {
try {
Files.createDirectories(CONF_DIR);
Files.createDirectories(RpoModInfo.CONF_DIR);
} catch (IOException e) {
LOGGER.error("Could not initialize config directory", e);
RpoModInfo.LOGGER.error("Could not initialize config directory", e);
}
if (FabricLoader.getInstance().isDevelopmentEnvironment())
SAVE_ACTIONS.add(() -> LOGGER.info("Save"));
if (RpoModInfo.CONFIG.debugLogs)
SAVE_ACTIONS.add(() -> RpoModInfo.LOGGER.info("Save"));
SAVE_ACTIONS.add(() -> {
for (Map.Entry<String, ConfigBranch> e : CONFIG_BRANCH.entrySet()) {
STAR_SCRIPT.set(sanitizeString(e.getKey()), () -> e.getValue().buildStarscript());
@ -111,16 +77,19 @@ public class Respackopts implements ClientModInitializer {
});
DirFilterEventImpl.init();
FileFilterEventImpl.init();
RpoCommand.register();
if (RpoModInfo.CONFIG.debugCommands)
RpoCommand.register();
}
public static void save() {
if (RpoModInfo.CONFIG.debugLogs)
RpoModInfo.LOGGER.info("Saving configs");
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);
try (Writer writer = Files.newBufferedWriter(RpoModInfo.CONF_DIR.resolve(e.getKey() + ".json"))) {
RpoModInfo.GSON.toJson(e.getValue(), writer);
writer.flush();
} catch (IOException ex) {
LOGGER.error("Could not save config", ex);
RpoModInfo.LOGGER.error("Could not save config", ex);
}
}
for (Runnable action : SAVE_ACTIONS) {
@ -129,15 +98,17 @@ public class Respackopts implements ClientModInitializer {
}
public static void load(String id) {
Path q = CONF_DIR.resolve(id + ".json");
Path q = RpoModInfo.CONF_DIR.resolve(id + ".json");
if (Files.exists(q)) {
if (RpoModInfo.CONFIG.debugLogs)
RpoModInfo.LOGGER.info("Loading configs for: " + id);
try (Reader reader = Files.newBufferedReader(q)) {
ConfigBranch b = GSON.fromJson(reader, ConfigBranch.class);
ConfigBranch b = RpoModInfo.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);
RpoModInfo.LOGGER.error("Failed to load " + id, e);
}
}
}
@ -155,6 +126,8 @@ public class Respackopts implements ClientModInitializer {
}
public static CompletableFuture<Void> forceReloadResources() {
if (RpoModInfo.CONFIG.debugLogs)
RpoModInfo.LOGGER.info("Forcing resource reload");
return CompletableFuture.allOf(MinecraftClient.getInstance().reloadResources(),
reloadData());
}

View File

@ -0,0 +1,49 @@
package io.gitlab.jfronny.respackopts;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.gitlab.jfronny.respackopts.data.ConfigFile;
import io.gitlab.jfronny.respackopts.data.DirRpo;
import io.gitlab.jfronny.respackopts.data.FileRpo;
import io.gitlab.jfronny.respackopts.data.condition.Condition;
import io.gitlab.jfronny.respackopts.data.entry.ConfigBooleanEntry;
import io.gitlab.jfronny.respackopts.data.entry.ConfigBranch;
import io.gitlab.jfronny.respackopts.data.entry.ConfigEnumEntry;
import io.gitlab.jfronny.respackopts.data.entry.ConfigNumericEntry;
import io.gitlab.jfronny.respackopts.gson.*;
import meteordevelopment.starscript.Script;
import net.fabricmc.loader.api.FabricLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Path;
public class RpoModInfo {
public static final Integer META_VERSION = 5;
public static final String ID = "respackopts";
public static final Logger LOGGER = LogManager.getFormatterLogger(ID);
public static final String FILE_EXTENSION = ".rpo";
public static Path CONF_DIR;
public static ConfigFile CONFIG;
public static final Gson GSON;
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(FileRpo.class, new RpoDeserializer())
.registerTypeAdapter(DirRpo.class, new DirRpoDeserializer())
.registerTypeAdapter(Condition.class, new ConditionDeserializer())
.setPrettyPrinting()
.create();
try {
CONF_DIR = FabricLoader.getInstance().getConfigDir().resolve(ID);
CONFIG = ConfigFile.load();
} catch (Throwable e) {
LOGGER.error("Could not resolve config directory", e);
}
}
}

View File

@ -0,0 +1,43 @@
package io.gitlab.jfronny.respackopts.data;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ConfigFile {
public boolean debugCommands = false;
public boolean debugLogs = false;
public boolean dashloaderCompat = true;
private static final Path rpoPath = RpoModInfo.CONF_DIR.resolve("_respackopts.conf");
public static ConfigFile load() {
if (!Files.exists(rpoPath))
new ConfigFile().save();
try (BufferedReader br = Files.newBufferedReader(rpoPath)) {
return RpoModInfo.GSON.fromJson(br, ConfigFile.class);
} catch (IOException e) {
RpoModInfo.LOGGER.error("Could not load config, using default", e);
return new ConfigFile();
}
}
public void save() {
if (!Files.exists(RpoModInfo.CONF_DIR)) {
try {
Files.createDirectories(RpoModInfo.CONF_DIR);
} catch (IOException e) {
RpoModInfo.LOGGER.error("Could not create config dir", e);
return;
}
}
try (BufferedWriter bw = Files.newBufferedWriter(rpoPath)) {
RpoModInfo.GSON.toJson(this, bw);
} catch (IOException e) {
RpoModInfo.LOGGER.error("Could not save", e);
}
}
}

View File

@ -2,6 +2,7 @@ package io.gitlab.jfronny.respackopts.data.entry;
import com.google.common.collect.ImmutableMap;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.util.RpoFormatException;
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
@ -55,10 +56,10 @@ public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
}
else {
if (mode == SyncMode.RESPACK_LOAD) {
Respackopts.LOGGER.warn("Type mismatch in config (" + getName() + "), overwriting");
RpoModInfo.LOGGER.warn("Type mismatch in config (" + getName() + "), overwriting");
add(e.getKey(), e.getValue().clone());
} else
Respackopts.LOGGER.warn("Type mismatch in config (" + getName() + "), ignoring");
RpoModInfo.LOGGER.warn("Type mismatch in config (" + getName() + "), ignoring");
}
}
}

View File

@ -1,12 +1,11 @@
package io.gitlab.jfronny.respackopts.data.entry;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import meteordevelopment.starscript.value.Value;
import net.minecraft.text.Text;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
@ -35,7 +34,7 @@ public abstract class ConfigEntry<T> {
public T getValue() {
if (value == null) {
if (defaultValue == null) {
Respackopts.LOGGER.warn("No default value or current value set for entry, returning null in " + getName());
RpoModInfo.LOGGER.warn("No default value or current value set for entry, returning null in " + getName());
return null;
}
value = getDefault();
@ -51,7 +50,7 @@ public abstract class ConfigEntry<T> {
public T getDefault() {
if (defaultValue == null) {
defaultValue = getValue();
Respackopts.LOGGER.warn("No default value set for entry, using current in " + getName());
RpoModInfo.LOGGER.warn("No default value set for entry, using current in " + getName());
}
return defaultValue;
}

View File

@ -1,5 +1,6 @@
package io.gitlab.jfronny.respackopts.data.entry;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.util.GuiFactory;
import io.gitlab.jfronny.respackopts.Respackopts;
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
@ -62,7 +63,7 @@ public class ConfigEnumEntry extends ConfigEntry<String> {
setValue(values.get(n.nextValue));
}
else {
Respackopts.LOGGER.error("Could not load default value for enum in " + getName());
RpoModInfo.LOGGER.error("Could not load default value for enum in " + getName());
}
}
}

View File

@ -4,6 +4,7 @@ import io.gitlab.jfronny.libjf.data.ResourcePath;
import io.gitlab.jfronny.libjf.data.UserResourceEvents;
import io.gitlab.jfronny.libjf.data.WrappedPack;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.data.DirRpo;
import io.gitlab.jfronny.respackopts.data.PackCapability;
import io.gitlab.jfronny.respackopts.util.RpoFormatException;
@ -86,7 +87,7 @@ public class DirFilterEventImpl {
try {
return !rpo.conditions.evaluate(packId);
} catch (RpoFormatException e) {
Respackopts.LOGGER.error("Couldn't parse dir conditions", e);
RpoModInfo.LOGGER.error("Couldn't parse dir conditions", e);
}
return false;
}
@ -108,13 +109,13 @@ public class DirFilterEventImpl {
}
if (pack.getUnderlying().contains(rp.getType(), rp.getId())) {
try (InputStream stream = pack.getUnderlying().open(rp.getType(), rp.getId()); Reader w = new InputStreamReader(stream)) {
drp = Respackopts.GSON.fromJson(w, DirRpo.class);
drp = RpoModInfo.GSON.fromJson(w, DirRpo.class);
drp.path = name;
if (drp.fallback != null && !drp.fallback.endsWith("/"))
drp.fallback += "/";
return drp;
} catch (IOException e) {
Respackopts.LOGGER.error("Couldn't open dir rpo", e);
RpoModInfo.LOGGER.error("Couldn't open dir rpo", e);
}
}
return null;

View File

@ -2,6 +2,7 @@ package io.gitlab.jfronny.respackopts.filters.util;
import io.gitlab.jfronny.libjf.data.WrappedPack;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.util.RpoFormatException;
public class FileExclusionProvider {
@ -12,7 +13,7 @@ public class FileExclusionProvider {
try {
return !rpo.conditions.evaluate(Respackopts.getId(pack));
} catch (RpoFormatException e) {
Respackopts.LOGGER.error("Could not evaluate condition " + name, e);
RpoModInfo.LOGGER.error("Could not evaluate condition " + name, e);
return false;
}
}, false);

View File

@ -2,6 +2,7 @@ package io.gitlab.jfronny.respackopts.filters.util;
import io.gitlab.jfronny.libjf.data.WrappedPack;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import meteordevelopment.starscript.Script;
import java.io.*;
@ -23,7 +24,7 @@ public class FileExpansionProvider {
try {
return replace(inputStream, rpo.expansions);
} catch (IOException e) {
Respackopts.LOGGER.error("Could not perform file expansion on " + name, e);
RpoModInfo.LOGGER.error("Could not perform file expansion on " + name, e);
return inputStream;
}
}, inputStream);

View File

@ -2,7 +2,7 @@ package io.gitlab.jfronny.respackopts.filters.util;
import io.gitlab.jfronny.libjf.data.ResourcePath;
import io.gitlab.jfronny.libjf.data.WrappedPack;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
@ -36,10 +36,10 @@ public class FileFallbackProvider {
return pack.open(tmp.getType(), tmp.getId());
}
}
Respackopts.LOGGER.error("Could not determine replacement for " + name);
RpoModInfo.LOGGER.error("Could not determine replacement for " + name);
}
catch (Exception e) {
Respackopts.LOGGER.error("Could not determine replacement for " + name, e);
RpoModInfo.LOGGER.error("Could not determine replacement for " + name, e);
}
return null;
}, null);
@ -50,7 +50,7 @@ public class FileFallbackProvider {
for (Identifier identifier : ret) {
String path = identifier.getPath();
if (FileRpoSearchProvider.isRpo(path)) {
String expectedTarget = path.substring(0, path.length() - Respackopts.FILE_EXTENSION.length());
String expectedTarget = path.substring(0, path.length() - RpoModInfo.FILE_EXTENSION.length());
if (ret.stream().noneMatch(s -> s.getPath().equals(expectedTarget)) && fileVisible(pack, type.getDirectory() + "/" + expectedTarget)) {
ret.add(new Identifier(namespace, expectedTarget));
}

View File

@ -2,7 +2,7 @@ package io.gitlab.jfronny.respackopts.filters.util;
import io.gitlab.jfronny.libjf.data.ResourcePath;
import io.gitlab.jfronny.libjf.data.WrappedPack;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.data.FileRpo;
import java.io.InputStream;
@ -11,7 +11,7 @@ import java.io.Reader;
public class FileRpoSearchProvider {
public static boolean isRpo(String fileName) {
return fileName.endsWith(Respackopts.FILE_EXTENSION);
return fileName.endsWith(RpoModInfo.FILE_EXTENSION);
}
public static <T> T modifyWithRpo(String fileName, WrappedPack pack, ModifiedGenerator<T> getModified, T defaultValue) {
@ -19,18 +19,18 @@ public class FileRpoSearchProvider {
return defaultValue;
ResourcePath rpoPath;
try {
rpoPath = new ResourcePath(fileName + Respackopts.FILE_EXTENSION);
rpoPath = new ResourcePath(fileName + RpoModInfo.FILE_EXTENSION);
if (!pack.contains(rpoPath.getType(), rpoPath.getId()))
return defaultValue;
} catch (Throwable e) {
Respackopts.LOGGER.error("Could not check file filter status", e);
RpoModInfo.LOGGER.error("Could not check file filter status", e);
return defaultValue;
}
try (InputStream stream = pack.open(rpoPath.getType(), rpoPath.getId()); Reader w = new InputStreamReader(stream)) {
return getModified.getModified(Respackopts.GSON.fromJson(w, FileRpo.class));
return getModified.getModified(RpoModInfo.GSON.fromJson(w, FileRpo.class));
}
catch (Exception e) {
Respackopts.LOGGER.error("Could not generate replacement for " + rpoPath.getName() + " in " + pack.getName(), e);
RpoModInfo.LOGGER.error("Could not generate replacement for " + rpoPath.getName() + " in " + pack.getName(), e);
return defaultValue;
}
}

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.respackopts.gson;
import com.google.gson.*;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.data.entry.ConfigEnumEntry;
import java.lang.reflect.Type;
@ -38,7 +38,7 @@ public class EnumEntrySerializer implements JsonSerializer<ConfigEnumEntry>, Jso
throw new JsonSyntaxException("Expected string entry in enum");
}
if (result.values.isEmpty())
Respackopts.LOGGER.warn("Enum entry empty");
RpoModInfo.LOGGER.warn("Enum entry empty");
else
result.setDefault(result.values.get(0));
return result;

View File

@ -4,7 +4,7 @@ import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import meteordevelopment.starscript.Script;
import meteordevelopment.starscript.compiler.Compiler;
import meteordevelopment.starscript.compiler.Parser;
@ -26,7 +26,7 @@ public class ScriptDeserializer implements JsonDeserializer<Script> {
Parser.Result result = Parser.parse(s);
if (result.hasErrors()) {
for (Error error : result.errors) {
Respackopts.LOGGER.error(error);
RpoModInfo.LOGGER.error(error);
}
throw new JsonParseException("Could not parse script: See errors above");
}

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.respackopts.integration;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import net.fabricmc.loader.api.FabricLoader;
import java.io.IOException;
@ -14,9 +14,12 @@ public class DashLoaderCompat {
public static final boolean modPresent = FabricLoader.getInstance().isModLoaded("dashloader");
private static boolean forceReload = false;
// Called from ASM injected through mixin/dashloader/Plugin
// Called from ASM injected through mixin/AsmPlugin
@SuppressWarnings("unused")
public static void injection() {
if (forceReload) {
if (RpoModInfo.CONFIG.debugLogs)
RpoModInfo.LOGGER.info("Attempting to force a dashloader reload by removing its data directory");
try {
Class<?> loaderClass = Class.forName("net.oskarstrom.dashloader.DashLoader");
Object loaderInstance = loaderClass.getDeclaredMethod("getInstance").invoke(null);
@ -35,7 +38,7 @@ public class DashLoaderCompat {
}
});
} catch (Throwable e) {
Respackopts.LOGGER.error("Failed to remove dashloader data", e);
RpoModInfo.LOGGER.error("Failed to remove dashloader data", e);
}
}
forceReload = false;

View File

@ -3,6 +3,7 @@ package io.gitlab.jfronny.respackopts.integration;
import grondag.frex.FrexInitializer;
import grondag.frex.api.config.ShaderConfig;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.data.entry.ConfigBranch;
import net.minecraft.util.Identifier;
@ -12,8 +13,8 @@ public class FrexCompat implements FrexInitializer {
boolean initial = true;
@Override
public void onInitalizeFrex() {
ShaderConfig.registerShaderConfigSupplier(new Identifier(Respackopts.ID, "config_supplier"), FrexCompat::generateShader);
Respackopts.LOGGER.info("enabled frex/canvas support");
ShaderConfig.registerShaderConfigSupplier(new Identifier(RpoModInfo.ID, "config_supplier"), FrexCompat::generateShader);
RpoModInfo.LOGGER.info("enabled frex/canvas support");
Respackopts.SAVE_ACTIONS.add(() -> {
try {
if (!initial)
@ -21,12 +22,14 @@ public class FrexCompat implements FrexInitializer {
initial = false;
}
catch (Throwable e) {
Respackopts.LOGGER.error("Could not reload shader config", e);
RpoModInfo.LOGGER.error("Could not reload shader config", e);
}
});
}
public static String generateShader() {
if (RpoModInfo.CONFIG.debugLogs)
RpoModInfo.LOGGER.info("Generating FREX shader code");
StringBuilder sb = new StringBuilder();
sb.append("#define respackopts_loaded");
for (Map.Entry<String, ConfigBranch> e : Respackopts.CONFIG_BRANCH.entrySet()) {

View File

@ -3,14 +3,14 @@ package io.gitlab.jfronny.respackopts.integration;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.data.ConfigFile;
import me.shedaniel.clothconfig2.api.ConfigBuilder;
import me.shedaniel.clothconfig2.api.ConfigCategory;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import net.minecraft.client.gui.screen.FatalErrorScreen;
import net.minecraft.text.TranslatableText;
import java.util.concurrent.atomic.AtomicBoolean;
public class ModMenuCompat implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
@ -22,20 +22,38 @@ public class ModMenuCompat implements ModMenuApi {
.setTitle(new TranslatableText("respackopts.mainconfig"));
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
builder.setSavingRunnable(() -> {
RpoModInfo.CONFIG.save();
Respackopts.save();
DashLoaderCompat.requestForceReload();
Respackopts.forceReloadResources();
});
AtomicBoolean categoryAdded = new AtomicBoolean(false);
//Respackopts config screen
ConfigFile defaultConfig = new ConfigFile();
ConfigCategory mainConfig = builder.getOrCreateCategory(new TranslatableText("respackopts.mainconfig"));
mainConfig.addEntry(
entryBuilder.startBooleanToggle(new TranslatableText("respackopts.mainconfig.debugCommands"), RpoModInfo.CONFIG.debugCommands)
.setDefaultValue(defaultConfig.debugCommands)
.setSaveConsumer(b -> RpoModInfo.CONFIG.debugCommands = b)
.build()
);
mainConfig.addEntry(
entryBuilder.startBooleanToggle(new TranslatableText("respackopts.mainconfig.debugLogs"), RpoModInfo.CONFIG.debugLogs)
.setDefaultValue(defaultConfig.debugLogs)
.setSaveConsumer(b -> RpoModInfo.CONFIG.debugLogs = b)
.build()
);
mainConfig.addEntry(
entryBuilder.startBooleanToggle(new TranslatableText("respackopts.mainconfig.dashloaderCompat"), RpoModInfo.CONFIG.dashloaderCompat)
.requireRestart()
.setDefaultValue(defaultConfig.dashloaderCompat)
.setSaveConsumer(b -> RpoModInfo.CONFIG.dashloaderCompat = b)
.build()
);
//Pack config screens
Respackopts.CONFIG_BRANCH.forEach((id, conf) -> {
categoryAdded.set(true);
ConfigCategory config = builder.getOrCreateCategory(new TranslatableText("respackopts.title." + id));
ConfigCategory config = builder.getOrCreateCategory(new TranslatableText((Respackopts.PACK_METAS.get(id).version >= 5 ? "rpo." : "respackopts.title.") + id));
Respackopts.factory.buildCategory(conf, id, config::addEntry, entryBuilder, "");
});
if (!categoryAdded.get()) {
builder.getOrCreateCategory(new TranslatableText("respackopts.mainconfig"))
.addEntry(entryBuilder.startTextDescription(new TranslatableText("respackopts.noPack")).build());
}
return builder.build();
}
catch (Throwable t) {

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.respackopts.mixin;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.integration.DashLoaderCompat;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
@ -22,7 +22,8 @@ import java.util.Set;
public class AsmPlugin implements IMixinConfigPlugin {
@Override
public void onLoad(String mixinPackage) {
if (DashLoaderCompat.modPresent) {
if (RpoModInfo.CONFIG.dashloaderCompat && DashLoaderCompat.modPresent) {
RpoModInfo.LOGGER.info("Injecting RPO into the mixin pipeline in order to facilitate dashloader integration. If respackopts is mentioned, try disabling this via the config before reporting (\"debugLogs\")");
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?> classLoaderClass = classLoader.getClass();
@ -98,7 +99,7 @@ public class AsmPlugin implements IMixinConfigPlugin {
found = true;
}
}
if (!found) Respackopts.LOGGER.error("Could not hack into dashloader");
if (!found) RpoModInfo.LOGGER.error("Could not hack into dashloader");
ClassWriter writer = new MixinClassWriter(reader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
klass.accept(writer);

View File

@ -1,6 +1,7 @@
package io.gitlab.jfronny.respackopts.mixin;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.client.option.GameOptions;
import net.minecraft.resource.ResourcePackManager;
@ -19,6 +20,8 @@ public class OptionsScreenMixin {
private void refreshResourcePacks(ResourcePackManager resourcePackManager, CallbackInfo info) {
if (Respackopts.forcePackReload) {
Respackopts.forcePackReload = false;
if (RpoModInfo.CONFIG.debugLogs)
RpoModInfo.LOGGER.info("Clearing loaded resource packs to enable a proper resource reload");
this.settings.resourcePacks.clear();
}
}

View File

@ -1,6 +1,7 @@
package io.gitlab.jfronny.respackopts.mixin;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.util.MetadataLocateResult;
import io.gitlab.jfronny.respackopts.data.PackCapability;
import io.gitlab.jfronny.respackopts.data.PackMeta;
@ -30,13 +31,15 @@ public class ResourcePackManagerMixin {
MetadataLocateResult scan = rpo$locateMetadata(v);
if (scan.hasMeta()) {
try (InputStream is = scan.pack().open(scan.type(), Respackopts.CONF_ID); InputStreamReader isr = new InputStreamReader(is)) {
PackMeta conf = Respackopts.GSON.fromJson(isr, PackMeta.class);
if (Respackopts.META_VERSION < conf.version) {
Respackopts.LOGGER.error(s + " was not loaded as it specifies a newer respackopts version than is installed");
PackMeta conf = RpoModInfo.GSON.fromJson(isr, PackMeta.class);
if (RpoModInfo.CONFIG.debugLogs)
RpoModInfo.LOGGER.info("Discovered pack: " + conf.id);
if (RpoModInfo.META_VERSION < conf.version) {
RpoModInfo.LOGGER.error(s + " was not loaded as it specifies a newer respackopts version than is installed");
return;
}
if (Respackopts.META_VERSION > conf.version) {
Respackopts.LOGGER.warn(s + " uses an outdated RPO format (" + conf.version + "). Although this is supported, using the latest version (" + Respackopts.META_VERSION + ") is recommended");
if (RpoModInfo.META_VERSION > conf.version) {
RpoModInfo.LOGGER.warn(s + " uses an outdated RPO format (" + conf.version + "). Although this is supported, using the latest version (" + RpoModInfo.META_VERSION + ") is recommended");
}
conf.conf.setVersion(conf.version);
if (conf.version < 5)
@ -50,7 +53,7 @@ public class ResourcePackManagerMixin {
Respackopts.PACK_METAS.put(conf.id, conf);
Respackopts.load(conf.id);
} catch (Throwable e) {
Respackopts.LOGGER.error("Could not initialize pack meta for " + s, e);
RpoModInfo.LOGGER.error("Could not initialize pack meta for " + s, e);
}
}
});

View File

@ -1,6 +1,7 @@
package io.gitlab.jfronny.respackopts.util;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RpoModInfo;
import io.gitlab.jfronny.respackopts.data.entry.ConfigBranch;
import io.gitlab.jfronny.respackopts.integration.FrexCompat;
import net.fabricmc.loader.api.FabricLoader;
@ -17,7 +18,7 @@ import java.util.Map;
import static net.fabricmc.fabric.api.client.command.v1.ClientCommandManager.*;
public class RpoCommand {
private static final ModContainer respackotps = FabricLoader.getInstance().getModContainer(Respackopts.ID).get();
private static final ModContainer respackotps = FabricLoader.getInstance().getModContainer(RpoModInfo.ID).get();
public static void register() {
DISPATCHER.register(literal("rpo").then(literal("dump").then(literal("frex").executes(ctx -> {
ctx.getSource().sendFeedback(dump(FrexCompat.generateShader(), "frex.frag"));
@ -36,11 +37,11 @@ public class RpoCommand {
return 1;
})));
DISPATCHER.register(literal("rpo").then(literal("version").executes(ctx -> {
ctx.getSource().sendFeedback(new TranslatableText("respackopts.versionText", respackotps.getMetadata().getVersion(), Respackopts.META_VERSION));
ctx.getSource().sendFeedback(new TranslatableText("respackopts.versionText", respackotps.getMetadata().getVersion(), RpoModInfo.META_VERSION));
return 1;
})));
DISPATCHER.register(literal("rpo").executes(ctx -> {
ctx.getSource().sendFeedback(new TranslatableText("respackopts.versionText", respackotps.getMetadata().getVersion(), Respackopts.META_VERSION));
ctx.getSource().sendFeedback(new TranslatableText("respackopts.versionText", respackotps.getMetadata().getVersion(), RpoModInfo.META_VERSION));
return 1;
}));
}

View File

@ -3,8 +3,10 @@
"respackopts.loadError": "There is an issue with the resource pack configs. Please take a look at the game log",
"respackopts.configure": "Configure",
"respackopts.mainconfig": "ResPackOpts",
"respackopts.mainconfig.debugCommands": "Debug Commands",
"respackopts.mainconfig.debugLogs": "Debug Logs",
"respackopts.mainconfig.dashloaderCompat": "Dashloader compatibility",
"respackopts.invalid": "Invalid value",
"respackopts.noPack": "No resource pack that supports RPO could be found. Install one and it will appear here",
"respackopts.dumpFailed": "Could not dump the requested resource, look at your log for details",
"respackopts.dumpSucceeded": "Successfully dumped the resource to %s",
"respackopts.versionText": "Version %s using the respackotps meta version %s"

View File

@ -3,6 +3,5 @@
"respackopts.loadError": "Wystąpił problem z konfiguracją paczki zasobów. Sprawdź logi gry",
"respackopts.configure": "Konfiguruj",
"respackopts.mainconfig": "ResPackOpts",
"respackopts.invalid": "Nieprawidłowa wartość",
"respackopts.noPack": "Nie znaleziono żadnej paczki zasobów wspierającej RPO. Zainstaluj jakąś, to pojawi się tutaj"
"respackopts.invalid": "Nieprawidłowa wartość"
}

View File

@ -10,6 +10,7 @@ import java.nio.file.Files;
import java.nio.file.Paths;
import static io.gitlab.jfronny.respackopts.Respackopts.*;
import static io.gitlab.jfronny.respackopts.RpoModInfo.*;
import static io.gitlab.jfronny.respackopts.Respackopts.CONFIG_BRANCH;
import static org.junit.jupiter.api.Assertions.*;