From 25739e28a5c6d82ae8db39bb0e7f16e932b757e2 Mon Sep 17 00:00:00 2001 From: JFronny Date: Thu, 8 Dec 2022 19:00:41 +0100 Subject: [PATCH] Update to 1.19.3 --- build.gradle.kts | 2 +- docs/filerpo/MultipleFileSelection.md | 2 +- docs/filerpo/ToggleFilesWithFallback.md | 7 +- gradle.properties | 8 +- .../jfronny/respackopts/Respackopts.java | 11 +- .../respackopts/filters/DebugEvents.java | 45 ++++++ .../filters/DirFilterEventImpl.java | 140 ------------------ .../respackopts/filters/DirFilterEvents.java | 124 ++++++++++++++++ .../filters/FileFilterEventImpl.java | 109 -------------- .../respackopts/filters/FileFilterEvents.java | 89 +++++++++++ .../filters/util/FileExpansionProvider.java | 15 +- .../filters/util/FileFallbackProvider.java | 30 ++-- .../filters/util/FileRpoSearchProvider.java | 49 +++--- .../AbstractFileResourcePackAccessor.java | 13 -- .../mixin/DirectoryResourcePackAccessor.java | 13 ++ .../mixin/FileResourcePackProviderMixin.java | 20 +++ .../mixin/ResourcePackManagerMixin.java | 52 +++---- .../mixin/ZipResourcePackAccessor.java | 13 ++ .../server/ServerInstanceHolder.java | 2 +- src/main/resources/fabric.mod.json | 5 - src/main/resources/respackopts.mixins.json | 6 +- 21 files changed, 393 insertions(+), 362 deletions(-) create mode 100644 src/main/java/io/gitlab/jfronny/respackopts/filters/DebugEvents.java delete mode 100644 src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterEventImpl.java create mode 100644 src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterEvents.java delete mode 100644 src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterEventImpl.java create mode 100644 src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterEvents.java delete mode 100644 src/main/java/io/gitlab/jfronny/respackopts/mixin/AbstractFileResourcePackAccessor.java create mode 100644 src/main/java/io/gitlab/jfronny/respackopts/mixin/DirectoryResourcePackAccessor.java create mode 100644 src/main/java/io/gitlab/jfronny/respackopts/mixin/FileResourcePackProviderMixin.java create mode 100644 src/main/java/io/gitlab/jfronny/respackopts/mixin/ZipResourcePackAccessor.java diff --git a/build.gradle.kts b/build.gradle.kts index 00af584..8acb083 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,7 +26,7 @@ dependencies { modClientCompileOnly("io.vram:frex-fabric-mc119:+") modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil:${prop("libjf_version")}") - modLocalRuntime("com.terraformersmc:modmenu:4.1.1") + modLocalRuntime("com.terraformersmc:modmenu:5.0.0-alpha.4") testImplementation("org.junit.jupiter:junit-jupiter:5.9.0") diff --git a/docs/filerpo/MultipleFileSelection.md b/docs/filerpo/MultipleFileSelection.md index a712fe3..082f73e 100644 --- a/docs/filerpo/MultipleFileSelection.md +++ b/docs/filerpo/MultipleFileSelection.md @@ -13,7 +13,7 @@ You will need to navigate to the file you would like to toggle inside your resou `some_recipe.json` would be `some_recipe.json.rpo`
### `.rpo` explanation : -You need a `.rpo` file per texture (except for the last one in your list) if you have 3 files to select beteen then you will need 2 `.rpo` files, +You need a `.rpo` file per texture (except for the last one in your list) if you have 3 files to select between then you will need 2 `.rpo` files, if you have 4 files to select between then you will need 3 `.rpo` files and so on etc... ### Layout: diff --git a/docs/filerpo/ToggleFilesWithFallback.md b/docs/filerpo/ToggleFilesWithFallback.md index 7dbb34f..48e189f 100644 --- a/docs/filerpo/ToggleFilesWithFallback.md +++ b/docs/filerpo/ToggleFilesWithFallback.md @@ -1,6 +1,6 @@ # Switch between two files -This is a simple `IF` statement simply returning true/false to if the texture/file should be loaded into the pack. -(Pick one file over another). +Imagine a simple `IF` statement controlling whether the texture/file should be loaded into the pack. +That is exactly what this page is about. You will need the `Pack ID` and `Entry Name` from your `respackopts.json5` that you created earlier if you have not, see [Main Config](../setup/MainConfig.md) on how to do so.
@@ -28,6 +28,9 @@ You will need to navigate to the file you would like to toggle inside your resou } ``` +Please be aware that Minecraft restricts file and path names. +You MUST follow these! If you don't (for example by using uppercase letters or symbols), your pack WILL NOT WORK! + ## Another way to do this: Respackopts supports specifying multiple possible fallbacks when configuring single files. You can use this functionality as follows: diff --git a/gradle.properties b/gradle.properties index e5b830a..db453d1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # https://fabricmc.net/develop/ -minecraft_version=1.19.2 -yarn_mappings=build.28 +minecraft_version=1.19.3 +yarn_mappings=build.2 loader_version=0.14.11 maven_group=io.gitlab.jfronny @@ -13,6 +13,6 @@ curseforge_id=430090 curseforge_required_dependencies=fabric-api, libjf curseforge_optional_dependencies=modmenu -fabric_version=0.68.0+1.19.2 -libjf_version=3.2.1 +fabric_version=0.68.1+1.19.3 +libjf_version=3.3.1 muscript_version=1.0-SNAPSHOT diff --git a/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java b/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java index 95edcfd..d6d31a6 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java @@ -5,8 +5,7 @@ import io.gitlab.jfronny.gson.Gson; import io.gitlab.jfronny.gson.GsonBuilder; import io.gitlab.jfronny.libjf.config.api.v1.ConfigHolder; import io.gitlab.jfronny.muscript.compiler.expr.*; -import io.gitlab.jfronny.respackopts.filters.DirFilterEventImpl; -import io.gitlab.jfronny.respackopts.filters.FileFilterEventImpl; +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.SaveHook; @@ -16,6 +15,8 @@ import io.gitlab.jfronny.respackopts.server.ServerInstanceHolder; import net.fabricmc.api.EnvType; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.resource.InputSupplier; +import net.minecraft.util.Util; import java.io.IOException; import java.nio.file.Files; @@ -41,7 +42,7 @@ public class Respackopts implements ModInitializer, SaveHook { public static final String ID = "respackopts"; public static final Logger LOGGER = Logger.forName(ID); - public static Path FALLBACK_CONF_DIR = FabricLoader.getInstance().getConfigDir().resolve(ID); + public static final Path FALLBACK_CONF_DIR = FabricLoader.getInstance().getConfigDir().resolve(ID); @Override public void onInitialize() { @@ -50,8 +51,8 @@ public class Respackopts implements ModInitializer, SaveHook { } catch (IOException e) { LOGGER.error("Could not initialize config directory", e); } - DirFilterEventImpl.init(); - FileFilterEventImpl.init(); + DirFilterEvents.init(); + FileFilterEvents.init(); ServerInstanceHolder.init(); } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/DebugEvents.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/DebugEvents.java new file mode 100644 index 0000000..662cecc --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/respackopts/filters/DebugEvents.java @@ -0,0 +1,45 @@ +package io.gitlab.jfronny.respackopts.filters; + +import io.gitlab.jfronny.libjf.data.manipulation.api.UserResourceEvents; +import io.gitlab.jfronny.respackopts.Respackopts; +import net.minecraft.resource.*; +import net.minecraft.resource.metadata.ResourceMetadataReader; +import net.minecraft.util.Identifier; + +import java.io.InputStream; +import java.util.function.Supplier; + +public enum DebugEvents implements UserResourceEvents.FindResource, UserResourceEvents.ParseMetadata, UserResourceEvents.Open, UserResourceEvents.OpenRoot { + INSTANCE; + + public static void init() { + UserResourceEvents.FIND_RESOURCE.register(INSTANCE); + UserResourceEvents.PARSE_METADATA.register(INSTANCE); + UserResourceEvents.OPEN.register(INSTANCE); + UserResourceEvents.OPEN_ROOT.register(INSTANCE); + } + + @Override + public ResourcePack.ResultConsumer findResources(ResourceType type, String namespace, String prefix, ResourcePack.ResultConsumer previous, ResourcePack pack) { + Respackopts.LOGGER.info("FIND_RESOURCE " + type + " in " + namespace + " " + prefix + " of " + pack.getName()); + return previous; + } + + @Override + public InputSupplier open(ResourceType type, Identifier id, InputSupplier previous, ResourcePack pack) { + Respackopts.LOGGER.info("OPEN " + type + " at " + id + " of " + pack.getName()); + return previous; + } + + @Override + public InputSupplier openRoot(String[] fileName, InputSupplier previous, ResourcePack pack) { + Respackopts.LOGGER.info("OPEN_ROOT " + String.join("/", fileName) + " of " + pack.getName()); + return previous; + } + + @Override + public T parseMetadata(ResourceMetadataReader reader, Supplier previous, ResourcePack pack) { + Respackopts.LOGGER.info("PARSE_METADATA " + reader.getKey() + " of " + pack.getName()); + return previous.get(); + } +} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterEventImpl.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterEventImpl.java deleted file mode 100644 index 93305ba..0000000 --- a/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterEventImpl.java +++ /dev/null @@ -1,140 +0,0 @@ -package io.gitlab.jfronny.respackopts.filters; - -import io.gitlab.jfronny.libjf.*; -import io.gitlab.jfronny.libjf.data.manipulation.api.*; -import io.gitlab.jfronny.muscript.debug.*; -import io.gitlab.jfronny.respackopts.*; -import io.gitlab.jfronny.respackopts.gson.*; -import io.gitlab.jfronny.respackopts.model.*; -import io.gitlab.jfronny.respackopts.model.cache.*; -import io.gitlab.jfronny.respackopts.model.enums.*; -import io.gitlab.jfronny.respackopts.util.*; -import net.minecraft.resource.*; -import net.minecraft.util.*; - -import java.io.*; -import java.util.*; - -public class DirFilterEventImpl { - public static void init() { - UserResourceEvents.OPEN.register((type, id, previous, pack) -> { - if (!MetaCache.hasCapability(pack, PackCapability.DirFilter)) - return previous.get(); - String path = new ResourcePath(type, id).getName(); - DirRpo rpo = findDirRpo(pack, path); - if (rpo != null && dirHidden(rpo, MetaCache.getKeyByPack(pack), path)) { - path = findReplacementDir(path, rpo); - if (path == null) throw new FileNotFoundException(); - ResourcePath rp = new ResourcePath(path); - return pack.open(rp.getType(), rp.getId()); - } - return previous.get(); - }); - UserResourceEvents.FIND_RESOURCE.register((type, namespace, prefix, allowedPathPredicate, previous, pack) -> { - // Warning: the Identifiers here DON'T CONTAIN THE TYPE! - // Therefore, it needs to be added when calling a method that generates a ResourcePath! - Collection prevVals = previous.get(); - if (!MetaCache.hasCapability(pack, PackCapability.DirFilter)) - return prevVals; - Collection nextRes = new LinkedHashSet<>(prevVals); - boolean dirFilterAdditive = MetaCache.hasCapability(pack, PackCapability.DirFilterAdditive); - for (Identifier identifier : prevVals) { - String path = type.getDirectory() + "/" + identifier.getNamespace() + "/" + identifier.getPath(); - DirRpo rpo = findDirRpo(pack, path); - if (rpo != null) { - if (dirHidden(rpo, MetaCache.getKeyByPack(pack), path)) { - path = findReplacementDir(path, rpo); - if (path == null) - nextRes.remove(identifier); - else if (dirFilterAdditive) { - String[] s = path.split("/", 3); - if (s.length == 3) { - ResourcePath rp = new ResourcePath(path); - //TODO improve this impl (used for files that aren't at the original location - for (Identifier resource : pack.findResources(rp.getType(), rp.getId().getNamespace(), rp.getId().getPath(), (a) -> true)) { - String p = type.getDirectory() + "/" + resource.getNamespace() + "/" + resource.getPath(); - p = p.replace(rpo.fallback, rpo.path + "/"); - rp = new ResourcePath(p); - if (allowedPathPredicate.test(rp.getId())) - nextRes.add(rp.getId()); - } - } - } - } - } - } - return nextRes; - }); - UserResourceEvents.CONTAINS.register((type, id, previous, pack) -> { - if (!MetaCache.hasCapability(pack, PackCapability.DirFilter)) - return previous.get(); - String path = new ResourcePath(type, id).getName(); - DirRpo rpo = findDirRpo(pack, path); - if (rpo != null && dirHidden(rpo, MetaCache.getKeyByPack(pack), path)) { - path = findReplacementDir(path, rpo); - if (path == null) - return false; - ResourcePath rp = new ResourcePath(path); - return pack.contains(rp.getType(), rp.getId()); - } - return previous.get(); - }); - } - - private static String findReplacementDir(String dir, DirRpo rpo) { - if (rpo.fallback == null) return null; - return dir.replace(rpo.path + "/", rpo.fallback); - } - - private static boolean dirHidden(DirRpo rpo, CacheKey key, String file) { - if (rpo.condition == null) - return false; - try { - return !rpo.condition.get(MetaCache.getParameter(key)); - } catch (Condition.ConditionException e) { - String res = "Could not evaluate condition " + file + " (pack: " + key.packName() + ")"; - try { - Respackopts.LOGGER.error(res + " with condition:\n" + ObjectGraphPrinter.printGraph(rpo.condition) + ")", e); - } catch (Throwable ex) { - Respackopts.LOGGER.error(res, e); - } - } - return false; - } - - private static DirRpo findDirRpo(ResourcePack pack, String name) { - CachedPackState state = MetaCache.getState(MetaCache.getKeyByPack(pack)); - Map drpReg = state.cachedDirRPOs(); - int li = name.lastIndexOf('/'); - if (li <= 0) - return null; - name = name.substring(0, li); - if (drpReg.containsKey(name)) return drpReg.get(name); - DirRpo drp = findDirRpo(pack, name); - if (drp != null) { - drpReg.put(name, drp); - return drp; - } - ResourcePath rp; - try { - rp = new ResourcePath(name + "/" + Respackopts.FILE_EXTENSION); - } - catch (Exception e) { - return null; - } - if (UserResourceEvents.disable(() -> pack.contains(rp.getType(), rp.getId()))) { - try (InputStream stream = UserResourceEvents.disable(() -> pack.open(rp.getType(), rp.getId())); - Reader w = new InputStreamReader(stream)) { - drp = AttachmentHolder.deserialize(state.metadata().version, w, DirRpo.class); - drp.path = name; - if (drp.fallback != null && !drp.fallback.endsWith("/")) - drp.fallback += "/"; - drpReg.put(name, drp); - return drp; - } catch (IOException e) { - Respackopts.LOGGER.error("Couldn't open dir rpo " + rp.getName(), e); - } - } - return null; - } -} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterEvents.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterEvents.java new file mode 100644 index 0000000..9fbb775 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterEvents.java @@ -0,0 +1,124 @@ +package io.gitlab.jfronny.respackopts.filters; + +import io.gitlab.jfronny.libjf.ResourcePath; +import io.gitlab.jfronny.libjf.data.manipulation.api.UserResourceEvents; +import io.gitlab.jfronny.muscript.debug.ObjectGraphPrinter; +import io.gitlab.jfronny.respackopts.Respackopts; +import io.gitlab.jfronny.respackopts.gson.AttachmentHolder; +import io.gitlab.jfronny.respackopts.model.Condition; +import io.gitlab.jfronny.respackopts.model.DirRpo; +import io.gitlab.jfronny.respackopts.model.cache.CacheKey; +import io.gitlab.jfronny.respackopts.model.cache.CachedPackState; +import io.gitlab.jfronny.respackopts.model.enums.PackCapability; +import io.gitlab.jfronny.respackopts.util.MetaCache; +import net.minecraft.resource.*; +import net.minecraft.util.Identifier; + +import java.io.*; +import java.util.Map; + +public enum DirFilterEvents implements UserResourceEvents.Open, UserResourceEvents.FindResource { + INSTANCE; + + public static void init() { + UserResourceEvents.OPEN.register(INSTANCE); + UserResourceEvents.FIND_RESOURCE.register(INSTANCE); + } + + @Override + public InputSupplier open(ResourceType type, Identifier id, InputSupplier previous, ResourcePack pack) { + if (!MetaCache.hasCapability(pack, PackCapability.DirFilter)) return previous; + String path = new ResourcePath(type, id).getName(); + DirRpo rpo = findDirRpo(pack, path); + if (rpo != null && dirHidden(rpo, MetaCache.getKeyByPack(pack), path)) { + path = findReplacementDir(path, rpo); + if (path == null) return null; + ResourcePath rp = new ResourcePath(path); + return pack.open(rp.getType(), rp.getId()); + } + return previous; + } + + @Override + public ResourcePack.ResultConsumer findResources(ResourceType type, String namespace, String prefix, ResourcePack.ResultConsumer previous, ResourcePack pack) { + // Warning: the Identifiers here DON'T CONTAIN THE TYPE! + // Therefore, it needs to be added when calling a method that generates a ResourcePath! + if (!MetaCache.hasCapability(pack, PackCapability.DirFilter)) return previous; + boolean dirFilterAdditive = MetaCache.hasCapability(pack, PackCapability.DirFilterAdditive); + return (identifier, value) -> { + String path = type.getDirectory() + "/" + identifier.getNamespace() + "/" + identifier.getPath(); + DirRpo rpo = findDirRpo(pack, path); + if (rpo != null && dirHidden(rpo, MetaCache.getKeyByPack(pack), path)) { + path = findReplacementDir(path, rpo); + if (path != null && dirFilterAdditive) { + String[] s = path.split("/", 3); + if (s.length == 3) { + ResourcePath rp = new ResourcePath(path); + //TODO improve this impl (used for files that aren't at the original location + pack.findResources(rp.getType(), rp.getId().getNamespace(), rp.getId().getPath(), (resource, resVal) -> { + String p = type.getDirectory() + "/" + resource.getNamespace() + "/" + resource.getPath(); + p = p.replace(rpo.fallback, rpo.path + "/"); + previous.accept(new ResourcePath(p).getId(), resVal); + }); + } + } + } else previous.accept(identifier, value); + }; + } + + private String findReplacementDir(String dir, DirRpo rpo) { + if (rpo.fallback == null) return null; + return dir.replace(rpo.path + "/", rpo.fallback); + } + + private boolean dirHidden(DirRpo rpo, CacheKey key, String file) { + if (rpo.condition == null) + return false; + try { + return !rpo.condition.get(MetaCache.getParameter(key)); + } catch (Condition.ConditionException e) { + String res = "Could not evaluate condition " + file + " (pack: " + key.packName() + ")"; + try { + Respackopts.LOGGER.error(res + " with condition:\n" + ObjectGraphPrinter.printGraph(rpo.condition) + ")", e); + } catch (Throwable ex) { + Respackopts.LOGGER.error(res, e); + } + } + return false; + } + + private DirRpo findDirRpo(ResourcePack pack, String name) { + CachedPackState state = MetaCache.getState(MetaCache.getKeyByPack(pack)); + Map drpReg = state.cachedDirRPOs(); + int li = name.lastIndexOf('/'); + if (li <= 0) + return null; + name = name.substring(0, li); + if (drpReg.containsKey(name)) return drpReg.get(name); + DirRpo drp = findDirRpo(pack, name); + if (drp != null) { + drpReg.put(name, drp); + return drp; + } + ResourcePath rp; + try { + rp = new ResourcePath(name + "/" + Respackopts.FILE_EXTENSION); + } + catch (Exception e) { + return null; + } + InputSupplier is = UserResourceEvents.disable(() -> pack.open(rp.getType(), rp.getId())); + if (is == null) return null; + try (Reader w = new InputStreamReader(is.get())) { + drp = AttachmentHolder.deserialize(state.metadata().version, w, DirRpo.class); + drp.path = name; + if (drp.fallback != null && !drp.fallback.endsWith("/")) + drp.fallback += "/"; + drpReg.put(name, drp); + return drp; + } catch (IOException e) { + Respackopts.LOGGER.error("Couldn't open dir rpo " + rp.getName(), e); + } + return null; + } +} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterEventImpl.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterEventImpl.java deleted file mode 100644 index 7970c02..0000000 --- a/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterEventImpl.java +++ /dev/null @@ -1,109 +0,0 @@ -package io.gitlab.jfronny.respackopts.filters; - -import io.gitlab.jfronny.libjf.ResourcePath; -import io.gitlab.jfronny.libjf.data.manipulation.api.UserResourceEvents; -import io.gitlab.jfronny.respackopts.Respackopts; -import io.gitlab.jfronny.respackopts.util.MetaCache; -import io.gitlab.jfronny.respackopts.model.enums.PackCapability; -import io.gitlab.jfronny.respackopts.filters.util.FileExclusionProvider; -import io.gitlab.jfronny.respackopts.filters.util.FileExpansionProvider; -import io.gitlab.jfronny.respackopts.filters.util.FileFallbackProvider; -import net.minecraft.resource.AbstractFileResourcePack; -import net.minecraft.resource.ResourcePack; -import net.minecraft.util.Identifier; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -public class FileFilterEventImpl { - private static final Map containsFileWasFallback = new HashMap<>(); - private static boolean containsFileWasFallback() { - boolean v = FileFilterEventImpl.containsFileWasFallback.getOrDefault(Thread.currentThread().getId(), false); - containsFileWasFallback(false); - return v; - } - - private static void containsFileWasFallback(boolean value) { - FileFilterEventImpl.containsFileWasFallback.put(Thread.currentThread().getId(), value); - } - - public static void init() { - UserResourceEvents.OPEN.register((type, id, previous, pack) -> { - if (skip(pack)) return previous.get(); - String name = new ResourcePath(type, id).getName(); - if (pack.contains(type, id)) { - return containsFileWasFallback() - ? FileFallbackProvider.getReplacement(pack, name) - : FileExpansionProvider.replace(previous.get(), pack, name); - } - else return null; - }); - UserResourceEvents.FIND_RESOURCE.register((type, namespace, prefix, allowedPathPredicate, previous, pack) -> { - // Warning: the Identifiers here DON'T CONTAIN THE TYPE! - // Therefore, it needs to be added when calling a method that generates a ResourcePath! - Collection prevVals = previous.get(); - if (skip(pack)) return prevVals; - prevVals.removeIf(s -> { - String fileName = type.getDirectory() + "/" + s.getNamespace() + "/" + s.getPath(); - return FileExclusionProvider.fileHidden(pack, fileName) && !FileFallbackProvider.fileHasFallback(pack, fileName); - }); - // Completion of the path is handled separately here - FileFallbackProvider.addFallbackResources(pack, prevVals, namespace, type); - return prevVals; - }); - UserResourceEvents.CONTAINS.register((type, id, previous, pack) -> { - if (skip(pack)) return previous.get(); - containsFileWasFallback(false); - return containsHook(previous.get(), pack, new ResourcePath(type, id).getName()); - }); - UserResourceEvents.OPEN_ROOT.register((fileName, previous, pack) -> { - if (skip(pack)) return previous.get(); - InputStream is = previous.get(); - if (containsHook(is != null, pack, fileName)) { - return containsFileWasFallback() - ? FileFallbackProvider.getReplacement(pack, fileName) - : FileExpansionProvider.replace(previous.get(), pack, fileName); - } - else return null; - }); - } - - private static boolean containsHook(boolean previous, ResourcePack pack, String name) { - if (previous) { - if (FileExclusionProvider.fileHidden(pack, name)) { - if (FileFallbackProvider.fileHasFallback(pack, name)) { - containsFileWasFallback(true); - } else { - return false; - } - } - return true; - } - else { - boolean hasRpo; - try { - hasRpo = UserResourceEvents.disable(() -> { - if (name.contains("/")) { - ResourcePath rp = new ResourcePath(name + Respackopts.FILE_EXTENSION); - return pack.contains(rp.getType(), rp.getId()); - } - return pack.openRoot(name + Respackopts.FILE_EXTENSION) != null; - }); - } catch (IOException e) { - hasRpo = false; - } - if (hasRpo && FileFallbackProvider.fileHasFallback(pack, name)) { - containsFileWasFallback(true); - return true; - } - return false; - } - } - - private static boolean skip(ResourcePack pack) { - return !(pack instanceof AbstractFileResourcePack) || !MetaCache.hasCapability(pack, PackCapability.FileFilter); - } -} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterEvents.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterEvents.java new file mode 100644 index 0000000..70f5f90 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterEvents.java @@ -0,0 +1,89 @@ +package io.gitlab.jfronny.respackopts.filters; + +import io.gitlab.jfronny.libjf.ResourcePath; +import io.gitlab.jfronny.libjf.data.manipulation.api.UserResourceEvents; +import io.gitlab.jfronny.respackopts.Respackopts; +import io.gitlab.jfronny.respackopts.util.MetaCache; +import io.gitlab.jfronny.respackopts.model.enums.PackCapability; +import io.gitlab.jfronny.respackopts.filters.util.FileExclusionProvider; +import io.gitlab.jfronny.respackopts.filters.util.FileExpansionProvider; +import io.gitlab.jfronny.respackopts.filters.util.FileFallbackProvider; +import net.minecraft.resource.*; +import net.minecraft.util.Identifier; + +import java.io.InputStream; +import java.util.*; + +public enum FileFilterEvents implements UserResourceEvents.OpenRoot, UserResourceEvents.Open, UserResourceEvents.FindResource { + INSTANCE; + + public static void init() { + UserResourceEvents.OPEN_ROOT.register(INSTANCE); + UserResourceEvents.OPEN.register(INSTANCE); + UserResourceEvents.FIND_RESOURCE.register(INSTANCE); + } + + @Override + public InputSupplier openRoot(String[] fileName, InputSupplier previous, ResourcePack pack) { + if (skip(pack)) return previous; + String path = String.join("/", fileName); + return switch (probe(previous != null, pack, path)) { + case MISSING -> null; + case FALLBACK -> FileFallbackProvider.getReplacement(pack, path); + case CONTAINS -> FileExpansionProvider.replace(previous, pack, path); + }; + } + + @Override + public InputSupplier open(ResourceType type, Identifier id, InputSupplier previous, ResourcePack pack) { + if (skip(pack)) return previous; + String name = new ResourcePath(type, id).getName(); + return switch (probe(previous != null, pack, name)) { + case MISSING -> null; + case FALLBACK -> FileFallbackProvider.getReplacement(pack, name); + case CONTAINS -> FileExpansionProvider.replace(previous, pack, name); + }; + } + + @Override + public ResourcePack.ResultConsumer findResources(ResourceType type, String namespace, String prefix, ResourcePack.ResultConsumer previous, ResourcePack pack) { + // Warning: the Identifiers here DON'T CONTAIN THE TYPE! + // Therefore, it needs to be added when calling a method that generates a ResourcePath! + if (skip(pack)) return previous; + Set ids = new HashSet<>(); + return (identifier, value) -> { + // Completion of the path is handled separately here + String fileName = type.getDirectory() + "/" + identifier.getNamespace() + "/" + identifier.getPath(); + if (!FileExclusionProvider.fileHidden(pack, fileName) || FileFallbackProvider.fileHasFallback(pack, fileName)) { + ids.add(identifier); + previous.accept(identifier, open(type, identifier, value, pack)); + } + FileFallbackProvider.addFallbackResources(namespace, type, identifier, pack, ids, previous); + }; + } + + private ContainsResult probe(boolean previous, ResourcePack pack, String name) { + if (previous) { + if (!FileExclusionProvider.fileHidden(pack, name)) return ContainsResult.CONTAINS; + else if (FileFallbackProvider.fileHasFallback(pack, name)) return ContainsResult.FALLBACK; + else return ContainsResult.MISSING; + } + else { + boolean missing; + if (name.contains("/")) { + ResourcePath rp = new ResourcePath(name + Respackopts.FILE_EXTENSION); + missing = UserResourceEvents.disable(() -> pack.open(rp.getType(), rp.getId())) == null; + } else missing = UserResourceEvents.disable(() -> pack.openRoot(name + Respackopts.FILE_EXTENSION)) == null; + if (missing && FileFallbackProvider.fileHasFallback(pack, name)) return ContainsResult.FALLBACK; + else return ContainsResult.MISSING; + } + } + + enum ContainsResult { + MISSING, CONTAINS, FALLBACK + } + + private boolean skip(ResourcePack pack) { + return !(pack instanceof AbstractFileResourcePack && MetaCache.hasCapability(pack, PackCapability.FileFilter)); + } +} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileExpansionProvider.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileExpansionProvider.java index db8791c..647f47b 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileExpansionProvider.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileExpansionProvider.java @@ -3,7 +3,9 @@ package io.gitlab.jfronny.respackopts.filters.util; import io.gitlab.jfronny.commons.data.dynamic.Dynamic; import io.gitlab.jfronny.muscript.compiler.expr.StringExpr; import io.gitlab.jfronny.respackopts.Respackopts; +import io.gitlab.jfronny.respackopts.RespackoptsConfig; import io.gitlab.jfronny.respackopts.util.MetaCache; +import net.minecraft.resource.InputSupplier; import net.minecraft.resource.ResourcePack; import java.io.*; @@ -18,15 +20,10 @@ public class FileExpansionProvider { return new ByteArrayInputStream(s.getBytes()); } - public static InputStream replace(InputStream inputStream, ResourcePack pack, String file) { - return FileRpoSearchProvider.modifyWithRpo(file, pack, rpo -> { - if (rpo.expansions == null || rpo.expansions.isEmpty()) - return inputStream; - try { - return replace(MetaCache.getParameter(MetaCache.getKeyByPack(pack)), inputStream, rpo.expansions); - } catch (IOException e) { - Respackopts.LOGGER.error("Could not perform file expansion on " + file, e); - return inputStream; + public static InputSupplier replace(InputSupplier inputStream, ResourcePack pack, String file) { + return FileRpoSearchProvider.modifyWithRpo(file, pack, rpo -> rpo.expansions == null || rpo.expansions.isEmpty() ? inputStream : () -> { + try (InputStream is = inputStream.get()) { + return replace(MetaCache.getParameter(MetaCache.getKeyByPack(pack)), is, rpo.expansions); } }, inputStream); } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileFallbackProvider.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileFallbackProvider.java index 6536484..d779c8c 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileFallbackProvider.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileFallbackProvider.java @@ -2,12 +2,11 @@ package io.gitlab.jfronny.respackopts.filters.util; import io.gitlab.jfronny.libjf.ResourcePath; import io.gitlab.jfronny.respackopts.Respackopts; -import net.minecraft.resource.ResourcePack; -import net.minecraft.resource.ResourceType; +import net.minecraft.resource.*; import net.minecraft.util.Identifier; import java.io.InputStream; -import java.util.Collection; +import java.util.Set; public class FileFallbackProvider { public static boolean fileHasFallback(ResourcePack pack, String file) { @@ -15,22 +14,21 @@ public class FileFallbackProvider { if (rpo.fallbacks != null) { for (String s : rpo.fallbacks) { ResourcePath tmp = new ResourcePath(s); - if (pack.contains(tmp.getType(), tmp.getId())) - return true; + if (pack.open(tmp.getType(), tmp.getId()) != null) return true; } } return false; }, false); } - public static InputStream getReplacement(ResourcePack pack, String file) { + public static InputSupplier getReplacement(ResourcePack pack, String file) { return FileRpoSearchProvider.modifyWithRpo(file, pack, rpo -> { try { if (rpo.fallbacks != null) { for (String s : rpo.fallbacks) { ResourcePath tmp = new ResourcePath(s); - if (pack.contains(tmp.getType(), tmp.getId())) - return pack.open(tmp.getType(), tmp.getId()); + InputSupplier is = pack.open(tmp.getType(), tmp.getId()); + if (is != null) return is; } } Respackopts.LOGGER.error("Could not determine replacement for " + file); @@ -42,15 +40,15 @@ public class FileFallbackProvider { }, null); } - public static void addFallbackResources(ResourcePack pack, Collection ret, String namespace, ResourceType type) { + public static void addFallbackResources(String namespace, ResourceType type, Identifier identifier, ResourcePack pack, Set ids, ResourcePack.ResultConsumer out) { // Warning: the Identifiers here DON'T CONTAIN THE TYPE! Therefore, it needs to be added when calling a method that generates a ResourcePath! - for (Identifier identifier : ret) { - String path = identifier.getPath(); - if (FileRpoSearchProvider.isRpo(path)) { - String expectedTarget = path.substring(0, path.length() - Respackopts.FILE_EXTENSION.length()); - if (ret.stream().noneMatch(s -> s.getPath().equals(expectedTarget)) && fileHasFallback(pack, type.getDirectory() + "/" + expectedTarget)) { - ret.add(new Identifier(namespace, expectedTarget)); - } + String path = identifier.getPath(); + if (FileRpoSearchProvider.isRpo(path)) { + String expectedTarget = path.substring(0, path.length() - Respackopts.FILE_EXTENSION.length()); + if (ids.stream().noneMatch(s -> s.getPath().equals(expectedTarget)) && fileHasFallback(pack, type.getDirectory() + "/" + expectedTarget)) { + Identifier id = new Identifier(namespace, expectedTarget); + ids.add(id); + out.accept(id, pack.open(type, id)); } } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileRpoSearchProvider.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileRpoSearchProvider.java index 248c4fa..c8eb521 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileRpoSearchProvider.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/filters/util/FileRpoSearchProvider.java @@ -2,18 +2,14 @@ package io.gitlab.jfronny.respackopts.filters.util; import io.gitlab.jfronny.libjf.ResourcePath; import io.gitlab.jfronny.respackopts.Respackopts; -import io.gitlab.jfronny.respackopts.gson.*; -import io.gitlab.jfronny.respackopts.model.DirRpo; +import io.gitlab.jfronny.respackopts.gson.AttachmentHolder; import io.gitlab.jfronny.respackopts.model.FileRpo; -import io.gitlab.jfronny.respackopts.model.cache.*; +import io.gitlab.jfronny.respackopts.model.cache.CachedPackState; import io.gitlab.jfronny.respackopts.util.MetaCache; -import net.minecraft.resource.ResourceNotFoundException; +import net.minecraft.resource.InputSupplier; import net.minecraft.resource.ResourcePack; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; +import java.io.*; import java.util.Map; public class FileRpoSearchProvider { @@ -21,40 +17,37 @@ public class FileRpoSearchProvider { return fileName.endsWith(Respackopts.FILE_EXTENSION); } - public static T modifyWithRpo(String fileName, ResourcePack pack, ModifiedGenerator getModified, T defaultValue) { - if (FileRpoSearchProvider.isRpo(fileName)) - return defaultValue; + public static T modifyWithRpo(String fileName, ResourcePack pack, Action action, T defaultValue) { + if (isRpo(fileName)) return defaultValue; CachedPackState state = MetaCache.getState(MetaCache.getKeyByPack(pack)); - Map frpReg = state.cachedFileRPOs(); - String rpPathName = fileName + Respackopts.FILE_EXTENSION; - if (frpReg.containsKey(rpPathName)) - return getModified.getModified(frpReg.get(rpPathName)); + Map rpoCache = state.cachedFileRPOs(); + String rpoPathS = fileName + Respackopts.FILE_EXTENSION; + if (rpoCache.containsKey(rpoPathS)) return action.run(rpoCache.get(rpoPathS)); ResourcePath rpoPath = null; + InputSupplier is; if (fileName.contains("/")) { try { - rpoPath = new ResourcePath(rpPathName); - if (!pack.contains(rpoPath.getType(), rpoPath.getId())) - return defaultValue; + rpoPath = new ResourcePath(rpoPathS); + is = pack.open(rpoPath.getType(), rpoPath.getId()); } catch (Throwable e) { Respackopts.LOGGER.error("Could not check file filter status", e); return defaultValue; } - } - try (InputStream stream = rpoPath == null ? pack.openRoot(rpPathName) : pack.open(rpoPath.getType(), rpoPath.getId()); - Reader w = stream == null ? null : new InputStreamReader(stream)) { - if (w == null) throw new FileNotFoundException("Could not find file: " + fileName); + } else is = pack.openRoot(rpoPathS); + if (is == null) return defaultValue; + try (Reader w = new InputStreamReader(is.get())) { FileRpo frp = AttachmentHolder.deserialize(state.metadata().version, w, FileRpo.class); - frp.path = rpPathName; - frpReg.put(rpPathName, frp); - return getModified.getModified(frp); + frp.path = rpoPathS; + rpoCache.put(rpoPathS, frp); + return action.run(frp); } catch (Exception e) { - if (!(e instanceof ResourceNotFoundException)) Respackopts.LOGGER.error("Could not generate replacement for " + (rpoPath == null ? fileName : rpoPath.getName()) + " in " + pack.getName(), e); + Respackopts.LOGGER.error("Could not get replacement for " + (rpoPath == null ? fileName : rpoPath.getName()) + " in " + pack.getName(), e); return defaultValue; } } - public interface ModifiedGenerator { - T getModified(FileRpo rpo); + public interface Action { + T run(FileRpo rpo); } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/mixin/AbstractFileResourcePackAccessor.java b/src/main/java/io/gitlab/jfronny/respackopts/mixin/AbstractFileResourcePackAccessor.java deleted file mode 100644 index e339bae..0000000 --- a/src/main/java/io/gitlab/jfronny/respackopts/mixin/AbstractFileResourcePackAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.gitlab.jfronny.respackopts.mixin; - -import net.minecraft.resource.AbstractFileResourcePack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.io.File; - -@Mixin(AbstractFileResourcePack.class) -public interface AbstractFileResourcePackAccessor { - @Accessor("base") - File getBase(); -} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/mixin/DirectoryResourcePackAccessor.java b/src/main/java/io/gitlab/jfronny/respackopts/mixin/DirectoryResourcePackAccessor.java new file mode 100644 index 0000000..fa10124 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/respackopts/mixin/DirectoryResourcePackAccessor.java @@ -0,0 +1,13 @@ +package io.gitlab.jfronny.respackopts.mixin; + +import net.minecraft.resource.DirectoryResourcePack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.nio.file.Path; + +@Mixin(DirectoryResourcePack.class) +public interface DirectoryResourcePackAccessor { + @Accessor("root") + Path getRoot(); +} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/mixin/FileResourcePackProviderMixin.java b/src/main/java/io/gitlab/jfronny/respackopts/mixin/FileResourcePackProviderMixin.java new file mode 100644 index 0000000..5fc85f9 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/respackopts/mixin/FileResourcePackProviderMixin.java @@ -0,0 +1,20 @@ +package io.gitlab.jfronny.respackopts.mixin; + +import io.gitlab.jfronny.respackopts.Respackopts; +import net.minecraft.resource.FileResourcePackProvider; +import net.minecraft.resource.ResourcePackProfile; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.nio.file.Files; +import java.nio.file.Path; + +@Mixin(FileResourcePackProvider.class) +public class FileResourcePackProviderMixin { + @Inject(method = "getFactory(Ljava/nio/file/Path;Z)Lnet/minecraft/resource/ResourcePackProfile$PackFactory;", at = @At("HEAD"), cancellable = true) + private static void getFactory(Path path, boolean alwaysStable, CallbackInfoReturnable cir) { + if (Files.isRegularFile(path) && path.getFileName().toString().endsWith(Respackopts.FILE_EXTENSION)) cir.setReturnValue(null); + } +} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/mixin/ResourcePackManagerMixin.java b/src/main/java/io/gitlab/jfronny/respackopts/mixin/ResourcePackManagerMixin.java index a1d53a4..425de61 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/mixin/ResourcePackManagerMixin.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/mixin/ResourcePackManagerMixin.java @@ -44,38 +44,38 @@ public class ResourcePackManagerMixin { private void rpo$checkProfile(String profileName, String displayName, ResourcePack rpi, Set toRemove) { Path dataLocation = null; - if (rpi instanceof AbstractFileResourcePack arr) { - File pack = arr.getBase(); - if (pack != null) { - dataLocation = pack.toPath().getParent().resolve(pack.getName() + Respackopts.FILE_EXTENSION); - } else { - Respackopts.LOGGER.warn("Base path of abstract file resource pack " + arr.getName() + " is null. This shouldn't happen!"); - } + if (rpi instanceof DirectoryResourcePack drp) { + Path pack = ((DirectoryResourcePackAccessor) drp).getRoot(); + if (pack != null) dataLocation = pack.getParent().resolve(pack.getFileName() + Respackopts.FILE_EXTENSION); + else Respackopts.LOGGER.warn("Base path of directory resource pack " + rpi.getName() + " is null. This shouldn't happen!"); + } else if (rpi instanceof ZipResourcePack zrp) { + File pack = ((ZipResourcePackAccessor) zrp).getBackingZipFile(); + if (pack != null) dataLocation = pack.toPath().getParent().resolve(pack.getName() + Respackopts.FILE_EXTENSION); + else Respackopts.LOGGER.warn("Base path of zip resource pack " + rpi.getName() + " is null. This shouldn't happen!"); } - try (InputStream is = rpi.openRoot(Respackopts.ID + ".json5")) { - rpo$readConfiguration(is, dataLocation, rpi.getName(), displayName, toRemove); - return; - } catch (FileNotFoundException ignored) { - } catch (IOException e) { - String message = "Could not read respackopts config in root for " + profileName; - if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.error(message, e); - else Respackopts.LOGGER.error(message); + var conf = rpi.openRoot(Respackopts.ID + ".json5"); + if (conf != null) { + try (InputStream is = conf.get()) { + rpo$readConfiguration(is, dataLocation, rpi.getName(), displayName, toRemove); + return; + } catch (IOException e) { + String message = "Could not read respackopts config in root for " + profileName; + if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.error(message, e); + else Respackopts.LOGGER.error(message); + } } Identifier confId = new Identifier(Respackopts.ID, "conf.json"); - ResourceType packConfType = null; for (ResourceType type : ResourceType.values()) { - if (rpi.contains(type, confId)) { - packConfType = type; - } - } - - if (packConfType != null) { - try (InputStream is = rpi.open(packConfType, confId)) { - rpo$readConfiguration(is, dataLocation, rpi.getName(), displayName, toRemove); - } catch (Throwable e) { - Respackopts.LOGGER.error("Could not initialize pack meta for " + profileName, e); + conf = rpi.open(type, confId); + if (conf != null) { + try (InputStream is = conf.get()) { + rpo$readConfiguration(is, dataLocation, rpi.getName(), displayName, toRemove); + return; + } catch (Throwable e) { + Respackopts.LOGGER.error("Could not initialize pack meta for " + profileName, e); + } } } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/mixin/ZipResourcePackAccessor.java b/src/main/java/io/gitlab/jfronny/respackopts/mixin/ZipResourcePackAccessor.java new file mode 100644 index 0000000..6940102 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/respackopts/mixin/ZipResourcePackAccessor.java @@ -0,0 +1,13 @@ +package io.gitlab.jfronny.respackopts.mixin; + +import net.minecraft.resource.ZipResourcePack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.io.File; + +@Mixin(ZipResourcePack.class) +public interface ZipResourcePackAccessor { + @Accessor("backingZipFile") + File getBackingZipFile(); +} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/server/ServerInstanceHolder.java b/src/main/java/io/gitlab/jfronny/respackopts/server/ServerInstanceHolder.java index aabb07f..d96d755 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/server/ServerInstanceHolder.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/server/ServerInstanceHolder.java @@ -42,7 +42,7 @@ public class ServerInstanceHolder { SaveProperties saveProperties = server.getSaveProperties(); List enabled = Lists.newArrayList(manager.getEnabledNames()); manager.scanPacks(); - List disabled = saveProperties.getDataPackSettings().getDisabled(); + List disabled = saveProperties.getDataConfiguration().dataPacks().getDisabled(); for (String name : manager.getNames()) { if (!disabled.contains(name) && !enabled.contains(name)) { enabled.add(name); diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 08f3417..65a92b8 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -39,10 +39,5 @@ }, "conflicts": { "libjf": "<3.0.0" - }, - "custom": { - "loom:injected_interfaces": { - "net/minecraft/class_3255": ["io/gitlab/jfronny/respackopts/mixin/AbstractFileResourcePackAccessor"] - } } } diff --git a/src/main/resources/respackopts.mixins.json b/src/main/resources/respackopts.mixins.json index b6146fb..14d41ca 100644 --- a/src/main/resources/respackopts.mixins.json +++ b/src/main/resources/respackopts.mixins.json @@ -4,8 +4,10 @@ "package": "io.gitlab.jfronny.respackopts.mixin", "compatibilityLevel": "JAVA_8", "mixins": [ - "AbstractFileResourcePackAccessor", - "ResourcePackManagerMixin" + "DirectoryResourcePackAccessor", + "FileResourcePackProviderMixin", + "ResourcePackManagerMixin", + "ZipResourcePackAccessor" ], "injectors": { "defaultRequire": 1