Merge branch 'master' into 1.17
This commit is contained in:
commit
9d08c54324
13 files changed
+210
-108
No files matched your search
+23
-21
@@ -3170,6 +3170,11 @@ Player's ping in milliseconds, or `null` if its not a player.
|
||||
|
||||
Player's permission level, or `null` if not applicable for this entity.
|
||||
|
||||
### `query(e, 'client_brand')`
|
||||
|
||||
Returns recognized type of client of the client connected. Possible results include `'vanilla'`, or `'carpet <version>'` where
|
||||
version indicates the version of the connected carpet client.
|
||||
|
||||
### `query(e, 'effect', name?)`
|
||||
|
||||
Without extra arguments, it returns list of effect active on a living entity. Each entry is a triple of short
|
||||
@@ -4566,13 +4571,15 @@ Available output types:
|
||||
### `read_file(resource, type)`
|
||||
### `delete_file(resource, type)`
|
||||
### `write_file(resource, type, data, ...)`
|
||||
### `list_files(resource, type)`
|
||||
|
||||
With the specified `resource` in the scripts folder, of a specific `type`, writes/appends `data` to it, reads its
|
||||
content, or deletes the resource.
|
||||
content, deletes the resource, or lists other files under this resource.
|
||||
|
||||
Resource is identified by a path to the file.
|
||||
A path can contain letters, numbers, characters `-`, `+`, or `_`, and a folder separator: `'/'`. Any other characters are stripped
|
||||
from the name. Empty descriptors are invalid. Do not add file extensions to the descriptor - extensions are inferred
|
||||
from the name. Empty descriptors are invalid, except for `list_files` where it means the root folder.
|
||||
Do not add file extensions to the descriptor - extensions are inferred
|
||||
based on the `type` of the file.
|
||||
|
||||
Resources can be located in the app specific space, or a shared space for all the apps. Accessing of app-specific
|
||||
@@ -4587,33 +4594,26 @@ specific data directory is under `world/scripts/foo.data/...`, and shared data s
|
||||
|
||||
The default no-name app, via `/script run` command can only save/load/read files from the shared space.
|
||||
|
||||
Functions return `null` if an error is encounter or no file is present (for read and delete operations). Returns `true`
|
||||
for success writes and deletes, and requested data, based on the file type, for read operations.
|
||||
Functions return `null` if an error is encounter or no file is present (for read, list and delete operations). Returns `true`
|
||||
for success writes and deletes, and requested data, based on the file type, for read operations. It returns list of files
|
||||
for folder listing.
|
||||
|
||||
NBT files can be written once as they an store one tag at a time. Consecutive writes will overwrite previous data.
|
||||
|
||||
Write operations to text files always result in appending to the existing file, so consecutive writes will increase
|
||||
the size of the file and add data to it. Since files are closed after each write, sending multiple lines of data to
|
||||
write is beneficial for writing speed. To send multiple packs of data, either provide them flat or as a list in the
|
||||
third argument.
|
||||
* `write_file('temp', 'text', 'foo', 'bar', 'baz')` or
|
||||
* write_file('temp', 'text', l('foo', 'bar', 'baz'))
|
||||
|
||||
To log a single line of string
|
||||
|
||||
Supported values for resource `type` is:
|
||||
Supported values for resource `type` are:
|
||||
* `nbt` - NBT tag
|
||||
* `text` - text resource with automatic newlines added
|
||||
* `raw` - text resource without implied newlines
|
||||
* `shared_nbt`, `shared_text`, `shared_raw` - shared versions of the above
|
||||
* `folder` - for `list_files` only - indicting folder listing instead of files
|
||||
* `shared_nbt`, `shared_text`, `shared_raw`, `shared_folder` - shared versions of the above
|
||||
|
||||
NBT files have extension `.nbt`, store one NBT tag, and return a NBT type value. Text files have `.txt` extension,
|
||||
stores multiple lines of text and returns lists of all lines from the file. With `write_file`, multiple lines can be
|
||||
sent to the file at once. The only difference between `raw` and `text` types are automatic newlines added after each
|
||||
record to the file.
|
||||
record to the file. Since files are closed after each write, sending multiple lines of data to
|
||||
write is beneficial for writing speed. To send multiple packs of data, either provide them flat or as a list in the
|
||||
third argument.
|
||||
|
||||
<pre>
|
||||
write_file('foo', 'shared_text, l('one', 'two'));
|
||||
write_file('foo', 'shared_text, ['one', 'two']);
|
||||
write_file('foo', 'shared_text', 'three\n', 'four\n');
|
||||
write_file('foo', 'shared_raw', 'five\n', 'six\n');
|
||||
|
||||
@@ -4791,7 +4791,6 @@ Available options in the scarpet app space:
|
||||
* `game_version` - base version of the game
|
||||
|
||||
Server related properties
|
||||
|
||||
* `server_motd` - the motd of the server visible when joining
|
||||
* `server_ip` - IP adress of the game hosted
|
||||
* `server_whitelisted` - boolean indicating whether the access to the server is only for whitelisted players
|
||||
@@ -4807,7 +4806,10 @@ Available options in the scarpet app space:
|
||||
* `java_version` - version of Java
|
||||
* `java_bits` - number indicating how many bits the Java has, 32 or 64
|
||||
* `java_system_cpu_load` - current percentage of CPU used by the system
|
||||
* `java_process_cpu_load` - current percentage of CPU used by JVM# `/script run` command
|
||||
* `java_process_cpu_load` - current percentage of CPU used by JVM
|
||||
|
||||
Scarpet related properties
|
||||
* `scarpet_version` - returns the version of the carpet your scarpet comes with.# `/script run` command
|
||||
|
||||
Primary way to input commands. The command executes in the context, position, and dimension of the executing player,
|
||||
commandblock, etc... The command receives 4 variables, `x`, `y`, `z` and `p` indicating position and
|
||||
|
||||
@@ -275,13 +275,15 @@ Available output types:
|
||||
### `read_file(resource, type)`
|
||||
### `delete_file(resource, type)`
|
||||
### `write_file(resource, type, data, ...)`
|
||||
### `list_files(resource, type)`
|
||||
|
||||
With the specified `resource` in the scripts folder, of a specific `type`, writes/appends `data` to it, reads its
|
||||
content, or deletes the resource.
|
||||
content, deletes the resource, or lists other files under this resource.
|
||||
|
||||
Resource is identified by a path to the file.
|
||||
A path can contain letters, numbers, characters `-`, `+`, or `_`, and a folder separator: `'/'`. Any other characters are stripped
|
||||
from the name. Empty descriptors are invalid. Do not add file extensions to the descriptor - extensions are inferred
|
||||
from the name. Empty descriptors are invalid, except for `list_files` where it means the root folder.
|
||||
Do not add file extensions to the descriptor - extensions are inferred
|
||||
based on the `type` of the file.
|
||||
|
||||
Resources can be located in the app specific space, or a shared space for all the apps. Accessing of app-specific
|
||||
@@ -296,33 +298,26 @@ specific data directory is under `world/scripts/foo.data/...`, and shared data s
|
||||
|
||||
The default no-name app, via `/script run` command can only save/load/read files from the shared space.
|
||||
|
||||
Functions return `null` if an error is encounter or no file is present (for read and delete operations). Returns `true`
|
||||
for success writes and deletes, and requested data, based on the file type, for read operations.
|
||||
Functions return `null` if an error is encounter or no file is present (for read, list and delete operations). Returns `true`
|
||||
for success writes and deletes, and requested data, based on the file type, for read operations. It returns list of files
|
||||
for folder listing.
|
||||
|
||||
NBT files can be written once as they an store one tag at a time. Consecutive writes will overwrite previous data.
|
||||
|
||||
Write operations to text files always result in appending to the existing file, so consecutive writes will increase
|
||||
the size of the file and add data to it. Since files are closed after each write, sending multiple lines of data to
|
||||
write is beneficial for writing speed. To send multiple packs of data, either provide them flat or as a list in the
|
||||
third argument.
|
||||
* `write_file('temp', 'text', 'foo', 'bar', 'baz')` or
|
||||
* write_file('temp', 'text', l('foo', 'bar', 'baz'))
|
||||
|
||||
To log a single line of string
|
||||
|
||||
Supported values for resource `type` is:
|
||||
Supported values for resource `type` are:
|
||||
* `nbt` - NBT tag
|
||||
* `text` - text resource with automatic newlines added
|
||||
* `raw` - text resource without implied newlines
|
||||
* `shared_nbt`, `shared_text`, `shared_raw` - shared versions of the above
|
||||
* `folder` - for `list_files` only - indicting folder listing instead of files
|
||||
* `shared_nbt`, `shared_text`, `shared_raw`, `shared_folder` - shared versions of the above
|
||||
|
||||
NBT files have extension `.nbt`, store one NBT tag, and return a NBT type value. Text files have `.txt` extension,
|
||||
stores multiple lines of text and returns lists of all lines from the file. With `write_file`, multiple lines can be
|
||||
sent to the file at once. The only difference between `raw` and `text` types are automatic newlines added after each
|
||||
record to the file.
|
||||
record to the file. Since files are closed after each write, sending multiple lines of data to
|
||||
write is beneficial for writing speed. To send multiple packs of data, either provide them flat or as a list in the
|
||||
third argument.
|
||||
|
||||
<pre>
|
||||
write_file('foo', 'shared_text, l('one', 'two'));
|
||||
write_file('foo', 'shared_text, ['one', 'two']);
|
||||
write_file('foo', 'shared_text', 'three\n', 'four\n');
|
||||
write_file('foo', 'shared_raw', 'five\n', 'six\n');
|
||||
|
||||
@@ -500,7 +495,6 @@ Available options in the scarpet app space:
|
||||
* `game_version` - base version of the game
|
||||
|
||||
Server related properties
|
||||
|
||||
* `server_motd` - the motd of the server visible when joining
|
||||
* `server_ip` - IP adress of the game hosted
|
||||
* `server_whitelisted` - boolean indicating whether the access to the server is only for whitelisted players
|
||||
@@ -517,3 +511,6 @@ Available options in the scarpet app space:
|
||||
* `java_bits` - number indicating how many bits the Java has, 32 or 64
|
||||
* `java_system_cpu_load` - current percentage of CPU used by the system
|
||||
* `java_process_cpu_load` - current percentage of CPU used by JVM
|
||||
|
||||
Scarpet related properties
|
||||
* `scarpet_version` - returns the version of the carpet your scarpet comes with.
|
||||
@@ -366,6 +366,11 @@ Player's ping in milliseconds, or `null` if its not a player.
|
||||
|
||||
Player's permission level, or `null` if not applicable for this entity.
|
||||
|
||||
### `query(e, 'client_brand')`
|
||||
|
||||
Returns recognized type of client of the client connected. Possible results include `'vanilla'`, or `'carpet <version>'` where
|
||||
version indicates the version of the connected carpet client.
|
||||
|
||||
### `query(e, 'effect', name?)`
|
||||
|
||||
Without extra arguments, it returns list of effect active on a living entity. Each entry is a triple of short
|
||||
|
||||
@@ -55,6 +55,7 @@ item_category
|
||||
last_tick_times
|
||||
light
|
||||
liquid
|
||||
list_files
|
||||
load_app_data
|
||||
loaded
|
||||
loaded_status
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
plop harvest destroy schedule nbt draw_shape create_marker remove_all_markers
|
||||
|
||||
load_app_data store_app_data read_file write_file delete_file
|
||||
load_app_data store_app_data read_file write_file delete_file list_files
|
||||
escape_nbt parse_nbt encode_nbt tag_matches statistic
|
||||
</Keywords>
|
||||
<Keywords name="Keywords3">euler pi null true false</Keywords>
|
||||
|
||||
@@ -217,6 +217,13 @@ public class ServerNetworkHandler
|
||||
|
||||
}
|
||||
|
||||
public static String getPlayerStatus(ServerPlayerEntity player)
|
||||
{
|
||||
if (remoteCarpetPlayers.containsKey(player)) return "carpet "+remoteCarpetPlayers.get(player);
|
||||
if (validCarpetPlayers.contains(player)) return "carpet "+CarpetSettings.carpetVersion;
|
||||
return "vanilla";
|
||||
}
|
||||
|
||||
private static class DataBuilder
|
||||
{
|
||||
private CompoundTag tag;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,19 +88,39 @@ 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)
|
||||
public static String recognizeResource(Value value, boolean isFloder)
|
||||
{
|
||||
String origfile = value.getString();
|
||||
String file = origfile.toLowerCase(Locale.ROOT).replaceAll("[^A-Za-z0-9\\-+_/]", "");
|
||||
file = Arrays.stream(file.split("/+")).filter(s -> !s.isEmpty()).collect(Collectors.joining("/"));
|
||||
if (file.isEmpty())
|
||||
if (file.isEmpty() && !isFloder)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot use "+origfile+" as resource name - must have some letters and numbers");
|
||||
}
|
||||
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));
|
||||
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);
|
||||
Value retVal;
|
||||
if (type.equals("nbt"))
|
||||
expression.addLazyFunction("list_files", 2, (c, t, lv) ->
|
||||
{
|
||||
Tag state = ((CarpetScriptHost)((CarpetContext)c).host).readFileTag(resource, shared);
|
||||
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 (fdesc.getMiddle().equals("nbt"))
|
||||
{
|
||||
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));
|
||||
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));
|
||||
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;
|
||||
});
|
||||
@@ -874,7 +894,7 @@ public class Auxiliary {
|
||||
if (lv.size()>0)
|
||||
{
|
||||
c.host.issueDeprecation("load_app_data(...) with arguments");
|
||||
file = recognizeResource(lv.get(0).evalValue(c));
|
||||
file = recognizeResource(lv.get(0).evalValue(c), false);
|
||||
if (lv.size() > 1)
|
||||
{
|
||||
shared = lv.get(1).evalValue(c).getBoolean();
|
||||
@@ -897,7 +917,7 @@ public class Auxiliary {
|
||||
if (lv.size()>1)
|
||||
{
|
||||
c.host.issueDeprecation("store_app_data(...) with more than one argument");
|
||||
file = recognizeResource(lv.get(1).evalValue(c));
|
||||
file = recognizeResource(lv.get(1).evalValue(c), false);
|
||||
if (lv.size() > 2)
|
||||
{
|
||||
shared = lv.get(2).evalValue(c).getBoolean();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package carpet.script.bundled;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.PositionTracker;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.nbt.TagReaders;
|
||||
@@ -21,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
|
||||
{
|
||||
@@ -60,7 +63,20 @@ public class FileModule extends Module
|
||||
}
|
||||
|
||||
//copied private method from net.minecraft.nbt.NbtIo.read()
|
||||
// to read non-compound tags - these won't be compressed
|
||||
public static Tag read(File file)
|
||||
{
|
||||
try
|
||||
{
|
||||
return NbtIo.readCompressed(file);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
try
|
||||
{
|
||||
return NbtIo.read(file);
|
||||
}
|
||||
catch (IOException ioException)
|
||||
{
|
||||
try (DataInputStream dataInput_1 = new DataInputStream(new FileInputStream(file)))
|
||||
{
|
||||
@@ -80,6 +96,8 @@ public class FileModule extends Module
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//copied private method from net.minecraft.nbt.NbtIo.write() and client method safe_write
|
||||
public static boolean write(Tag tag_1, File file)
|
||||
@@ -87,6 +105,19 @@ public class FileModule extends Module
|
||||
File file_2 = new File(file.getAbsolutePath() + "_tmp");
|
||||
if (file_2.exists()) file_2.delete();
|
||||
|
||||
if (tag_1 instanceof CompoundTag)
|
||||
{
|
||||
try
|
||||
{
|
||||
NbtIo.writeCompressed((CompoundTag) tag_1, file_2);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try (DataOutputStream dataOutputStream_1 = new DataOutputStream(new FileOutputStream(file_2)))
|
||||
{
|
||||
dataOutputStream_1.writeByte(tag_1.getType());
|
||||
@@ -100,6 +131,7 @@ public class FileModule extends Module
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (file.exists()) file.delete();
|
||||
if (!file.exists()) file_2.renameTo(file);
|
||||
return true;
|
||||
@@ -144,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
return module.getName()+".data"+(file==null || file.isEmpty()?"":"/"+file);
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package carpet.script.utils;
|
||||
|
||||
import carpet.CarpetServer;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.script.CarpetContext;
|
||||
import carpet.script.CarpetScriptHost;
|
||||
import carpet.script.value.ListValue;
|
||||
@@ -123,14 +124,7 @@ public class SystemInfo {
|
||||
});
|
||||
return carpetRules;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
put("scarpet_version", c -> StringValue.of(CarpetSettings.carpetVersion));
|
||||
|
||||
}};
|
||||
public static Value get(String what, CarpetContext cc)
|
||||
|
||||
@@ -9,6 +9,7 @@ import carpet.fakes.MobEntityInterface;
|
||||
import carpet.fakes.HungerManagerInterface;
|
||||
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
||||
import carpet.helpers.Tracer;
|
||||
import carpet.network.ServerNetworkHandler;
|
||||
import carpet.patches.EntityPlayerMPFake;
|
||||
import carpet.script.CarpetContext;
|
||||
import carpet.script.EntityEventsGroup;
|
||||
@@ -594,6 +595,14 @@ public class EntityValue extends Value
|
||||
return Value.NULL;
|
||||
});
|
||||
|
||||
put("client_brand", (e, a) -> {
|
||||
if (e instanceof ServerPlayerEntity)
|
||||
{
|
||||
return StringValue.of(ServerNetworkHandler.getPlayerStatus((ServerPlayerEntity) e));
|
||||
}
|
||||
return Value.NULL;
|
||||
});
|
||||
|
||||
put("team", (e, a) -> e.getScoreboardTeam()==null?Value.NULL:new StringValue(e.getScoreboardTeam().getName()));
|
||||
|
||||
put("ping", (e, a) -> {
|
||||
|
||||
Reference in new issue
Block a user