110 lines
4.8 KiB
Java
110 lines
4.8 KiB
Java
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<Long, Boolean> 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<Identifier> 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);
|
|
}
|
|
}
|