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