diff --git a/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java b/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java index 13c5a74..45ece6a 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java @@ -4,6 +4,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import io.gitlab.jfronny.libjf.data.WrappedPack; import io.gitlab.jfronny.respackopts.data.DirRpo; +import io.gitlab.jfronny.respackopts.data.PackCapability; +import io.gitlab.jfronny.respackopts.data.Respackmeta; import io.gitlab.jfronny.respackopts.data.Rpo; import io.gitlab.jfronny.respackopts.data.entry.*; import io.gitlab.jfronny.respackopts.filters.DirFilterProvider; @@ -36,7 +38,7 @@ import java.util.concurrent.CompletableFuture; @Environment(EnvType.CLIENT) public class Respackopts implements ClientModInitializer { - public static final Integer META_VERSION = 4; + public static final Integer META_VERSION = 5; public static final String ID = "respackopts"; public static final Identifier CONF_ID = new Identifier(ID, "conf.json"); public static final Logger LOGGER = LogManager.getFormatterLogger(ID); @@ -45,6 +47,7 @@ public class Respackopts implements ClientModInitializer { public static Path CONF_DIR; public static final Map CONFIG_BRANCH = new HashMap<>(); + public static final Map PACK_METAS = new HashMap<>(); public static final Map DISPLAY_NAME_LOOKUP = new HashMap<>(); public static final Map PACK_NAME_LOOKUP = new HashMap<>(); @@ -82,6 +85,12 @@ public class Respackopts implements ClientModInitializer { return PACK_NAME_LOOKUP.get(pack.getName()); } + public static boolean hasCapability(WrappedPack pack, PackCapability capability) { + String id = getId(pack); + if (id == null) return false; + return PACK_METAS.get(id).capabilities.contains(capability); + } + @Override public void onInitializeClient() { try { diff --git a/src/main/java/io/gitlab/jfronny/respackopts/data/PackCapability.java b/src/main/java/io/gitlab/jfronny/respackopts/data/PackCapability.java new file mode 100644 index 0000000..8a0be9a --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/respackopts/data/PackCapability.java @@ -0,0 +1,5 @@ +package io.gitlab.jfronny.respackopts.data; + +public enum PackCapability { + FileFilter, DirFilter, DirFilterAdditive +} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/data/Respackmeta.java b/src/main/java/io/gitlab/jfronny/respackopts/data/Respackmeta.java index 0561ae4..c5f5780 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/data/Respackmeta.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/data/Respackmeta.java @@ -2,8 +2,11 @@ package io.gitlab.jfronny.respackopts.data; import io.gitlab.jfronny.respackopts.data.entry.ConfigBranch; +import java.util.Set; + public class Respackmeta { public ConfigBranch conf; public String id; public Integer version; + public Set capabilities = Set.of(PackCapability.FileFilter); } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterProvider.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterProvider.java index 8a0d771..bccb91f 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterProvider.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/filters/DirFilterProvider.java @@ -5,6 +5,7 @@ import io.gitlab.jfronny.libjf.data.UserResourceEvents; import io.gitlab.jfronny.libjf.data.WrappedPack; import io.gitlab.jfronny.respackopts.Respackopts; import io.gitlab.jfronny.respackopts.data.DirRpo; +import io.gitlab.jfronny.respackopts.data.PackCapability; import io.gitlab.jfronny.respackopts.data.RpoError; import io.gitlab.jfronny.respackopts.filters.conditions.ConditionEvaluator; import net.minecraft.util.Identifier; @@ -14,6 +15,8 @@ import java.io.*; public class DirFilterProvider { public static void init() { UserResourceEvents.OPEN.register((type, id, previous, pack) -> { + if (!Respackopts.hasCapability(pack, PackCapability.DirFilter)) + return previous; String path = new ResourcePath(type, id).getName(); DirRpo rpo = findDirRpo(pack, path); if (rpo != null && dirHidden(rpo, Respackopts.getId(pack))) { @@ -27,19 +30,40 @@ public class DirFilterProvider { UserResourceEvents.FIND_RESOURCE.register((type, namespace, prefix, maxDepth, pathFilter, 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! + if (!Respackopts.hasCapability(pack, PackCapability.DirFilter)) + return previous; + boolean dirFilterAdditive = Respackopts.hasCapability(pack, PackCapability.DirFilterAdditive); //TODO support files that weren't there at the original location for (Identifier identifier : previous) { String path = type.getDirectory() + "/" + identifier.getNamespace() + "/" + identifier.getPath(); DirRpo rpo = findDirRpo(pack, path); - if (rpo != null && dirHidden(rpo, Respackopts.getId(pack))) { - path = findReplacementDir(path, rpo); - if (path == null) - previous.remove(identifier); + if (rpo != null) { + if (dirHidden(rpo, Respackopts.getId(pack))) { + path = findReplacementDir(path, rpo); + if (path == null) + previous.remove(identifier); + else if (dirFilterAdditive) { + String[] s = path.split("/", 3); + if (s.length == 3) { + ResourcePath rp = new ResourcePath(path); + //TODO this implementation is stupid + for (Identifier resource : pack.findResources(rp.getType(), rp.getId().getNamespace(), rp.getId().getPath(), maxDepth, (a) -> true)) { + String p = type.getDirectory() + "/" + resource.getNamespace() + "/" + resource.getPath(); + p = p.replace(rpo.fallback, rpo.path + "/"); + rp = new ResourcePath(p); + if (pathFilter.test(p)) + previous.add(rp.getId()); + } + } + } + } } } return previous; }); UserResourceEvents.CONTAINS.register((type, id, previous, pack) -> { + if (!Respackopts.hasCapability(pack, PackCapability.DirFilter)) + return previous; String path = new ResourcePath(type, id).getName(); DirRpo rpo = findDirRpo(pack, path); if (rpo != null && dirHidden(rpo, Respackopts.getId(pack))) { diff --git a/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterProvider.java b/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterProvider.java index b515e86..24b5d40 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterProvider.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/filters/FileFilterProvider.java @@ -3,6 +3,8 @@ package io.gitlab.jfronny.respackopts.filters; import io.gitlab.jfronny.libjf.data.ResourcePath; import io.gitlab.jfronny.libjf.data.UserResourceEvents; import io.gitlab.jfronny.libjf.data.WrappedPack; +import io.gitlab.jfronny.respackopts.Respackopts; +import io.gitlab.jfronny.respackopts.data.PackCapability; import io.gitlab.jfronny.respackopts.filters.conditions.ResourcePackFilter; import io.gitlab.jfronny.respackopts.filters.expansion.DataExpander; import io.gitlab.jfronny.respackopts.filters.fallback.FallbackFilter; @@ -61,6 +63,6 @@ public class FileFilterProvider { } private static boolean skip(WrappedPack pack) { - return !(pack.getUnderlying() instanceof AbstractFileResourcePack); + return !(pack.getUnderlying() instanceof AbstractFileResourcePack) || !Respackopts.hasCapability(pack, PackCapability.FileFilter); } } 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 1d60044..38aa21a 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/mixin/ResourcePackManagerMixin.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/mixin/ResourcePackManagerMixin.java @@ -4,6 +4,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.gitlab.jfronny.respackopts.Respackopts; import io.gitlab.jfronny.respackopts.data.MetadataLocateResult; +import io.gitlab.jfronny.respackopts.data.PackCapability; import io.gitlab.jfronny.respackopts.data.Respackmeta; import io.gitlab.jfronny.respackopts.data.entry.SyncMode; import net.minecraft.resource.ResourcePack; @@ -41,12 +42,15 @@ public class ResourcePackManagerMixin { Respackopts.LOGGER.warn(s + " uses an outdated RPO format (" + conf.version + "). Although this is supported, using the latest version (" + Respackopts.META_VERSION + ") is recommended"); } conf.conf.setVersion(conf.version); + if (conf.version < 5) + conf.capabilities.add(PackCapability.DirFilter); if (!Respackopts.CONFIG_BRANCH.containsKey(conf.id)) Respackopts.CONFIG_BRANCH.put(conf.id, conf.conf); else Respackopts.CONFIG_BRANCH.get(conf.id).sync(conf.conf, SyncMode.RESPACK_LOAD); Respackopts.DISPLAY_NAME_LOOKUP.put(v.getDisplayName().asString(), conf.id); Respackopts.PACK_NAME_LOOKUP.put(v.createResourcePack().getName(), conf.id); + Respackopts.PACK_METAS.put(conf.id, conf); Respackopts.load(conf.id); } catch (Throwable e) { Respackopts.LOGGER.error("Could not initialize pack meta for " + s, e);