2021-08-25 20:26:42 +02:00
|
|
|
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.DirRpo;
|
2021-08-26 18:23:29 +02:00
|
|
|
import io.gitlab.jfronny.respackopts.data.PackCapability;
|
2021-08-25 20:26:42 +02:00
|
|
|
import io.gitlab.jfronny.respackopts.data.RpoError;
|
|
|
|
import io.gitlab.jfronny.respackopts.filters.conditions.ConditionEvaluator;
|
|
|
|
import net.minecraft.util.Identifier;
|
|
|
|
|
|
|
|
import java.io.*;
|
|
|
|
|
|
|
|
public class DirFilterProvider {
|
|
|
|
public static void init() {
|
|
|
|
UserResourceEvents.OPEN.register((type, id, previous, pack) -> {
|
2021-08-26 18:23:29 +02:00
|
|
|
if (!Respackopts.hasCapability(pack, PackCapability.DirFilter))
|
|
|
|
return previous;
|
2021-08-25 20:26:42 +02:00
|
|
|
String path = new ResourcePath(type, id).getName();
|
|
|
|
DirRpo rpo = findDirRpo(pack, path);
|
2021-08-26 16:00:21 +02:00
|
|
|
if (rpo != null && dirHidden(rpo, Respackopts.getId(pack))) {
|
2021-08-25 20:26:42 +02:00
|
|
|
path = findReplacementDir(path, rpo);
|
|
|
|
if (path == null) throw new FileNotFoundException();
|
|
|
|
ResourcePath rp = new ResourcePath(path);
|
|
|
|
return pack.open(rp.getType(), rp.getId());
|
|
|
|
}
|
|
|
|
return previous;
|
|
|
|
});
|
|
|
|
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!
|
2021-08-26 18:23:29 +02:00
|
|
|
if (!Respackopts.hasCapability(pack, PackCapability.DirFilter))
|
|
|
|
return previous;
|
|
|
|
boolean dirFilterAdditive = Respackopts.hasCapability(pack, PackCapability.DirFilterAdditive);
|
2021-08-25 20:26:42 +02:00
|
|
|
//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);
|
2021-08-26 18:23:29 +02:00
|
|
|
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());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-08-25 20:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return previous;
|
|
|
|
});
|
|
|
|
UserResourceEvents.CONTAINS.register((type, id, previous, pack) -> {
|
2021-08-26 18:23:29 +02:00
|
|
|
if (!Respackopts.hasCapability(pack, PackCapability.DirFilter))
|
|
|
|
return previous;
|
2021-08-25 20:26:42 +02:00
|
|
|
String path = new ResourcePath(type, id).getName();
|
|
|
|
DirRpo rpo = findDirRpo(pack, path);
|
2021-08-26 16:00:21 +02:00
|
|
|
if (rpo != null && dirHidden(rpo, Respackopts.getId(pack))) {
|
2021-08-25 20:26:42 +02:00
|
|
|
path = findReplacementDir(path, rpo);
|
|
|
|
if (path == null)
|
|
|
|
return false;
|
|
|
|
ResourcePath rp = new ResourcePath(path);
|
|
|
|
return pack.contains(rp.getType(), rp.getId());
|
|
|
|
}
|
|
|
|
return previous;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private static String findReplacementDir(String dir, DirRpo rpo) {
|
|
|
|
if (rpo.fallback == null) return null;
|
|
|
|
return dir.replace(rpo.path + "/", rpo.fallback);
|
|
|
|
}
|
|
|
|
|
2021-08-26 16:00:21 +02:00
|
|
|
private static boolean dirHidden(DirRpo rpo, String packId) {
|
2021-08-25 20:26:42 +02:00
|
|
|
if (rpo.conditions == null)
|
|
|
|
return false;
|
|
|
|
try {
|
2021-08-26 16:00:21 +02:00
|
|
|
return !ConditionEvaluator.evaluate(rpo.conditions, packId);
|
2021-08-25 20:26:42 +02:00
|
|
|
} catch (RpoError e) {
|
|
|
|
Respackopts.LOGGER.error("Couldn't parse dir conditions", e);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static DirRpo findDirRpo(WrappedPack pack, String name) {
|
|
|
|
int li = name.lastIndexOf('/');
|
|
|
|
if (li <= 0)
|
|
|
|
return null;
|
|
|
|
name = name.substring(0, li);
|
|
|
|
DirRpo drp = findDirRpo(pack, name);
|
|
|
|
if (drp != null)
|
|
|
|
return drp;
|
|
|
|
ResourcePath rp;
|
|
|
|
try {
|
|
|
|
rp = new ResourcePath(name + "/.rpo");
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
if (pack.getUnderlying().contains(rp.getType(), rp.getId())) {
|
|
|
|
try (InputStream stream = pack.getUnderlying().open(rp.getType(), rp.getId()); Reader w = new InputStreamReader(stream)) {
|
|
|
|
drp = Respackopts.GSON.fromJson(w, DirRpo.class);
|
|
|
|
drp.path = name;
|
|
|
|
if (drp.fallback != null && !drp.fallback.endsWith("/"))
|
|
|
|
drp.fallback += "/";
|
|
|
|
return drp;
|
|
|
|
} catch (IOException e) {
|
|
|
|
Respackopts.LOGGER.error("Couldn't open dir rpo", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|