semi-auto cleanup

This commit is contained in:
gnembon committed 2023-02-04 13:26:21 +01:00
1 parent cad80f82c6
commit 8f61271606
99 files changed
+11463 -8007

No files matched your search

@@ -3,6 +3,7 @@ package carpet.script.argument;
public abstract class Argument
{
public int offset;
protected Argument(int offset)
{
this.offset = offset;
@@ -7,48 +7,52 @@ import carpet.script.value.ListValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import net.minecraft.core.BlockPos;
public class BlockArgument extends Argument
{
public final BlockValue block;
public final String replacement;
private BlockArgument(BlockValue b, int o)
private BlockArgument(final BlockValue b, final int o)
{
super(o);
block = b;
replacement = null;
}
private BlockArgument(BlockValue b, int o, String replacement)
private BlockArgument(final BlockValue b, final int o, final String replacement)
{
super(o);
block = b;
this.replacement = replacement;
}
public static BlockArgument findIn(CarpetContext c, List<Value> params, int offset)
public static BlockArgument findIn(final CarpetContext c, final List<Value> params, final int offset)
{
return findIn(c, params,offset, false, false, false);
return findIn(c, params, offset, false, false, false);
}
public static BlockArgument findIn(CarpetContext c, List<Value> params, int offset, boolean acceptString)
public static BlockArgument findIn(final CarpetContext c, final List<Value> params, final int offset, final boolean acceptString)
{
return findIn(c, params,offset, acceptString, false, false);
return findIn(c, params, offset, acceptString, false, false);
}
public static BlockArgument findIn(CarpetContext c, List<Value> params, int offset, boolean acceptString, boolean optional, boolean anyString)
public static BlockArgument findIn(final CarpetContext c, final List<Value> params, final int offset, final boolean acceptString, final boolean optional, final boolean anyString)
{
return findIn(c, params.listIterator(offset), offset, acceptString, optional, anyString);
}
public static BlockArgument findIn(CarpetContext c, Iterator<Value> params, int offset, boolean acceptString, boolean optional, boolean anyString)
public static BlockArgument findIn(final CarpetContext c, final Iterator<Value> params, final int offset, final boolean acceptString, final boolean optional, final boolean anyString)
{
try
{
Value v1 = params.next();
final Value v1 = params.next();
//add conditional from string name
if (optional && v1.isNull())
{
@@ -69,10 +73,10 @@ public class BlockArgument extends Argument
final BlockPos pos = c.origin();
if (v1 instanceof ListValue)
{
List<Value> args = ((ListValue) v1).getItems();
int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
final List<Value> args = ((ListValue) v1).getItems();
final int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
final int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
final int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
return new BlockArgument(
new BlockValue(
@@ -82,9 +86,9 @@ public class BlockArgument extends Argument
),
1 + offset);
}
int xpos = (int) NumericValue.asNumber(v1).getLong();
int ypos = (int) NumericValue.asNumber( params.next()).getLong();
int zpos = (int) NumericValue.asNumber( params.next()).getLong();
final int xpos = (int) NumericValue.asNumber(v1).getLong();
final int ypos = (int) NumericValue.asNumber(params.next()).getLong();
final int zpos = (int) NumericValue.asNumber(params.next()).getLong();
return new BlockArgument(
new BlockValue(
null,
@@ -100,13 +104,17 @@ public class BlockArgument extends Argument
}
}
private static InternalExpressionException handleError(boolean optional, boolean acceptString)
private static InternalExpressionException handleError(final boolean optional, final boolean acceptString)
{
String message = "Block-type argument should be defined either by three coordinates (a triple or by three arguments), or a block value";
if (acceptString)
message+=", or a string with block description";
{
message += ", or a string with block description";
}
if (optional)
message+=", or null";
{
message += ", or null";
}
return new InternalExpressionException(message);
}
@@ -59,14 +59,19 @@ public class FileArgument
private FileSystem zfs;
private Path zipPath;
public final static Object writeIOSync = new Object();
public static final Object writeIOSync = new Object();
public void close() {
if (zfs != null && zfs.isOpen()) {
try {
public void close()
{
if (zfs != null && zfs.isOpen())
{
try
{
zfs.close();
} catch (IOException e) {
throw new InternalExpressionException("Unable to close zip container: "+zipContainer);
}
catch (final IOException e)
{
throw new InternalExpressionException("Unable to close zip container: " + zipContainer);
}
zfs = null;
}
@@ -86,10 +91,10 @@ public class FileArgument
public static Map<String, Type> of = Arrays.stream(values()).collect(Collectors.toMap(t -> t.id, t -> t));
Type(String id, String extension)
Type(final String id, final String extension)
{
this.id = id;
this.extension = extension;
this.id = id;
this.extension = extension;
}
}
@@ -98,7 +103,7 @@ public class FileArgument
READ, CREATE, DELETE
}
public FileArgument(String resource, Type type, String zipContainer, boolean isFolder, boolean isShared, Reason reason)
public FileArgument(final String resource, final Type type, final String zipContainer, final boolean isFolder, final boolean isShared, final Reason reason)
{
this.resource = resource;
this.type = type;
@@ -111,48 +116,68 @@ public class FileArgument
}
@Override
public String toString() {
return "path: "+resource+" zip: "+zipContainer+" type: "+type.id+" folder: "+isFolder+" shared: "+isShared+" reason: "+reason.toString();
public String toString()
{
return "path: " + resource + " zip: " + zipContainer + " type: " + type.id + " folder: " + isFolder + " shared: " + isShared + " reason: " + reason.toString();
}
public static FileArgument from(List<Value> lv, boolean isFolder, Reason reason)
public static FileArgument from(final List<Value> lv, final boolean isFolder, final Reason reason)
{
if (lv.size() < 2) throw new InternalExpressionException("File functions require path and type as first two arguments");
String origtype = lv.get(1).getString().toLowerCase(Locale.ROOT);
boolean shared = origtype.startsWith("shared_");
String typeString = shared ? origtype.substring(7) : origtype; //len(shared_)
Type type = Type.of.get(typeString);
Pair<String, String> resource = recognizeResource(lv.get(0).getString(), isFolder, type);
if (type==null)
throw new InternalExpressionException("Unsupported file type: "+origtype);
if (type==Type.FOLDER && !isFolder)
if (lv.size() < 2)
{
throw new InternalExpressionException("File functions require path and type as first two arguments");
}
final String origtype = lv.get(1).getString().toLowerCase(Locale.ROOT);
final boolean shared = origtype.startsWith("shared_");
final String typeString = shared ? origtype.substring(7) : origtype; //len(shared_)
final Type type = Type.of.get(typeString);
final Pair<String, String> resource = recognizeResource(lv.get(0).getString(), isFolder, type);
if (type == null)
{
throw new InternalExpressionException("Unsupported file type: " + origtype);
}
if (type == Type.FOLDER && !isFolder)
{
throw new InternalExpressionException("Folder types are no supported for this IO function");
return new FileArgument(resource.getLeft(), type,resource.getRight(), isFolder, shared, reason);
}
return new FileArgument(resource.getLeft(), type, resource.getRight(), isFolder, shared, reason);
}
public static FileArgument resourceFromPath(String path, Reason reason, boolean shared)
public static FileArgument resourceFromPath(final String path, final Reason reason, final boolean shared)
{
Pair<String, String> resource = recognizeResource(path, false, Type.ANY);
return new FileArgument(resource.getLeft(), Type.ANY,resource.getRight(), false, shared, reason);
final Pair<String, String> resource = recognizeResource(path, false, Type.ANY);
return new FileArgument(resource.getLeft(), Type.ANY, resource.getRight(), false, shared, reason);
}
public static Pair<String,String> recognizeResource(String origfile, boolean isFolder, Type type)
public static Pair<String, String> recognizeResource(final String origfile, final boolean isFolder, final Type type)
{
String[] pathElements = origfile.split("[/\\\\]+");
List<String> path = new ArrayList<>();
final String[] pathElements = origfile.split("[/\\\\]+");
final List<String> path = new ArrayList<>();
String zipPath = null;
for (int i =0; i < pathElements.length; i++ )
for (int i = 0; i < pathElements.length; i++)
{
String token = pathElements[i];
boolean isZip = token.endsWith(".zip") && (isFolder || (i < pathElements.length-1));
if (zipPath != null && isZip) throw new InternalExpressionException(token+" indicates zip access in an already zipped location "+zipPath);
if (isZip) token = token.substring(0, token.length()-4);
token = (type==Type.ANY && i == pathElements.length-1)? // sloppy really, but should work
token.replaceAll("[^A-Za-z0-9\\-+_.]", ""):
final boolean isZip = token.endsWith(".zip") && (isFolder || (i < pathElements.length - 1));
if (zipPath != null && isZip)
{
throw new InternalExpressionException(token + " indicates zip access in an already zipped location " + zipPath);
}
if (isZip)
{
token = token.substring(0, token.length() - 4);
}
token = (type == Type.ANY && i == pathElements.length - 1) ? // sloppy really, but should work
token.replaceAll("[^A-Za-z0-9\\-+_.]", "") :
token.replaceAll("[^A-Za-z0-9\\-+_]", "");
if (token.isEmpty()) continue;
if (isZip) token = token + ".zip";
if (token.isEmpty())
{
continue;
}
if (isZip)
{
token = token + ".zip";
}
path.add(token);
if (isZip)
{
@@ -161,80 +186,106 @@ public class FileArgument
}
}
if (path.isEmpty() && !isFolder)
{
throw new InternalExpressionException(
"Cannot use "+origfile+" as resource name: indicated path is empty"+((zipPath==null)?"":" in zip container "+zipPath)
"Cannot use " + origfile + " as resource name: indicated path is empty" + ((zipPath == null) ? "" : " in zip container " + zipPath)
);
}
return Pair.of(String.join("/", path), zipPath);
}
private Path resolve(String suffix)
private Path resolve(final String suffix)
{
if (CarpetServer.minecraft_server == null)
{
throw new InternalExpressionException("Accessing world files without server running");
return CarpetServer.minecraft_server.getWorldPath(LevelResource.ROOT).resolve("scripts/"+suffix);
}
return CarpetServer.minecraft_server.getWorldPath(LevelResource.ROOT).resolve("scripts/" + suffix);
}
private Path toPath(Module module)
private Path toPath(final Module module)
{
if (!isShared && module == null) return null;
if (!isShared && module == null)
{
return null;
}
if (zipContainer == null)
return resolve(getDescriptor(module, resource)+(isFolder?"":type.extension));
{
return resolve(getDescriptor(module, resource) + (isFolder ? "" : type.extension));
}
else
{
if (zfs == null)
{
Map<String, String> env = new HashMap<>();
if (reason == Reason.CREATE) env.put("create", "true");
zipPath = resolve(getDescriptor(module, zipContainer));
if (!Files.exists(zipPath) && reason != Reason.CREATE) return null; // no zip file
try {
if (!Files.exists(zipPath.getParent())) Files.createDirectories(zipPath.getParent());
zfs = FileSystems.newFileSystem(URI.create("jar:"+ zipPath.toUri().toString()), env);
final Map<String, String> env = new HashMap<>();
if (reason == Reason.CREATE)
{
env.put("create", "true");
}
catch (FileSystemNotFoundException | IOException e)
zipPath = resolve(getDescriptor(module, zipContainer));
if (!Files.exists(zipPath) && reason != Reason.CREATE)
{
return null; // no zip file
}
try
{
if (!Files.exists(zipPath.getParent()))
{
Files.createDirectories(zipPath.getParent());
}
zfs = FileSystems.newFileSystem(URI.create("jar:" + zipPath.toUri()), env);
}
catch (final FileSystemNotFoundException | IOException e)
{
CarpetScriptServer.LOG.warn("Exception when opening zip file", e);
throw new ThrowStatement("Unable to open zip file: "+zipContainer, Throwables.IO_EXCEPTION);
throw new ThrowStatement("Unable to open zip file: " + zipContainer, Throwables.IO_EXCEPTION);
}
}
return zfs.getPath(resource+(isFolder?"/":type.extension));
return zfs.getPath(resource + (isFolder ? "/" : type.extension));
}
}
private Path moduleRootPath(Module module)
private Path moduleRootPath(final Module module)
{
if (!isShared && module == null) return null;
return resolve(isShared?"shared":module.name()+".data");
return !isShared && module == null
? null
: resolve(isShared ? "shared" : module.name() + ".data");
}
public String getDisplayPath()
{
return (isShared?"shared/":"")+(zipContainer!=null?zipContainer+"/":"")+resource+type.extension;
return (isShared ? "shared/" : "") + (zipContainer != null ? zipContainer + "/" : "") + resource + type.extension;
}
private String getDescriptor(Module module, String res)
private String getDescriptor(final Module module, final String res)
{
if (isShared)
{
return res.isEmpty()?"shared":"shared/"+res;
return res.isEmpty() ? "shared" : "shared/" + res;
}
if (module != null) // appdata
{
return module.name()+".data"+(res==null || res.isEmpty()?"":"/"+res);
return module.name() + ".data" + (res == null || res.isEmpty() ? "" : "/" + res);
}
throw new InternalExpressionException("Invalid file descriptor: "+res);
throw new InternalExpressionException("Invalid file descriptor: " + res);
}
public boolean findPathAndApply(Module module, Consumer<Path> action)
public boolean findPathAndApply(final Module module, final Consumer<Path> action)
{
try { synchronized (writeIOSync)
try
{
Path dataFile = toPath(module);//, resourceName, supportedTypes.get(type), isShared);
if (dataFile == null) return false;
createPaths(dataFile);
action.accept(dataFile);
} }
synchronized (writeIOSync)
{
final Path dataFile = toPath(module);//, resourceName, supportedTypes.get(type), isShared);
if (dataFile == null)
{
return false;
}
createPaths(dataFile);
action.accept(dataFile);
}
}
finally
{
close();
@@ -242,83 +293,109 @@ public class FileArgument
return true;
}
public Stream<Path> listFiles(Module module)
public Stream<Path> listFiles(final Module module)
{
Path dir = toPath(module);
if (dir == null || !Files.exists(dir)) return null;
String ext = type.extension;
final Path dir = toPath(module);
if (dir == null || !Files.exists(dir))
{
return null;
}
final String ext = type.extension;
try
{
return Files.list(dir).filter(path -> (type==Type.FOLDER)
?Files.isDirectory(path)
:(Files.isRegularFile(path) && path.toString().endsWith(ext))
return Files.list(dir).filter(path -> (type == Type.FOLDER)
? Files.isDirectory(path)
: (Files.isRegularFile(path) && path.toString().endsWith(ext))
);
}
catch (IOException ignored)
catch (final IOException ignored)
{
return null;
}
}
public Stream<String> listFolder(Module module)
public Stream<String> listFolder(final Module module)
{
Stream<String> strings;
try (Stream<Path> result = listFiles(module)) { synchronized (writeIOSync)
try (final Stream<Path> result = listFiles(module))
{
if (result == null) return null;
Path rootPath = moduleRootPath(module);
if (rootPath == null) return null;
String zipComponent = (zipContainer != null) ? rootPath.relativize(zipPath).toString() : null;
// need to evaluate the stream before exiting try-with-resources else there'll be no data to stream
strings = (zipContainer == null)
? result.map(p -> rootPath.relativize(p).toString().replaceAll("[\\\\/]+", "/")).toList().stream()
: result.map(p -> (zipComponent + '/'+ p.toString()).replaceAll("[\\\\/]+", "/")).toList().stream();
} }
synchronized (writeIOSync)
{
if (result == null)
{
return null;
}
final Path rootPath = moduleRootPath(module);
if (rootPath == null)
{
return null;
}
final String zipComponent = (zipContainer != null) ? rootPath.relativize(zipPath).toString() : null;
// need to evaluate the stream before exiting try-with-resources else there'll be no data to stream
strings = (zipContainer == null)
? result.map(p -> rootPath.relativize(p).toString().replaceAll("[\\\\/]+", "/")).toList().stream()
: result.map(p -> (zipComponent + '/' + p.toString()).replaceAll("[\\\\/]+", "/")).toList().stream();
}
}
finally
{
close();
}
if (type == Type.FOLDER)
// java 8 paths are inconsistent. in java 16 they all should not have trailing slashes
return strings.map(s -> s.endsWith("/")?s.substring(0, s.length()-1):s);
return strings.map(FilenameUtils::removeExtension);
// java 8 paths are inconsistent. in java 16 they all should not have trailing slashes
return type == Type.FOLDER
? strings.map(s -> s.endsWith("/") ? s.substring(0, s.length() - 1) : s)
: strings.map(FilenameUtils::removeExtension);
}
private void createPaths(Path file)
private void createPaths(final Path file)
{
try {
try
{
if ((zipContainer == null || file.getParent() != null) &&
!Files.exists(file.getParent()) &&
Files.createDirectories(file.getParent()) == null
) throw new IOException();
} catch (IOException e) {
)
{
throw new IOException();
}
}
catch (final IOException e)
{
CarpetScriptServer.LOG.warn("IOException when creating paths", e);
throw new ThrowStatement("Unable to create paths for "+file.toString(), Throwables.IO_EXCEPTION);
throw new ThrowStatement("Unable to create paths for " + file, Throwables.IO_EXCEPTION);
}
}
public boolean appendToTextFile(Module module, List<String> message)
public boolean appendToTextFile(final Module module, final List<String> message)
{
try { synchronized (writeIOSync)
try
{
Path dataFile = toPath(module);//, resourceName, supportedTypes.get(type), isShared);
if (dataFile == null) return false;
createPaths(dataFile);
OutputStream out = Files.newOutputStream(dataFile, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
synchronized (writeIOSync)
{
for (String line: message)
final Path dataFile = toPath(module);
if (dataFile == null)
{
writer.append(line);
if (type == Type.TEXT) writer.newLine();
return false;
}
createPaths(dataFile);
final OutputStream out = Files.newOutputStream(dataFile, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
{
for (final String line : message)
{
writer.append(line);
if (type == Type.TEXT)
{
writer.newLine();
}
}
}
}
} }
catch (IOException e)
}
catch (final IOException e)
{
CarpetScriptServer.LOG.warn("IOException when appending to text file", e);
throw new ThrowStatement("Error when writing to the file: "+e, Throwables.IO_EXCEPTION);
throw new ThrowStatement("Error when writing to the file: " + e, Throwables.IO_EXCEPTION);
}
finally
{
@@ -327,76 +404,91 @@ public class FileArgument
return true;
}
public Tag getNbtData(Module module) // aka getData
public Tag getNbtData(final Module module) // aka getData
{
try { synchronized (writeIOSync) {
Path dataFile = toPath(module);
if (dataFile == null || !Files.exists(dataFile)) return null;
return readTag(dataFile);
} }
finally {
try
{
synchronized (writeIOSync)
{
final Path dataFile = toPath(module);
if (dataFile == null || !Files.exists(dataFile))
{
return null;
}
return readTag(dataFile);
}
}
finally
{
close();
}
}
//copied private method from net.minecraft.nbt.NbtIo.read()
// to read non-compound tags - these won't be compressed
public static Tag readTag(Path path)
public static Tag readTag(final Path path)
{
try
{
return NbtIo.readCompressed(Files.newInputStream(path));
}
catch (IOException e)
catch (final IOException e)
{
// Copy of NbtIo.read(File) because that's now client-side only
if (!Files.exists(path))
{
return null;
}
try (DataInputStream in = new DataInputStream(new BufferedInputStream(Files.newInputStream(path))))
try (final DataInputStream in = new DataInputStream(new BufferedInputStream(Files.newInputStream(path))))
{
return NbtIo.read(in);
}
catch (IOException ioException)
catch (final IOException ioException)
{
// not compressed compound tag neither uncompressed compound tag - trying any type of a tag
try (DataInputStream dataInput_1 = new DataInputStream(new BufferedInputStream(Files.newInputStream(path))))
try (final DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(Files.newInputStream(path))))
{
byte byte_1 = dataInput_1.readByte();
if (byte_1 == 0)
final byte b = dataInputStream.readByte();
if (b == 0)
{
return null;
}
else
{
dataInput_1.readUTF();
return TagTypes.getType(byte_1).load(dataInput_1, 0, NbtAccounter.UNLIMITED);
dataInputStream.readUTF();
return TagTypes.getType(b).load(dataInputStream, 0, NbtAccounter.UNLIMITED);
}
}
catch (IOException secondIO)
catch (final IOException secondIO)
{
CarpetScriptServer.LOG.warn("IOException when trying to read nbt file, something may have gone wrong with the fs", e);
CarpetScriptServer.LOG.warn("", ioException);
CarpetScriptServer.LOG.warn("", secondIO);
throw new ThrowStatement("Not a valid NBT tag in "+path.toString(), Throwables.NBT_ERROR);
throw new ThrowStatement("Not a valid NBT tag in " + path, Throwables.NBT_ERROR);
}
}
}
catch (ReportedException e)
catch (final ReportedException e)
{
throw new ThrowStatement("Error when reading NBT file "+path.toString(), Throwables.NBT_ERROR);
throw new ThrowStatement("Error when reading NBT file " + path.toString(), Throwables.NBT_ERROR);
}
}
public boolean saveNbtData(Module module, Tag tag) // aka saveData
public boolean saveNbtData(final Module module, final Tag tag) // aka saveData
{
try { synchronized (writeIOSync) {
Path dataFile = toPath(module);
if (dataFile == null) return false;
createPaths(dataFile);
return writeTagDisk(tag, dataFile, zipContainer != null);
} }
try
{
synchronized (writeIOSync)
{
final Path dataFile = toPath(module);
if (dataFile == null)
{
return false;
}
createPaths(dataFile);
return writeTagDisk(tag, dataFile, zipContainer != null);
}
}
finally
{
close();
@@ -404,9 +496,9 @@ public class FileArgument
}
//copied private method from net.minecraft.nbt.NbtIo.write() and client method safe_write
public static boolean writeTagDisk(Tag tag_1, Path path, boolean zipped)
public static boolean writeTagDisk(final Tag tag, Path path, final boolean zipped)
{
Path original = path;
final Path original = path;
try
{
if (!zipped)
@@ -415,19 +507,19 @@ public class FileArgument
Files.deleteIfExists(path);
}
if (tag_1 instanceof CompoundTag)
if (tag instanceof final CompoundTag cTag)
{
NbtIo.writeCompressed((CompoundTag) tag_1, Files.newOutputStream(path));
NbtIo.writeCompressed(cTag, Files.newOutputStream(path));
}
else
{
try (DataOutputStream dataOutputStream_1 = new DataOutputStream(Files.newOutputStream(path)))
try (final DataOutputStream dataOutputStream = new DataOutputStream(Files.newOutputStream(path)))
{
dataOutputStream_1.writeByte(tag_1.getId());
if (tag_1.getId() != 0)
dataOutputStream.writeByte(tag.getId());
if (tag.getId() != 0)
{
dataOutputStream_1.writeUTF("");
tag_1.write(dataOutputStream_1);
dataOutputStream.writeUTF("");
tag.write(dataOutputStream);
}
}
}
@@ -438,26 +530,31 @@ public class FileArgument
}
return true;
}
catch (IOException e)
catch (final IOException e)
{
CarpetScriptServer.LOG.warn("IO Exception when writing nbt file", e);
throw new ThrowStatement("Unable to write tag to "+original.toString(), Throwables.IO_EXCEPTION);
throw new ThrowStatement("Unable to write tag to " + original, Throwables.IO_EXCEPTION);
}
}
public boolean dropExistingFile(Module module)
public boolean dropExistingFile(final Module module)
{
try { synchronized (writeIOSync)
try
{
Path dataFile = toPath(module);
if (dataFile == null) return false;
return Files.deleteIfExists(dataFile);
} }
catch (IOException e)
synchronized (writeIOSync)
{
final Path dataFile = toPath(module);
if (dataFile == null)
{
return false;
}
return Files.deleteIfExists(dataFile);
}
}
catch (final IOException e)
{
CarpetScriptServer.LOG.warn("IOException when removing file", e);
throw new ThrowStatement("Error while removing file: "+getDisplayPath(), Throwables.IO_EXCEPTION);
throw new ThrowStatement("Error while removing file: " + getDisplayPath(), Throwables.IO_EXCEPTION);
}
finally
{
@@ -465,69 +562,95 @@ public class FileArgument
}
}
public List<String> listFile(Module module)
public List<String> listFile(final Module module)
{
try { synchronized (writeIOSync) {
Path dataFile = toPath(module);
if (dataFile == null) return null;
if (!Files.exists(dataFile)) return null;
return listFileContent(dataFile);
} }
finally {
try
{
synchronized (writeIOSync)
{
final Path dataFile = toPath(module);
if (dataFile == null)
{
return null;
}
if (!Files.exists(dataFile))
{
return null;
}
return listFileContent(dataFile);
}
}
finally
{
close();
}
}
public static List<String> listFileContent(Path filePath)
public static List<String> listFileContent(final Path filePath)
{
try (BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8)) {
List<String> result = new ArrayList<>();
for (;;) {
String line = reader.readLine();
try (final BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8))
{
final List<String> result = new ArrayList<>();
for (; ; )
{
final String line = reader.readLine();
if (line == null)
{
break;
result.add(line.replaceAll("[\n\r]+",""));
}
result.add(line.replaceAll("[\n\r]+", ""));
}
return result;
}
catch (IOException e)
catch (final IOException e)
{
CarpetScriptServer.LOG.warn("IOException when reading text file", e);
throw new ThrowStatement("Failed to read text file "+filePath.toString(), Throwables.IO_EXCEPTION);
throw new ThrowStatement("Failed to read text file " + filePath, Throwables.IO_EXCEPTION);
}
}
public JsonElement readJsonFile(Module module) {
try { synchronized (writeIOSync) {
Path dataFile = toPath(module);
if (dataFile == null || !Files.exists(dataFile)) return null;
return readJsonContent(dataFile);
} }
finally {
public JsonElement readJsonFile(final Module module)
{
try
{
synchronized (writeIOSync)
{
final Path dataFile = toPath(module);
if (dataFile == null || !Files.exists(dataFile))
{
return null;
}
return readJsonContent(dataFile);
}
}
finally
{
close();
}
}
public static JsonElement readJsonContent(Path filePath)
public static JsonElement readJsonContent(final Path filePath)
{
try (BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8))
try (final BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8))
{
return JsonParser.parseReader(reader);
}
catch (JsonParseException e)
catch (final JsonParseException e)
{
Throwable exc = e;
if(e.getCause() != null)
if (e.getCause() != null)
{
exc = e.getCause();
}
throw new ThrowStatement(MapValue.wrap(Map.of(
StringValue.of("error"), StringValue.of(exc.getMessage()),
StringValue.of("path"), StringValue.of(filePath.toString())
)), Throwables.JSON_ERROR);
}
catch (IOException e)
catch (final IOException e)
{
CarpetScriptServer.LOG.warn("IOException when reading JSON file", e);
throw new ThrowStatement("Failed to read json file content "+filePath.toString(), Throwables.IO_EXCEPTION);
throw new ThrowStatement("Failed to read json file content " + filePath, Throwables.IO_EXCEPTION);
}
}
@@ -19,7 +19,7 @@ public class FunctionArgument extends Argument
public FunctionValue function;
public List<Value> args;
private FunctionArgument(FunctionValue function, int offset, List<Value> args)
private FunctionArgument(final FunctionValue function, final int offset, final List<Value> args)
{
super(offset);
this.function = function;
@@ -27,10 +27,10 @@ public class FunctionArgument extends Argument
}
/**
* @param c context
* @param module module
* @param params list of params
* @param offset offset where to start looking for functional argument
* @param c context
* @param module module
* @param params list of params
* @param offset offset where to start looking for functional argument
* @param allowNone none indicates no function present, otherwise it will croak
* @param checkArgs whether the caller expects trailing parameters to fully resolve function argument list
* if not - argument count check will not be performed and its up to the caller to verify
@@ -38,63 +38,85 @@ public class FunctionArgument extends Argument
* @return argument data
*/
public static FunctionArgument findIn(
Context c,
Module module,
List<Value> params,
int offset,
boolean allowNone,
boolean checkArgs)
final Context c,
final Module module,
final List<Value> params,
final int offset,
final boolean allowNone,
final boolean checkArgs)
{
Value functionValue = params.get(offset);
if (functionValue.isNull())
{
if (allowNone) return new FunctionArgument(null, offset+1, Collections.emptyList());
if (allowNone)
{
return new FunctionArgument(null, offset + 1, Collections.emptyList());
}
throw new InternalExpressionException("function argument cannot be null");
}
if (!(functionValue instanceof FunctionValue))
{
String name = functionValue.getString();
final String name = functionValue.getString();
functionValue = c.host.getAssertFunction(module, name);
}
FunctionValue fun = (FunctionValue)functionValue;
int argsize = fun.getArguments().size();
final FunctionValue fun = (FunctionValue) functionValue;
final int argsize = fun.getArguments().size();
if (checkArgs)
{
int extraargs = params.size() - argsize - offset - 1;
final int extraargs = params.size() - argsize - offset - 1;
if (extraargs < 0)
{
throw new InternalExpressionException("Function " + fun.getPrettyString() + " requires at least " + fun.getArguments().size() + " arguments");
}
if (extraargs > 0 && fun.getVarArgs() == null)
{
throw new InternalExpressionException("Function " + fun.getPrettyString() + " requires " + fun.getArguments().size() + " arguments");
}
}
final List<Value> lvargs = new ArrayList<>();
for (int i = offset + 1, mx = params.size(); i < mx; i++)
{
lvargs.add(params.get(i));
}
List<Value> lvargs = new ArrayList<>();
for (int i = offset+1, mx = params.size(); i < mx; i++) lvargs.add(params.get(i));
return new FunctionArgument(fun, offset + 1 + argsize, lvargs);
}
public static FunctionArgument fromCommandSpec(ScriptHost host, Value funSpec) throws CommandSyntaxException {
FunctionValue function;
public static FunctionArgument fromCommandSpec(final ScriptHost host, Value funSpec) throws CommandSyntaxException
{
final FunctionValue function;
List<Value> args = Collections.emptyList();
if (!(funSpec instanceof ListValue))
{
funSpec = ListValue.of(funSpec);
List<Value> params = ((ListValue) funSpec).getItems();
if (params.isEmpty()) throw CommandArgument.error("Function has empty spec");
Value first = params.get(0);
}
final List<Value> params = ((ListValue) funSpec).getItems();
if (params.isEmpty())
{
throw CommandArgument.error("Function has empty spec");
}
final Value first = params.get(0);
if (first instanceof FunctionValue)
{
function = (FunctionValue)first;
function = (FunctionValue) first;
}
else
{
String name = first.getString();
final String name = first.getString();
function = host.getFunction(name);
if (function == null) throw CommandArgument.error("Function "+name+" is not defined yet");
if (function == null)
{
throw CommandArgument.error("Function " + name + " is not defined yet");
}
}
if (params.size() > 1)
{
args = params.subList(1, params.size());
}
if (params.size() > 1) args = params.subList(1,params.size());
return new FunctionArgument(function, 0, args);
}
public List<Value> checkedArgs() {
public List<Value> checkedArgs()
{
function.checkArgs(args.size());
return args;
}
@@ -6,9 +6,11 @@ import carpet.script.value.EntityValue;
import carpet.script.value.ListValue;
import carpet.script.value.NumericValue;
import carpet.script.value.Value;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.Vec3;
@@ -19,14 +21,16 @@ public class Vector3Argument extends Argument
public final double pitch;
public boolean fromBlock = false;
public Entity entity = null;
private Vector3Argument(Vec3 v, int o)
private Vector3Argument(final Vec3 v, final int o)
{
super(o);
this.vec = v;
this.yaw = 0.0D;
this.pitch = 0.0D;
}
private Vector3Argument(Vec3 v, int o, double y, double p)
private Vector3Argument(final Vec3 v, final int o, final double y, final double p)
{
super(o);
this.vec = v;
@@ -40,52 +44,53 @@ public class Vector3Argument extends Argument
return this;
}
private Vector3Argument withEntity(Entity e)
private Vector3Argument withEntity(final Entity e)
{
entity = e;
return this;
}
public static Vector3Argument findIn(List<Value> params, int offset)
public static Vector3Argument findIn(final List<Value> params, final int offset)
{
return findIn(params, offset, false, false);
}
public static Vector3Argument findIn(List<Value> params, int offset, boolean optionalDirection, boolean optionalEntity) {
public static Vector3Argument findIn(final List<Value> params, final int offset, final boolean optionalDirection, final boolean optionalEntity)
{
return findIn(params.listIterator(offset), offset, optionalDirection, optionalEntity);
}
public static Vector3Argument findIn(Iterator<Value> params, int offset, boolean optionalDirection, boolean optionalEntity)
public static Vector3Argument findIn(final Iterator<Value> params, final int offset, final boolean optionalDirection, final boolean optionalEntity)
{
try
{
Value v1 = params.next();
final Value v1 = params.next();
if (v1 instanceof BlockValue)
{
return (new Vector3Argument(Vec3.atCenterOf(((BlockValue) v1).getPos()), 1+offset)).fromBlock();
return (new Vector3Argument(Vec3.atCenterOf(((BlockValue) v1).getPos()), 1 + offset)).fromBlock();
}
if (optionalEntity && v1 instanceof EntityValue)
{
Entity e = ((EntityValue) v1).getEntity();
return new Vector3Argument(e.position(), 1+offset).withEntity(e);
final Entity e = ((EntityValue) v1).getEntity();
return new Vector3Argument(e.position(), 1 + offset).withEntity(e);
}
if (v1 instanceof ListValue)
{
List<Value> args = ((ListValue) v1).getItems();
Vec3 pos = new Vec3(
final List<Value> args = ((ListValue) v1).getItems();
final Vec3 pos = new Vec3(
NumericValue.asNumber(args.get(0)).getDouble(),
NumericValue.asNumber(args.get(1)).getDouble(),
NumericValue.asNumber(args.get(2)).getDouble());
double yaw = 0.0D;
double pitch = 0.0D;
if (args.size()>3 && optionalDirection)
if (args.size() > 3 && optionalDirection)
{
yaw = NumericValue.asNumber(args.get(3)).getDouble();
pitch = NumericValue.asNumber(args.get(4)).getDouble();
}
return new Vector3Argument(pos,offset+1, yaw, pitch);
return new Vector3Argument(pos, offset + 1, yaw, pitch);
}
Vec3 pos = new Vec3(
final Vec3 pos = new Vec3(
NumericValue.asNumber(v1).getDouble(),
NumericValue.asNumber(params.next()).getDouble(),
NumericValue.asNumber(params.next()).getDouble());
@@ -99,9 +104,9 @@ public class Vector3Argument extends Argument
eatenLength = 5;
}
return new Vector3Argument(pos, offset+eatenLength, yaw, pitch);
return new Vector3Argument(pos, offset + eatenLength, yaw, pitch);
}
catch (IndexOutOfBoundsException | NoSuchElementException e)
catch (final IndexOutOfBoundsException | NoSuchElementException e)
{
throw new InternalExpressionException("Position argument should be defined either by three coordinates (a triple or by three arguments), or a positioned block value");
}