package io.gitlab.jfronny.respackopts; import io.gitlab.jfronny.gson.*; import io.gitlab.jfronny.muscript.compiler.expr.*; import io.gitlab.jfronny.respackopts.filters.*; import io.gitlab.jfronny.respackopts.gson.*; import io.gitlab.jfronny.respackopts.gson.entry.*; import io.gitlab.jfronny.respackopts.integration.*; import io.gitlab.jfronny.respackopts.model.*; import io.gitlab.jfronny.respackopts.model.tree.*; import io.gitlab.jfronny.respackopts.util.*; import net.fabricmc.api.*; import net.fabricmc.loader.api.*; import net.minecraft.client.*; import net.minecraft.server.integrated.*; import net.minecraft.util.*; import org.slf4j.*; import java.io.*; import java.nio.file.*; import java.util.*; import java.util.concurrent.*; @Environment(EnvType.CLIENT) public class Respackopts implements ClientModInitializer { public static final Integer META_VERSION = 8; public static final String FILE_EXTENSION = ".rpo"; public static final Gson GSON; public static final String ID = "respackopts"; public static final Logger LOGGER = LoggerFactory.getLogger(ID); public static final Identifier CONF_ID = new Identifier(ID, "conf.json"); public static final Set SAVE_ACTIONS = new HashSet<>(); public static final GuiFactory GUI_FACTORY = new GuiFactory(); public static boolean forcePackReload = false; public static Path FALLBACK_CONF_DIR; public static ConfigFile CONFIG; public static final Identifier RPO_SHADER_ID = new Identifier(Respackopts.ID, "config_supplier"); private static String shaderImportSource; 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(Expr.class, new ExprDeserializer()) .registerTypeAdapter(StringExpr.class, new StringExprDeserializer()) .registerTypeAdapter(BoolExpr.class, new BoolExprDeserializer()) .registerTypeAdapter(Condition.class, new ConditionDeserializer()) .setLenient() .setPrettyPrinting() .create(); try { FALLBACK_CONF_DIR = FabricLoader.getInstance().getConfigDir().resolve(ID); CONFIG = ConfigFile.load(); } catch (Throwable e) { LOGGER.error("Could not resolve config directory", e); } } @Override public void onInitializeClient() { try { Files.createDirectories(FALLBACK_CONF_DIR); } catch (IOException e) { LOGGER.error("Could not initialize config directory", e); } if (CONFIG.debugLogs) SAVE_ACTIONS.add(() -> LOGGER.info("Save")); SAVE_ACTIONS.add(() -> { if (CONFIG.debugLogs) LOGGER.info("Generating shader code"); StringBuilder sb = new StringBuilder(); sb.append("#ifndef respackopts_loaded"); sb.append("\n#define respackopts_loaded"); MetaCache.forEach((key, state) -> state.configBranch().buildShader(sb, sanitizeString(state.packId()))); sb.append("\n#endif"); shaderImportSource = sb.toString(); }); DirFilterEventImpl.init(); FileFilterEventImpl.init(); if (CONFIG.debugCommands) RpoCommand.register(); if (FabricLoader.getInstance().isModLoaded("frex")) { FrexCompat.onInitializeFrex(); } } 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 forceReloadResources() { if (CONFIG.debugLogs) LOGGER.info("Forcing resource reload"); return CompletableFuture.allOf(MinecraftClient.getInstance().reloadResources(), reloadData()); } public static CompletableFuture reloadData() { IntegratedServer is = MinecraftClient.getInstance().getServer(); if (is != null) { is.getDataPackManager().scanPacks(); return is.reloadResources(is.getDataPackManager().getEnabledNames()); } return CompletableFuture.completedFuture(null); } public static String getShaderImportSource() { if (shaderImportSource == null) { Respackopts.LOGGER.error("Shader import source is null"); return ""; } return shaderImportSource; } }