added list_files, fixes #589

This commit is contained in:
gnembon committed 2020-12-03 04:05:11 -04:00
1 parent 5a15c115ac
commit 6e5af5bfc8
8 files changed
+126 -74

No files matched your search

@@ -41,6 +41,7 @@ import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.lang.Math.max;
import static net.minecraft.server.command.CommandManager.literal;
@@ -673,6 +674,12 @@ public class CarpetScriptHost extends ScriptHost
return Module.listFile(main, resource, "txt", isShared);
}
public Stream<String> listFolder(String resource, String ext, boolean isShared)
{
if (getName() == null && !isShared) return null; //
return Module.listFolder(main, resource, ext, isShared);
}
public void tick()
{
@@ -137,7 +137,7 @@ public class CarpetScriptServer
Path folder = server.getSavePath(WorldSavePath.ROOT).resolve("scripts");
Files.createDirectories(folder);
Optional<Path>
scriptPath = Files.walk(folder)
scriptPath = Files.list(folder)
.filter(script ->
script.getFileName().toString().equalsIgnoreCase(name+".sc") ||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name+".scl"))
@@ -149,7 +149,7 @@ public class CarpetScriptServer
{
Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
Files.createDirectories(globalFolder);
scriptPath = Files.walk(globalFolder)
scriptPath = Files.list(globalFolder)
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
.findFirst();
+48 -28
View File
@@ -32,6 +32,7 @@ import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.utils.Messenger;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.BlockState;
import net.minecraft.command.argument.EntityAnchorArgumentType;
import net.minecraft.entity.Entity;
@@ -50,7 +51,6 @@ import net.minecraft.particle.ParticleEffect;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.CommandOutput;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
@@ -69,6 +69,7 @@ import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import java.util.ArrayList;
import java.util.Arrays;
@@ -87,6 +88,12 @@ import static java.lang.Math.min;
public class Auxiliary {
public static final String MARKER_STRING = "__scarpet_marker";
private static final Map<String, SoundCategory> mixerMap = Arrays.stream(SoundCategory.values()).collect(Collectors.toMap(SoundCategory::getName, k -> k));
private static final Map<String, String> supportedTypes = ImmutableMap.of(
"raw", ".txt",
"text", ".txt",
"nbt", ".nbt",
"folder", "folder"
);
public static String recognizeResource(Value value, boolean isFloder)
{
@@ -100,6 +107,20 @@ public class Auxiliary {
return file;
}
public static Triple<String, String, Boolean> getFileDescriptor(List<LazyValue> lv, Context c, boolean isFloder)
{
if (lv.size() < 2) throw new InternalExpressionException("File functions require path and type as first two arguments");
String resource = recognizeResource(lv.get(0).evalValue(c), isFloder);
String origtype = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
boolean shared = origtype.startsWith("shared_");
String type = shared ? origtype.substring(7) : origtype; //len(shared_)
if (!supportedTypes.containsKey(type))
throw new InternalExpressionException("Unsupported file type: "+origtype);
if (type.equals("folder") && !isFloder)
throw new InternalExpressionException("Folder types are no supported for this IO function");
return Triple.of(resource, type, shared);
}
public static void apply(Expression expression)
{
expression.addLazyFunction("sound", -1, (c, t, lv) -> {
@@ -785,23 +806,29 @@ public class Auxiliary {
return (_c, _t) -> res; // pass through for variables
});
expression.addLazyFunction("read_file", 2, (c, t, lv) -> {
String resource = recognizeResource(lv.get(0).evalValue(c), false);
String origtype = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
boolean shared = origtype.startsWith("shared_");
String type = shared ? origtype.substring(7) : origtype; //len(shared_)
if (!type.equals("raw") && !type.equals("text") && !type.equals("nbt"))
throw new InternalExpressionException("Unsupported file type: "+origtype);
expression.addLazyFunction("list_files", 2, (c, t, lv) ->
{
Triple<String, String, Boolean> fdesc = getFileDescriptor(lv, c, true);
Stream<String> files = ((CarpetScriptHost) c.host).listFolder(fdesc.getLeft(), supportedTypes.get(fdesc.getMiddle()), fdesc.getRight());
if (files == null) return LazyValue.NULL;
Value ret = ListValue.wrap(files.map(StringValue::of).collect(Collectors.toList()));
return (cc, tt) -> ret;
});
expression.addLazyFunction("read_file", 2, (c, t, lv) ->
{
Triple<String, String, Boolean> fdesc = getFileDescriptor(lv, c, false);
Value retVal;
if (type.equals("nbt"))
if (fdesc.getMiddle().equals("nbt"))
{
Tag state = ((CarpetScriptHost)((CarpetContext)c).host).readFileTag(resource, shared);
Tag state = ((CarpetScriptHost) c.host).readFileTag(fdesc.getLeft(), fdesc.getRight());
if (state == null) return LazyValue.NULL;
retVal = new NBTSerializableValue(state);
}
else
{
List<String> content = ((CarpetScriptHost) ((CarpetContext) c).host).readTextResource(resource, shared);
List<String> content = ((CarpetScriptHost) c.host).readTextResource(fdesc.getLeft(), fdesc.getRight());
if (content == null) return LazyValue.NULL;
retVal = ListValue.wrap(content.stream().map(StringValue::new).collect(Collectors.toList()));
}
@@ -809,33 +836,26 @@ public class Auxiliary {
});
expression.addLazyFunction("delete_file", 2, (c, t, lv) -> {
String resource = recognizeResource(lv.get(0).evalValue(c), false);
String origtype = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
boolean shared = origtype.startsWith("shared_");
String type = shared ? origtype.substring(7) : origtype; //len(shared_)
if (!type.equals("raw") && !type.equals("text") && !type.equals("nbt"))
throw new InternalExpressionException("Unsupported file type: "+origtype);
boolean success = ((CarpetScriptHost)((CarpetContext)c).host).removeResourceFile(resource, shared, type);
return success?LazyValue.TRUE:LazyValue.FALSE;
Triple<String, String, Boolean> fdesc = getFileDescriptor(lv, c, false);
return ((CarpetScriptHost) c.host).removeResourceFile(fdesc.getLeft(), fdesc.getRight(), fdesc.getMiddle())
? LazyValue.TRUE
: LazyValue.FALSE;
});
expression.addLazyFunction("write_file", -1, (c, t, lv) -> {
if (lv.size() < 3) throw new InternalExpressionException("'write_file' requires three or more arguments");
String resource = recognizeResource(lv.get(0).evalValue(c), false);
String origtype = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
boolean shared = origtype.startsWith("shared_");
String type = shared ? origtype.substring(7) : origtype; //len(shared_)
if (!type.equals("raw") && !type.equals("text") && !type.equals("nbt"))
throw new InternalExpressionException("Unsupported file type: "+origtype);
Triple<String, String, Boolean> fdesc = getFileDescriptor(lv, c, false);
boolean success;
if (type.equals("nbt"))
if (fdesc.getMiddle().equals("nbt"))
{
Value val = lv.get(2).evalValue(c);
NBTSerializableValue tagValue = (val instanceof NBTSerializableValue)
? (NBTSerializableValue) val
: new NBTSerializableValue(val.getString());
Tag tag = tagValue.getTag();
success = ((CarpetScriptHost)((CarpetContext)c).host).writeTagFile(tag, resource, shared);
success = ((CarpetScriptHost) c.host).writeTagFile(tag, fdesc.getLeft(), fdesc.getRight());
}
else
{
@@ -860,7 +880,7 @@ public class Auxiliary {
data.add(lv.get(i).evalValue(c).getString());
}
}
success = ((CarpetScriptHost) ((CarpetContext) c).host).appendLogFile(resource, shared, type, data);
success = ((CarpetScriptHost) c.host).appendLogFile(fdesc.getLeft(), fdesc.getRight(), fdesc.getMiddle(), data);
}
return success?LazyValue.TRUE:LazyValue.FALSE;
});
@@ -23,6 +23,7 @@ import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
public class FileModule extends Module
{
@@ -175,4 +176,18 @@ public class FileModule extends Module
return null;
}
}
public static Stream<Path> listFiles(Path dir, String ext)
{
boolean folderListing = ext.equals("folder");
try
{
return Files.list(dir).
filter(path -> folderListing?Files.isDirectory(path):path.toString().endsWith(ext));
}
catch (IOException ignored)
{
return null;
}
}
}
+38 -24
View File
@@ -3,10 +3,12 @@ package carpet.script.bundled;
import carpet.CarpetServer;
import net.minecraft.nbt.Tag;
import net.minecraft.util.WorldSavePath;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;
public abstract class Module
{
@@ -19,61 +21,73 @@ public abstract class Module
{
if (isShared)
{
return "shared/"+file;
return file.isEmpty()?"shared":"shared/"+file;
}
else if (module != null && module.getName() != null) // appdata
if (module != null && module.getName() != null) // appdata
{
return module.getName()+".data"+(file==null?"":"/"+file);
}
else
{
throw new RuntimeException("Invalid file descriptor: "+file);
return module.getName()+".data"+(file==null || file.isEmpty()?"":"/"+file);
}
throw new RuntimeException("Invalid file descriptor: "+file);
}
public static Tag getData(Module module, String file, boolean isShared)
{
File dataFile = resolveResource(module, file, "nbt", isShared);
Path dataFile = resolveResource(module, file, "nbt", isShared);
if (dataFile == null) return null;
if (!Files.exists(dataFile.toPath()) || !(dataFile.isFile())) return null;
synchronized (writeIOSync) { return FileModule.read(dataFile); }
if (!Files.exists(dataFile) || !(dataFile.toFile().isFile())) return null;
synchronized (writeIOSync) { return FileModule.read(dataFile.toFile()); }
}
public static boolean saveData(Module module, String file, Tag globalState, boolean isShared)
{
File dataFile = resolveResource(module, file, "nbt", isShared);
Path dataFile = resolveResource(module, file, "nbt", isShared);
if (dataFile == null) return false;
if (!Files.exists(dataFile.toPath().getParent()) && !dataFile.getParentFile().mkdirs()) return false;
synchronized (writeIOSync) { return FileModule.write(globalState, dataFile); }
if (!Files.exists(dataFile.getParent()) && !dataFile.toFile().getParentFile().mkdirs()) return false;
synchronized (writeIOSync) { return FileModule.write(globalState, dataFile.toFile()); }
}
public static boolean appendToTextFile(Module module, String resourceName, String type, boolean isShared, List<String> message)
{
File dataFile = resolveResource(module, resourceName, "txt", isShared);
Path dataFile = resolveResource(module, resourceName, "txt", isShared);
if (dataFile == null) return false;
if (!Files.exists(dataFile.toPath().getParent()) && !dataFile.getParentFile().mkdirs()) return false;
synchronized (writeIOSync) { return FileModule.appendText(dataFile, type.equals("text"), message); }
if (!Files.exists(dataFile.getParent()) && !dataFile.toFile().getParentFile().mkdirs()) return false;
synchronized (writeIOSync) { return FileModule.appendText(dataFile.toFile(), type.equals("text"), message); }
}
public static boolean dropExistingFile(Module module, String resourceName, String ext, boolean isShared)
{
File dataFile = resolveResource(module, resourceName, ext, isShared);
Path dataFile = resolveResource(module, resourceName, ext, isShared);
if (dataFile == null) return false;
synchronized (writeIOSync) { return dataFile.delete(); }
synchronized (writeIOSync) { return dataFile.toFile().delete(); }
}
public static List<String> listFile(Module module, String resourceName, String ext, boolean isShared)
{
File dataFile = resolveResource(module, resourceName, ext, isShared);
Path dataFile = resolveResource(module, resourceName, ext, isShared);
if (dataFile == null) return null;
if (!dataFile.exists()) return null;
synchronized (writeIOSync) { return FileModule.listFileContent(dataFile); }
if (!dataFile.toFile().exists()) return null;
synchronized (writeIOSync) { return FileModule.listFileContent(dataFile.toFile()); }
}
private static File resolveResource(Module module, String resourceName, String ext, boolean isShared)
public static Stream<String> listFolder(Module module, String resourceName, String ext, boolean isShared)
{
Path dir = resolveResource(module, resourceName, null, isShared);
if (dir == null) return null;
if (!Files.exists(dir)) return null;
Stream<Path> result;
synchronized (writeIOSync) { result = FileModule.listFiles(dir, ext); }
if (result == null) return null;
Path rootPath = resolveResource(module, "", null, isShared);
Stream<String> strings = result.map(p -> rootPath.relativize(p).toString().replaceAll("[\\\\/]","/"));
if (!ext.equals("folder"))
return strings.map(FilenameUtils::removeExtension);
return strings;
}
private static Path resolveResource(Module module, String resourceName, String ext, boolean isShared)
{
if (!isShared && (module == null || module.getName() == null)) return null;
return CarpetServer.minecraft_server.getSavePath(WorldSavePath.ROOT).resolve("scripts/"+getDescriptor(module, resourceName, isShared)+"."+ext).toFile();
return CarpetServer.minecraft_server.getSavePath(WorldSavePath.ROOT).resolve("scripts/"+getDescriptor(module, resourceName, isShared)+(ext==null?"":"."+ext));
}
@Override