Add .fbt fallback textures

This commit is contained in:
JFronny 2021-02-15 11:44:59 +01:00
parent 0bf67f0dd2
commit 685fe0900e
24 changed files with 206 additions and 71 deletions

View File

@ -46,8 +46,14 @@ There have been issues with LibCD in development, so it might be smart not to us
Respackopts allows creating conditional resources by creating a file named `{targetFile}.rpo`.\ Respackopts allows creating conditional resources by creating a file named `{targetFile}.rpo`.\
This file is a json file that contains an array named "conditions". The resource will be ignored if any of the conditions are not met.\ This file is a json file that contains an array named "conditions". The resource will be ignored if any of the conditions are not met.\
This allows (for example) overrides for textures to only be loaded if the user enables them through the config.\ This allows (for example) overrides for textures to only be loaded if the user enables them through the config.\
It also allows the following operations: `and`, `equal`, `nor`/`not`, `or`, `xor` It also allows the following operations: `and`, `equal`, `nor`/`not`, `or`, `xor`.\
As an example can be seen [here](https://gitlab.com/JFronny/respackopts/-/tree/master/run/resourcepacks/lumi/assets/minecraft/lang) An example can be seen [here](https://gitlab.com/JFronny/respackopts/-/tree/master/run/resourcepacks/lumi/assets/minecraft/lang)
### Fallback resources
Respackopts allows creating fallbacks for resources if they are unavailable/disabled.\
To do this, create a file named `{targetFile}.fbt`.\
This file should contain a simple json array where each element is a reference to a possible fallback file.\
Use this in conjunction with the conditional resources feature in order to create multiple options for a single texture.\
An example can be seen [here](https://gitlab.com/JFronny/respackopts/-/tree/master/run/resourcepacks/lumi/assets/minecraft/lang)
## Mod developers ## Mod developers
All data is available in static HashMaps in `io.gitlab.jfronny.respackopts.Respackopts`.\ All data is available in static HashMaps in `io.gitlab.jfronny.respackopts.Respackopts`.\
To save information, call `Respackopts.save()`, `Respackopts.load()` to load. To save information, call `Respackopts.save()`, `Respackopts.load()` to load.

View File

@ -26,19 +26,22 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway. // Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:0.30.3+1.16"
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
// You may need to force-disable transitiveness on them. // You may need to force-disable transitiveness on them.
modCompile("com.terraformersmc:modmenu:1.14.15") modCompile("com.terraformersmc:modmenu:1.16.7")
include modApi("me.shedaniel.cloth:config-2:4.8.3") { include modApi("me.shedaniel.cloth:config-2:4.8.3") {
exclude(group: "net.fabricmc.fabric-api") exclude(group: "net.fabricmc.fabric-api")
exclude(group: "io.github.prospector")
} }
modApi "io.github.cottonmc:LibCD:3.0.3+1.16.3" modApi "io.github.cottonmc:LibCD:3.0.3+1.16.3"
modCompile "grondag:frex-mc116:4.0+" modCompile "grondag:frex-mc116:4.0+"
modCompile "grondag:canvas-mc116:1.0.+" modCompile("grondag:canvas-mc116:1.0.+") {
exclude(group: "io.github.prospector")
}
} }
processResources { processResources {

View File

@ -3,12 +3,9 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://modmuss50.me/fabric.html # check these on https://modmuss50.me/fabric.html
minecraft_version=1.16.5 minecraft_version=1.16.5
yarn_mappings=1.16.5+build.3 yarn_mappings=1.16.5+build.4
loader_version=0.11.1 loader_version=0.11.1
# Mod Properties # Mod Properties
mod_version=1.3.1 mod_version=1.4.0
maven_group=io.gitlab.jfronny maven_group=io.gitlab.jfronny
archives_base_name=respackopts archives_base_name=respackopts
# Dependencies
# check this on https://modmuss50.me/fabric.html
fabric_version=0.29.4+1.16

View File

@ -0,0 +1,3 @@
[
"assets/minecraft/lang/en_us_joke.json"
]

View File

@ -0,0 +1,9 @@
{
"respackopts.title.lumi": "Not Lumi Lights",
"respackopts.field.lumi.tonemap": "Not Tonemap mode",
"respackopts.tooltip.lumi.tonemap": "Not Tooltip test",
"respackopts.field.lumi.pbr": "Not Enable PBR",
"respackopts.field.lumi.debugMode": "Not Debug Mode",
"respackopts.field.lumi.waterVertexWavy": "Not Wavy water model",
"respackopts.tooltip.lumi.subcategoryTest.sliderTest": "Not Yayyy"
}

View File

@ -0,0 +1,5 @@
{
"conditions": [
"lumi:subcategoryTest.enableLangJokeFallback"
]
}

View File

@ -32,7 +32,8 @@
"max": 20 "max": 20
}, },
"enableLang": true, "enableLang": true,
"enableLangForceDisable": false "enableLangForceDisable": false,
"enableLangJokeFallback": true
} }
} }
} }

View File

@ -2,7 +2,6 @@ package io.gitlab.jfronny.respackopts;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import io.gitlab.jfronny.respackopts.conditions.SyntaxError;
import io.gitlab.jfronny.respackopts.data.Config; import io.gitlab.jfronny.respackopts.data.Config;
import io.gitlab.jfronny.respackopts.data.Respackmeta; import io.gitlab.jfronny.respackopts.data.Respackmeta;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
@ -16,7 +15,6 @@ import java.io.*;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class Respackopts implements ClientModInitializer { public class Respackopts implements ClientModInitializer {
@ -32,6 +30,7 @@ public class Respackopts implements ClientModInitializer {
static final Path p = FabricLoader.getInstance().getConfigDir().resolve("respackopts"); static final Path p = FabricLoader.getInstance().getConfigDir().resolve("respackopts");
public static final Set<Runnable> saveActions = new HashSet<>(); public static final Set<Runnable> saveActions = new HashSet<>();
public static final String fileExtension = ".rpo"; public static final String fileExtension = ".rpo";
public static final String fallbackTextureExtension = ".fbt";
public static boolean forceRespackReload = false; public static boolean forceRespackReload = false;
public static final Logger logger = LogManager.getFormatterLogger(ID); public static final Logger logger = LogManager.getFormatterLogger(ID);
@Override @Override

View File

@ -0,0 +1,8 @@
package io.gitlab.jfronny.respackopts.abstractions;
import java.io.IOException;
import java.io.InputStream;
public interface FileOpenProvider {
InputStream open(String file) throws IOException;
}

View File

@ -0,0 +1,59 @@
package io.gitlab.jfronny.respackopts.filters;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.abstractions.FileOpenProvider;
import io.gitlab.jfronny.respackopts.filters.conditions.ResourcePackFilter;
import io.gitlab.jfronny.respackopts.filters.fallback.FallbackFilter;
import net.minecraft.resource.ResourceNotFoundException;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.function.Predicate;
public class FilterProvider {
ResourcePackFilter rpo;
FallbackFilter fbt;
Predicate<String> containsFileBase;
boolean containsFileWasFallback = false;
public FilterProvider(Predicate<String> containsFileBase, FileOpenProvider openFileBase) {
this.containsFileBase = containsFileBase;
rpo = new ResourcePackFilter(containsFileBase, openFileBase);
fbt = new FallbackFilter(containsFileBase, openFileBase);
}
public void openFile(String name, File base, CallbackInfoReturnable<InputStream> info) throws IOException {
if (containsFileBase.test(name) && containsFileWasFallback) {
info.setReturnValue(fbt.getReplacement(name, new ResourceNotFoundException(base, name)));
}
}
public void containsFile(String name, CallbackInfoReturnable<Boolean> info) {
containsFileWasFallback = false;
if (info.getReturnValueZ()) {
if (!rpo.fileVisible(name)) {
if (fbt.fileVisible(name)) {
containsFileWasFallback = true;
} else {
info.setReturnValue(false);
}
}
}
else {
if (!name.endsWith(Respackopts.fallbackTextureExtension) && fbt.fileVisible(name)) {
containsFileWasFallback = true;
info.setReturnValue(true);
}
}
}
public void findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter, CallbackInfoReturnable<Collection<Identifier>> info) {
Collection<Identifier> ret = info.getReturnValue();
ret.removeIf(s -> !rpo.fileVisible(s.getPath()) && !fbt.fileVisible(namespace));
fbt.addFallbackResources(ret, namespace);
}
}

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import io.gitlab.jfronny.respackopts.Respackopts; import io.gitlab.jfronny.respackopts.Respackopts;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;

View File

@ -1,18 +1,18 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import io.gitlab.jfronny.respackopts.Respackopts; import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.abstractions.FileOpenProvider;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
public class ResourcePackFilter { public class ResourcePackFilter {
Predicate<String> containsFileBase; Predicate<String> containsFileBase;
Function<String, InputStream> openFileBase; FileOpenProvider openFileBase;
public ResourcePackFilter(Predicate<String> containsFileBase, Function<String, InputStream> openFileBase) { public ResourcePackFilter(Predicate<String> containsFileBase, FileOpenProvider openFileBase) {
this.containsFileBase = containsFileBase; this.containsFileBase = containsFileBase;
this.openFileBase = openFileBase; this.openFileBase = openFileBase;
} }
@ -22,7 +22,7 @@ public class ResourcePackFilter {
return true; return true;
if (!containsFileBase.test(name + Respackopts.fileExtension)) if (!containsFileBase.test(name + Respackopts.fileExtension))
return true; return true;
try (InputStream stream = openFileBase.apply(name + Respackopts.fileExtension); Reader w = new InputStreamReader(stream)) { try (InputStream stream = openFileBase.open(name + Respackopts.fileExtension); Reader w = new InputStreamReader(stream)) {
return ConditionEvaluator.evaluate(Respackopts.g.fromJson(w, JsonElement.class)); return ConditionEvaluator.evaluate(Respackopts.g.fromJson(w, JsonElement.class));
} }
catch (Throwable e) { catch (Throwable e) {

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
public class SyntaxError extends Exception { public class SyntaxError extends Exception {
public SyntaxError(String message) { public SyntaxError(String message) {

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.respackopts.conditions; package io.gitlab.jfronny.respackopts.filters.conditions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;

View File

@ -0,0 +1,71 @@
package io.gitlab.jfronny.respackopts.filters.fallback;
import com.google.gson.reflect.TypeToken;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.abstractions.FileOpenProvider;
import net.minecraft.resource.ResourceNotFoundException;
import net.minecraft.util.Identifier;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Collection;
import java.util.Set;
import java.util.function.Predicate;
public class FallbackFilter {
Predicate<String> containsFileBase;
FileOpenProvider openFileBase;
public FallbackFilter(Predicate<String> containsFileBase, FileOpenProvider openFileBase) {
this.containsFileBase = containsFileBase;
this.openFileBase = openFileBase;
}
public boolean fileVisible(String name) {
String fbt = name + Respackopts.fallbackTextureExtension;
if (containsFileBase.test(fbt)) {
System.out.println(fbt);
try (InputStream stream = openFileBase.open(fbt); Reader w = new InputStreamReader(stream)) {
Set<String> arr = Respackopts.g.fromJson(w, new TypeToken<Set<String>>(){}.getType());
for (String s : arr) {
if (containsFileBase.test(s))
return true;
}
}
catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
public InputStream getReplacement(String name, ResourceNotFoundException ex) throws ResourceNotFoundException {
String fbt = name + Respackopts.fallbackTextureExtension;
try (InputStream stream = openFileBase.open(fbt); Reader w = new InputStreamReader(stream)) {
Set<String> arr = Respackopts.g.fromJson(w, new TypeToken<Set<String>>(){}.getType());
for (String s : arr) {
if (containsFileBase.test(s))
return openFileBase.open(s);
}
}
catch (IOException e) {
e.printStackTrace();
}
throw ex;
}
public void addFallbackResources(Collection<Identifier> ret, String namespace) {
for (Identifier identifier : ret) {
String path = identifier.getPath();
if (path.endsWith(Respackopts.fallbackTextureExtension)) {
String expectedTarget = path.substring(0, path.length() - Respackopts.fallbackTextureExtension.length());
System.out.println(expectedTarget);
if (ret.stream().noneMatch(s -> s.getPath().equals(expectedTarget)) && fileVisible(expectedTarget)) {
ret.add(new Identifier(namespace, expectedTarget));
System.out.println("Added fallback");
}
}
}
}
}

View File

@ -5,8 +5,7 @@ import io.github.cottonmc.libcd.api.CDSyntaxError;
import io.github.cottonmc.libcd.api.condition.ConditionManager; import io.github.cottonmc.libcd.api.condition.ConditionManager;
import io.github.cottonmc.libcd.api.init.ConditionInitializer; import io.github.cottonmc.libcd.api.init.ConditionInitializer;
import io.gitlab.jfronny.respackopts.Respackopts; import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.conditions.ConditionEvaluator; import io.gitlab.jfronny.respackopts.filters.conditions.ConditionEvaluator;
import io.gitlab.jfronny.respackopts.conditions.SyntaxError;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class LibCDCompat implements ConditionInitializer { public class LibCDCompat implements ConditionInitializer {

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.respackopts.integration; package io.gitlab.jfronny.respackopts.integration;
import io.github.prospector.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import io.github.prospector.modmenu.api.ModMenuApi; import com.terraformersmc.modmenu.api.ModMenuApi;
import io.gitlab.jfronny.respackopts.Respackopts; import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.abstractions.JfConfigCategoryPrimary; import io.gitlab.jfronny.respackopts.abstractions.JfConfigCategoryPrimary;
import me.shedaniel.clothconfig2.api.ConfigBuilder; import me.shedaniel.clothconfig2.api.ConfigBuilder;

View File

@ -1,21 +1,17 @@
package io.gitlab.jfronny.respackopts.mixin.conditions; package io.gitlab.jfronny.respackopts.mixin.conditions;
import io.gitlab.jfronny.respackopts.conditions.ResourcePackFilter; import io.gitlab.jfronny.respackopts.filters.FilterProvider;
import net.minecraft.resource.AbstractFileResourcePack; import net.minecraft.resource.AbstractFileResourcePack;
import net.minecraft.resource.DirectoryResourcePack; import net.minecraft.resource.DirectoryResourcePack;
import net.minecraft.resource.ResourceNotFoundException;
import net.minecraft.resource.ResourceType; import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.apache.commons.io.input.NullInputStream;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.io.File; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection; import java.util.Collection;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -32,28 +28,20 @@ public abstract class DirectoryResourcePackMixin extends AbstractFileResourcePac
@Shadow protected abstract InputStream openFile(String name) throws IOException; @Shadow protected abstract InputStream openFile(String name) throws IOException;
ResourcePackFilter filter = new ResourcePackFilter(this::containsFile, (s) -> { FilterProvider filter = new FilterProvider(this::containsFile, this::openFile);
try {
return openFile(s);
} catch (IOException e) {
e.printStackTrace();
return new NullInputStream(0);
}
});
@Inject(at = @At("HEAD"), method = "openFile(Ljava/lang/String;)Ljava/io/InputStream;", cancellable = true) @Inject(at = @At("HEAD"), method = "openFile(Ljava/lang/String;)Ljava/io/InputStream;", cancellable = true)
protected void openFile(String name, CallbackInfoReturnable<InputStream> info) throws IOException { protected void openFile(String name, CallbackInfoReturnable<InputStream> info) throws IOException {
if (!filter.fileVisible(name)) { filter.openFile(name, base, info);
throw new ResourceNotFoundException(this.base, name);
}
} }
@Inject(at = @At("TAIL"), method = "containsFile(Ljava/lang/String;)Z", cancellable = true) @Inject(at = @At("TAIL"), method = "containsFile(Ljava/lang/String;)Z", cancellable = true)
protected void containsFile(String name, CallbackInfoReturnable<Boolean> info) { protected void containsFile(String name, CallbackInfoReturnable<Boolean> info) {
info.setReturnValue(info.getReturnValueZ() && filter.fileVisible(name)); filter.containsFile(name, info);
} }
@Inject(at = @At("TAIL"), method = "findResources(Lnet/minecraft/resource/ResourceType;Ljava/lang/String;Ljava/lang/String;ILjava/util/function/Predicate;)Ljava/util/Collection;") @Inject(at = @At("TAIL"), method = "findResources(Lnet/minecraft/resource/ResourceType;Ljava/lang/String;Ljava/lang/String;ILjava/util/function/Predicate;)Ljava/util/Collection;")
private void findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter, CallbackInfoReturnable<Collection<Identifier>> info) { private void findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter, CallbackInfoReturnable<Collection<Identifier>> info) {
info.getReturnValue().removeIf(s -> !filter.fileVisible(s.getPath())); filter.findResources(type, namespace, prefix, maxDepth, pathFilter, info);
} }
} }

View File

@ -1,21 +1,17 @@
package io.gitlab.jfronny.respackopts.mixin.conditions; package io.gitlab.jfronny.respackopts.mixin.conditions;
import io.gitlab.jfronny.respackopts.conditions.ResourcePackFilter; import io.gitlab.jfronny.respackopts.filters.FilterProvider;
import net.minecraft.resource.AbstractFileResourcePack; import net.minecraft.resource.AbstractFileResourcePack;
import net.minecraft.resource.ResourceNotFoundException;
import net.minecraft.resource.ResourceType; import net.minecraft.resource.ResourceType;
import net.minecraft.resource.ZipResourcePack; import net.minecraft.resource.ZipResourcePack;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.apache.commons.io.input.NullInputStream;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.io.File; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection; import java.util.Collection;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -26,35 +22,26 @@ public abstract class ZipResourcePackMixin extends AbstractFileResourcePack {
super(base); super(base);
} }
@Shadow @Shadow public abstract boolean containsFile(String name);
protected abstract boolean containsFile(String name);
@Shadow public abstract Set<String> getNamespaces(ResourceType type); @Shadow public abstract Set<String> getNamespaces(ResourceType type);
@Shadow protected abstract InputStream openFile(String name) throws IOException; @Shadow protected abstract InputStream openFile(String name) throws IOException;
ResourcePackFilter filter = new ResourcePackFilter(this::containsFile, (s) -> { FilterProvider filter = new FilterProvider(this::containsFile, this::openFile);
try {
return openFile(s);
} catch (IOException e) {
e.printStackTrace();
return new NullInputStream(0);
}
});
@Inject(at = @At("HEAD"), method = "openFile(Ljava/lang/String;)Ljava/io/InputStream;", cancellable = true) @Inject(at = @At("HEAD"), method = "openFile(Ljava/lang/String;)Ljava/io/InputStream;", cancellable = true)
protected void openFile(String name, CallbackInfoReturnable<InputStream> info) throws IOException { protected void openFile(String name, CallbackInfoReturnable<InputStream> info) throws IOException {
if (!filter.fileVisible(name)) { filter.openFile(name, base, info);
throw new ResourceNotFoundException(this.base, name);
}
} }
@Inject(at = @At("TAIL"), method = "containsFile(Ljava/lang/String;)Z", cancellable = true) @Inject(at = @At("TAIL"), method = "containsFile(Ljava/lang/String;)Z", cancellable = true)
protected void containsFile(String name, CallbackInfoReturnable<Boolean> info) { protected void containsFile(String name, CallbackInfoReturnable<Boolean> info) {
info.setReturnValue(info.getReturnValueZ() && filter.fileVisible(name)); filter.containsFile(name, info);
} }
@Inject(at = @At("TAIL"), method = "findResources(Lnet/minecraft/resource/ResourceType;Ljava/lang/String;Ljava/lang/String;ILjava/util/function/Predicate;)Ljava/util/Collection;") @Inject(at = @At("TAIL"), method = "findResources(Lnet/minecraft/resource/ResourceType;Ljava/lang/String;Ljava/lang/String;ILjava/util/function/Predicate;)Ljava/util/Collection;")
private void findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter, CallbackInfoReturnable<Collection<Identifier>> info) { private void findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter, CallbackInfoReturnable<Collection<Identifier>> info) {
info.getReturnValue().removeIf(s -> !filter.fileVisible(s.getPath())); filter.findResources(type, namespace, prefix, maxDepth, pathFilter, info);
} }
} }