Merge branch 'master' into 1.17

This commit is contained in:
gnembon committed 2021-01-07 00:41:15 -04:00
commit ed4afa15ff
49 files changed
+593 -211

No files matched your search

@@ -2,6 +2,7 @@ package carpet.script;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.helpers.TickSpeed;
import carpet.script.exception.InternalExpressionException;
import carpet.script.value.BlockValue;
import carpet.script.value.EntityValue;
@@ -973,6 +974,8 @@ public class CarpetEventServer
public void tick()
{
if (!TickSpeed.process_entities)
return;
Iterator<ScheduledCall> eventIterator = scheduledCalls.iterator();
List<ScheduledCall> currentCalls = new ArrayList<>();
while(eventIterator.hasNext())
@@ -18,6 +18,8 @@ import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.utils.Messenger;
import com.google.gson.JsonElement;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
@@ -705,7 +707,7 @@ public class CarpetScriptHost extends ScriptHost
public boolean removeResourceFile(String resource, boolean isShared, String type)
{
if (getName() == null && !isShared) return false; //
return Module.dropExistingFile(main, resource, type.equals("nbt")?"nbt":"txt", isShared);
return Module.dropExistingFile(main, resource, type, isShared);
}
public boolean appendLogFile(String resource, boolean isShared, String type, List<String> data)
@@ -714,16 +716,22 @@ public class CarpetScriptHost extends ScriptHost
return Module.appendToTextFile(main, resource, type, isShared, data);
}
public List<String> readTextResource(String resource, boolean isShared)
public List<String> readTextResource(String resource, String type, boolean isShared)
{
if (getName() == null && !isShared) return null; //
return Module.listFile(main, resource, "txt", isShared);
if (getName() == null && !isShared) return null;
return Module.listFile(main, resource, type, isShared);
}
public JsonElement readJsonFile(String resource, String type, boolean isShared)
{
if (getName() == null && !isShared) return null;
return Module.readJsonFile(main, resource, type, isShared);
}
public Stream<String> listFolder(String resource, String ext, boolean isShared)
public Stream<String> listFolder(String resource, String type, boolean isShared)
{
if (getName() == null && !isShared) return null; //
return Module.listFolder(main, resource, ext, isShared);
return Module.listFolder(main, resource, type, isShared);
}
+1 -1
View File
@@ -91,7 +91,7 @@ public abstract class ScriptHost
protected ScriptHost parent;
protected boolean perUser;
protected String user;
public String user;
public String getName() {return main ==null?null: main.getName();}
+38 -11
View File
@@ -6,6 +6,7 @@ import carpet.fakes.MinecraftServerInterface;
import carpet.fakes.StatTypeInterface;
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
import carpet.helpers.FeatureGenerator;
import carpet.script.bundled.Module;
import carpet.script.CarpetContext;
import carpet.script.CarpetEventServer;
import carpet.script.CarpetScriptHost;
@@ -19,6 +20,7 @@ import carpet.script.argument.Vector3Argument;
import carpet.script.exception.ExitStatement;
import carpet.script.exception.InternalExpressionException;
import carpet.script.utils.FixedCommandSource;
import carpet.script.utils.ScarpetJsonDeserializer;
import carpet.script.utils.ShapeDispatcher;
import carpet.script.utils.WorldTools;
import carpet.script.value.EntityValue;
@@ -33,7 +35,6 @@ 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.entity.Entity;
import net.minecraft.entity.EntityType;
@@ -69,6 +70,11 @@ import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -86,12 +92,7 @@ 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 final Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().registerTypeAdapter(Value.class, new ScarpetJsonDeserializer()).create();
public static String recognizeResource(Value value, boolean isFloder)
{
@@ -112,7 +113,7 @@ public class Auxiliary {
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))
if (!Module.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");
@@ -526,7 +527,7 @@ public class Auxiliary {
Text title = null;
if (lv.size() > 2)
{
pVal = lv.get(2).evalValue(c);
pVal = lv.get(2).evalValue(c);
if (pVal instanceof FormattedTextValue)
title = ((FormattedTextValue) pVal).getText();
else
@@ -803,7 +804,7 @@ public class Auxiliary {
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());
Stream<String> files = ((CarpetScriptHost) c.host).listFolder(fdesc.getLeft(), 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;
@@ -820,9 +821,29 @@ public class Auxiliary {
if (state == null) return LazyValue.NULL;
retVal = new NBTSerializableValue(state);
}
else if (fdesc.getMiddle().equals("json"))
{
JsonElement json;
try
{
json = ((CarpetScriptHost) c.host).readJsonFile(fdesc.getLeft(), fdesc.getMiddle(), fdesc.getRight());
}
catch (JsonParseException e)
{
Throwable exception = e;
if(e.getCause() != null)
exception = e.getCause();
throw new InternalExpressionException("Failed to read JSON file: "+exception.getMessage());
}
Value parsedJson = gson.fromJson(json, Value.class);
if (parsedJson == null)
retVal = Value.NULL;
else
retVal = parsedJson;
}
else
{
List<String> content = ((CarpetScriptHost) c.host).readTextResource(fdesc.getLeft(), fdesc.getRight());
List<String> content = ((CarpetScriptHost) c.host).readTextResource(fdesc.getLeft(), fdesc.getMiddle(), fdesc.getRight());
if (content == null) return LazyValue.NULL;
retVal = ListValue.wrap(content.stream().map(StringValue::new).collect(Collectors.toList()));
}
@@ -851,6 +872,12 @@ public class Auxiliary {
Tag tag = tagValue.getTag();
success = ((CarpetScriptHost) c.host).writeTagFile(tag, fdesc.getLeft(), fdesc.getRight());
}
else if (fdesc.getMiddle().equals("json"))
{
List<String> data = Collections.singletonList(gson.toJson(lv.get(2).evalValue(c).toJson()));
((CarpetScriptHost) c.host).removeResourceFile(fdesc.getLeft(), fdesc.getRight(), fdesc.getMiddle());
success = ((CarpetScriptHost) c.host).appendLogFile(fdesc.getLeft(), fdesc.getRight(), fdesc.getMiddle(), data);
}
else
{
List<String> data = new ArrayList<>();
+11 -4
View File
@@ -45,10 +45,17 @@ public class Entities {
{
expression.addLazyFunction("player", -1, (c, t, lv) ->
{
if (lv.size() ==0)
if (lv.size() == 0)
{
Entity callingEntity = ((CarpetContext)c).s.getEntity();
CarpetContext cc = (CarpetContext)c;
if (cc.host.user != null)
{
ServerPlayerEntity player = cc.s.getMinecraftServer().getPlayerManager().getPlayer(cc.host.user);
if (player == null) return LazyValue.NULL;
Value ret = new EntityValue(player);
return (_c, _t) -> ret;
}
Entity callingEntity = cc.s.getEntity();
if (callingEntity instanceof PlayerEntity)
{
Value retval = new EntityValue(callingEntity);
@@ -108,7 +115,7 @@ public class Entities {
retval = new EntityValue(player);
}
Value finalVar = retval;
return (cc, tt) -> finalVar;
return (_c, _t) -> finalVar;
});
expression.addLazyFunction("spawn", -1, (c, t, lv) ->
@@ -1,5 +1,7 @@
package carpet.script.api;
import carpet.mixins.ScoreboardObjective_scarpetMixin;
import carpet.mixins.Scoreboard_scarpetMixin;
import carpet.script.CarpetContext;
import carpet.script.Expression;
import carpet.script.LazyValue;
@@ -11,6 +13,7 @@ import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.FormattedTextValue;
import carpet.script.value.Value;
import com.google.common.collect.Lists;
import net.minecraft.entity.Entity;
import net.minecraft.entity.boss.BossBar;
import net.minecraft.entity.boss.BossBarManager;
@@ -133,8 +136,15 @@ public class Scoreboards {
}
ScoreboardObjective objective = scoreboard.getObjective(objectiveName);
if (objective != null)
if (objective != null) {
if(lv.size() == 1) return (_c, _t) -> StringValue.of(objective.getCriterion().getName());
if(objective.getCriterion().equals(criterion) || lv.size() == 1) return LazyValue.NULL;
((Scoreboard_scarpetMixin)scoreboard).getObjectivesByCriterion().get(objective.getCriterion()).remove(objective);
((ScoreboardObjective_scarpetMixin) objective).setCriterion(criterion);
(((Scoreboard_scarpetMixin)scoreboard).getObjectivesByCriterion().computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
scoreboard.updateObjective(objective);
return LazyValue.FALSE;
}
scoreboard.addObjective(objectiveName, criterion, new LiteralText(objectiveName), criterion.getDefaultRenderType());
return LazyValue.TRUE;
@@ -25,6 +25,10 @@ import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
public class FileModule extends Module
{
private String name;
@@ -137,11 +141,11 @@ public class FileModule extends Module
return true;
}
public static boolean appendText(File filePath, boolean addNewLines, List<String> data)
public static boolean appendText(Path filePath, boolean addNewLines, List<String> data)
{
try
{
OutputStream out = Files.newOutputStream(filePath.toPath(), StandardOpenOption.APPEND, StandardOpenOption.CREATE);
OutputStream out = Files.newOutputStream(filePath, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
{
for (String line: data)
@@ -159,9 +163,9 @@ public class FileModule extends Module
}
public static List<String> listFileContent(File filePath)
public static List<String> listFileContent(Path filePath)
{
try (BufferedReader reader = Files.newBufferedReader(filePath.toPath(), StandardCharsets.UTF_8)) {
try (BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8)) {
List<String> result = new ArrayList<>();
for (;;) {
String line = reader.readLine();
@@ -176,6 +180,18 @@ public class FileModule extends Module
return null;
}
}
public static JsonElement readJsonContent(Path filePath)
{
try (BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8))
{
return new JsonParser().parse(new JsonReader(reader));
}
catch (IOException e)
{
return null;
}
}
public static Stream<Path> listFiles(Path dir, String ext)
{
+30 -11
View File
@@ -5,9 +5,13 @@ import net.minecraft.nbt.Tag;
import net.minecraft.util.WorldSavePath;
import org.apache.commons.io.FilenameUtils;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonElement;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
public abstract class Module
@@ -16,6 +20,13 @@ public abstract class Module
public abstract String getCode();
public abstract boolean isLibrary();
public final static Object writeIOSync = new Object();
public final static Map<String, String> supportedTypes = ImmutableMap.of(
"raw", ".txt",
"text", ".txt",
"nbt", ".nbt",
"json", ".json",
"folder", "folder"
);
private static String getDescriptor(Module module, String file, boolean isShared)
{
@@ -32,7 +43,7 @@ public abstract class Module
public static Tag getData(Module module, String file, boolean isShared)
{
Path dataFile = resolveResource(module, file, "nbt", isShared);
Path dataFile = resolveResource(module, file, ".nbt", isShared);
if (dataFile == null) return null;
if (!Files.exists(dataFile) || !(dataFile.toFile().isFile())) return null;
synchronized (writeIOSync) { return FileModule.read(dataFile.toFile()); }
@@ -40,7 +51,7 @@ public abstract class Module
public static boolean saveData(Module module, String file, Tag globalState, boolean isShared)
{
Path dataFile = resolveResource(module, file, "nbt", isShared);
Path dataFile = resolveResource(module, file, ".nbt", isShared);
if (dataFile == null) return false;
if (!Files.exists(dataFile.getParent()) && !dataFile.toFile().getParentFile().mkdirs()) return false;
synchronized (writeIOSync) { return FileModule.write(globalState, dataFile.toFile()); }
@@ -48,30 +59,38 @@ public abstract class Module
public static boolean appendToTextFile(Module module, String resourceName, String type, boolean isShared, List<String> message)
{
Path dataFile = resolveResource(module, resourceName, "txt", isShared);
Path dataFile = resolveResource(module, resourceName, supportedTypes.get(type), isShared);
if (dataFile == null) return false;
if (!Files.exists(dataFile.getParent()) && !dataFile.toFile().getParentFile().mkdirs()) return false;
synchronized (writeIOSync) { return FileModule.appendText(dataFile.toFile(), type.equals("text"), message); }
synchronized (writeIOSync) { return FileModule.appendText(dataFile, type.equals("text"), message); }
}
public static boolean dropExistingFile(Module module, String resourceName, String ext, boolean isShared)
public static boolean dropExistingFile(Module module, String resourceName, String type, boolean isShared)
{
Path dataFile = resolveResource(module, resourceName, ext, isShared);
Path dataFile = resolveResource(module, resourceName, supportedTypes.get(type), isShared);
if (dataFile == null) return false;
synchronized (writeIOSync) { return dataFile.toFile().delete(); }
}
public static List<String> listFile(Module module, String resourceName, String ext, boolean isShared)
public static List<String> listFile(Module module, String resourceName, String type, boolean isShared)
{
Path dataFile = resolveResource(module, resourceName, ext, isShared);
Path dataFile = resolveResource(module, resourceName, supportedTypes.get(type), isShared);
if (dataFile == null) return null;
if (!dataFile.toFile().exists()) return null;
synchronized (writeIOSync) { return FileModule.listFileContent(dataFile.toFile()); }
synchronized (writeIOSync) { return FileModule.listFileContent(dataFile); }
}
public static JsonElement readJsonFile(Module module, String resourceName, String type, boolean isShared) {
Path dataFile = resolveResource(module, resourceName, supportedTypes.get(type), isShared);
if (dataFile == null) return null;
if (!dataFile.toFile().exists()) return null;
synchronized (writeIOSync) { return FileModule.readJsonContent(dataFile); }
}
public static Stream<String> listFolder(Module module, String resourceName, String ext, boolean isShared)
public static Stream<String> listFolder(Module module, String resourceName, String type, boolean isShared)
{
Path dir = resolveResource(module, resourceName, null, isShared);
String ext = supportedTypes.get(type);
if (dir == null) return null;
if (!Files.exists(dir)) return null;
Stream<Path> result;
@@ -87,7 +106,7 @@ public abstract class Module
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==null?"":"."+ext));
return CarpetServer.minecraft_server.getSavePath(WorldSavePath.ROOT).resolve("scripts/"+getDescriptor(module, resourceName, isShared)+(ext==null?"":ext));
}
@Override
@@ -315,13 +315,13 @@ public abstract class CommandArgument
public static CommandArgument buildFromConfig(String suffix, Map<String, Value> config, CarpetScriptHost host)
{
if (!config.containsKey("type"))
throw new InternalExpressionException("Custom types should at least specify the type");
throw new InternalExpressionException("Custom type "+suffix+" should at least specify the type");
String baseType = config.get("type").getString();
if (!builtIns.containsKey(baseType))
throw new InternalExpressionException("Unknown base type: "+baseType);
throw new InternalExpressionException("Unknown base type "+baseType+" for custom type "+suffix);
CommandArgument variant = builtIns.get(baseType).factory().get();
variant.configure(config, host);
variant.suffix = suffix;
variant.configure(config, host);
return variant;
}
@@ -334,9 +334,9 @@ public abstract class CommandArgument
}
if (config.containsKey("suggest"))
{
if (config.containsKey("suggester")) throw new InternalExpressionException("Attempted to provide 'suggest' list while 'suggester' is present");
if (config.containsKey("suggester")) throw new InternalExpressionException("Attempted to provide 'suggest' list while 'suggester' is present"+" for custom type "+suffix);
Value suggestionValue = config.get("suggest");
if (!(suggestionValue instanceof ListValue)) throw new InternalExpressionException("Argument suggestions needs to be a list");
if (!(suggestionValue instanceof ListValue)) throw new InternalExpressionException("Argument suggestions needs to be a list"+" for custom type "+suffix);
examples = ((ListValue) suggestionValue).getItems().stream()
.map(Value::getString)
.collect(Collectors.toSet());
@@ -378,7 +378,7 @@ public abstract class CommandArgument
args.add(MapValue.wrap(params));
args.addAll(customSuggester.args);
Value response = host.handleCommand(context.getSource(), customSuggester.function, args);
if (!(response instanceof ListValue)) throw error("Custom suggester should return a list of options");
if (!(response instanceof ListValue)) throw error("Custom suggester should return a list of options"+" for custom type "+suffix);
return ((ListValue) response).getItems().stream().map(Value::getString).collect(Collectors.toList());
}
if (needsMatching) return examples;
@@ -426,7 +426,7 @@ public abstract class CommandArgument
if (!caseSensitive) choseValue = choseValue.toLowerCase(Locale.ROOT);
if (!validOptions.isEmpty() && !validOptions.contains(choseValue))
{
throw new SimpleCommandExceptionType(new LiteralText("Incorrect value for "+param+": "+choseValue)).create();
throw new SimpleCommandExceptionType(new LiteralText("Incorrect value for "+param+": "+choseValue+" for custom type "+suffix)).create();
}
return StringValue.of(choseValue);
}
@@ -438,7 +438,7 @@ public abstract class CommandArgument
if (config.containsKey("options"))
{
Value optionsValue = config.get("options");
if (!(optionsValue instanceof ListValue)) throw new InternalExpressionException("Custom string type requires options passed as a list");
if (!(optionsValue instanceof ListValue)) throw new InternalExpressionException("Custom string type requires options passed as a list"+" for custom type "+suffix);
validOptions = ((ListValue) optionsValue).getItems().stream()
.map(v -> caseSensitive?v.getString():(v.getString().toLowerCase(Locale.ROOT)))
.collect(Collectors.toSet());
@@ -577,7 +577,7 @@ public abstract class CommandArgument
if (!single) return ListValue.wrap(founds.stream().map(EntityValue::new).collect(Collectors.toList()));
if (founds.size() == 0) return Value.NULL;
if (founds.size() == 1) return new EntityValue(founds.iterator().next());
throw new SimpleCommandExceptionType(new LiteralText("Multiple entities returned while only one was requested")).create();
throw new SimpleCommandExceptionType(new LiteralText("Multiple entities returned while only one was requested"+" for custom type "+suffix)).create();
}
@Override
@@ -618,7 +618,7 @@ public abstract class CommandArgument
int size = profiles.size();
if (size == 0) return Value.NULL;
if (size == 1) return StringValue.of(profiles.iterator().next().getName());
throw new SimpleCommandExceptionType(new LiteralText("Multiple game profiles returned while only one was requested")).create();
throw new SimpleCommandExceptionType(new LiteralText("Multiple game profiles returned while only one was requested"+" for custom type "+suffix)).create();
}
@Override
@@ -659,7 +659,7 @@ public abstract class CommandArgument
int size = holders.size();
if (size == 0) return Value.NULL;
if (size == 1) return StringValue.of(holders.iterator().next());
throw new SimpleCommandExceptionType(new LiteralText("Multiple score holders returned while only one was requested")).create();
throw new SimpleCommandExceptionType(new LiteralText("Multiple score holders returned while only one was requested"+" for custom type "+suffix)).create();
}
@Override
@@ -734,7 +734,7 @@ public abstract class CommandArgument
Identifier choseValue = IdentifierArgumentType.getIdentifier(context, param);
if (!validOptions.isEmpty() && !validOptions.contains(choseValue))
{
throw new SimpleCommandExceptionType(new LiteralText("Incorrect value for "+param+": "+choseValue)).create();
throw new SimpleCommandExceptionType(new LiteralText("Incorrect value for "+param+": "+choseValue+" for custom type "+suffix)).create();
}
return ValueConversions.of(choseValue);
}
@@ -752,7 +752,7 @@ public abstract class CommandArgument
if (config.containsKey("options"))
{
Value optionsValue = config.get("options");
if (!(optionsValue instanceof ListValue)) throw new InternalExpressionException("Custom sting type requires options passed as a list");
if (!(optionsValue instanceof ListValue)) throw new InternalExpressionException("Custom sting type requires options passed as a list"+" for custom type "+suffix);
validOptions = ((ListValue) optionsValue).getItems().stream().map(v -> new Identifier(v.getString())).collect(Collectors.toSet());
}
}
@@ -799,7 +799,7 @@ public abstract class CommandArgument
{
max = NumericValue.asNumber(config.get("max"), "max").getDouble();
}
if (max != null && min == null) throw new InternalExpressionException("Double types cannot be only upper-bounded");
if (max != null && min == null) throw new InternalExpressionException("Double types cannot be only upper-bounded"+" for custom type "+suffix);
}
@Override
@@ -850,7 +850,7 @@ public abstract class CommandArgument
{
max = NumericValue.asNumber(config.get("max"), "max").getLong();
}
if (max != null && min == null) throw new InternalExpressionException("Double types cannot be only upper-bounded");
if (max != null && min == null) throw new InternalExpressionException("Double types cannot be only upper-bounded"+" for custom type "+suffix);
}
@Override
@@ -923,7 +923,7 @@ public abstract class CommandArgument
int slot = ItemSlotArgumentType.getItemSlot(context, param);
if (restrict != null && !RESTRICTED_CONTAINERS.get(restrict).getLeft().contains(slot))
{
throw new SimpleCommandExceptionType(new LiteralText("Incorrect slot restricted to "+restrict)).create();
throw new SimpleCommandExceptionType(new LiteralText("Incorrect slot restricted to "+restrict+" for custom type "+suffix)).create();
}
return ValueConversions.ofVanillaSlotResult(slot);
}
@@ -937,7 +937,7 @@ public abstract class CommandArgument
restrict = config.get("restrict").getString().toLowerCase(Locale.ROOT);
needsMatching = true;
if (!RESTRICTED_CONTAINERS.containsKey(restrict))
throw new InternalExpressionException("Incorrect slot restriction: "+restrict);
throw new InternalExpressionException("Incorrect slot restriction "+restrict+" for custom type "+suffix);
}
}
@@ -87,7 +87,7 @@ public class DataStructures {
throw new InternalExpressionException("'slice' takes 2 or 3 arguments");
Value hwat = lv.get(0);
long from = NumericValue.asNumber(lv.get(1)).getLong();
long to = -1;
Long to = null;
if (lv.size()== 3)
to = NumericValue.asNumber(lv.get(2)).getLong();
return hwat.slice(from, to);
@@ -0,0 +1,78 @@
package carpet.script.utils;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import carpet.script.value.ListValue;
import carpet.script.value.MapValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
public class ScarpetJsonDeserializer implements JsonDeserializer<Value>{
@Override
public Value deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return parseElement(json);
}
private Value parseElement(JsonElement element) throws JsonParseException {
if (element.isJsonObject())
{
return parseMap(element.getAsJsonObject());
}
else if (element.isJsonArray())
{
return parseList(element.getAsJsonArray());
}
else if (element.isJsonPrimitive())
{
return parsePrimitive(element.getAsJsonPrimitive());
}
return Value.NULL;
}
private Value parseMap(JsonObject jsonMap) throws JsonParseException {
Map<Value, Value> map = new HashMap<Value, Value>();
jsonMap.entrySet().forEach(entry -> {
map.put(new StringValue(entry.getKey()), parseElement(entry.getValue()));
});
return MapValue.wrap(map);
}
private Value parseList(JsonArray jsonList) throws JsonParseException {
List<Value> list = new ArrayList<Value>();
jsonList.forEach(elem -> {
list.add(parseElement(elem));
});
return new ListValue(list);
}
private Value parsePrimitive(JsonPrimitive primitive) throws JsonParseException {
if (primitive.isString())
{
return new StringValue(primitive.getAsString());
}
else if (primitive.isBoolean())
{
return primitive.getAsBoolean() ? Value.TRUE : Value.FALSE;
}
else if (primitive.isNumber())
{
return NumericValue.of(primitive.getAsNumber());
}
return Value.NULL;
}
}
@@ -168,6 +168,15 @@ public class ShapesRenderer
}
}
public void renewShapes()
{
synchronized (shapes)
{
shapes.values().forEach(el -> el.values().forEach(shape -> {
shape.expiryTick++;
}));
}
}
public abstract static class RenderedShape<T extends ShapeDispatcher.ExpiringShape>
{
@@ -13,6 +13,7 @@ import carpet.settings.ParsedRule;
import carpet.settings.SettingsManager;
import com.sun.management.OperatingSystemMXBean;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.SharedConstants;
import net.minecraft.util.WorldSavePath;
import net.minecraft.world.GameRules;
@@ -56,6 +57,7 @@ public class SystemInfo {
put("game_view_distance", c -> new NumericValue(c.s.getMinecraftServer().getPlayerManager().getViewDistance()));
put("game_mod_name", c -> StringValue.of(c.s.getMinecraftServer().getServerModName()));
put("game_version", c -> StringValue.of(c.s.getMinecraftServer().getVersion()));
put("game_data_version", c->NumericValue.of(SharedConstants.getGameVersion().getWorldVersion()));
put("server_ip", c -> StringValue.of(c.s.getMinecraftServer().getServerIp()));
put("server_whitelisted", c -> new NumericValue(c.s.getMinecraftServer().isEnforceWhitelist()));
@@ -4,7 +4,7 @@ import carpet.script.exception.InternalExpressionException;
import java.util.Iterator;
public abstract class AbstractListValue extends Value
public abstract class AbstractListValue extends Value implements Iterable<Value>
{
public abstract Iterator<Value> iterator();
public void fatality() { }
@@ -7,6 +7,7 @@ import carpet.fakes.LivingEntityInterface;
import carpet.fakes.MemoryInterface;
import carpet.fakes.MobEntityInterface;
import carpet.fakes.HungerManagerInterface;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInteractionManagerInterface;
import carpet.helpers.Tracer;
import carpet.network.ServerNetworkHandler;
@@ -91,7 +92,7 @@ import static carpet.utils.MobAI.genericJump;
// TODO: decide whether copy(entity) should duplicate entity in the world.
public class EntityValue extends Value
{
private final Entity entity;
private Entity entity;
public EntityValue(Entity e)
{
@@ -120,6 +121,11 @@ public class EntityValue extends Value
public Entity getEntity()
{
if (entity instanceof ServerPlayerEntity && ((ServerPlayerEntityInterface)entity).isInvalidEntityObject())
{
ServerPlayerEntity newPlayer = entity.getServer().getPlayerManager().getPlayer(entity.getUuid());
if (newPlayer != null) entity = newPlayer;
}
return entity;
}
@@ -171,7 +177,7 @@ public class EntityValue extends Value
@Override
public String getString()
{
return entity.getName().getString();
return getEntity().getName().getString();
}
@Override
@@ -185,7 +191,7 @@ public class EntityValue extends Value
{
if (v instanceof EntityValue)
{
return entity.getEntityId()==((EntityValue) v).entity.getEntityId();
return getEntity().getEntityId()==((EntityValue) v).getEntity().getEntityId();
}
return super.equals((Value)v);
}
@@ -221,7 +227,7 @@ public class EntityValue extends Value
@Override
public int hashCode()
{
return entity.hashCode();
return getEntity().hashCode();
}
public static EntityClassDescriptor getEntityDescriptor(String who, MinecraftServer server)
@@ -389,7 +395,7 @@ public class EntityValue extends Value
throw new InternalExpressionException("Unknown entity feature: "+what);
try
{
return featureAccessors.get(what).apply(entity, arg);
return featureAccessors.get(what).apply(getEntity(), arg);
}
catch (NullPointerException npe)
{
@@ -850,7 +856,7 @@ public class EntityValue extends Value
throw new InternalExpressionException("Unknown entity action: " + what);
try
{
featureModifiers.get(what).accept(entity, toWhat);
featureModifiers.get(what).accept(getEntity(), toWhat);
}
catch (NullPointerException npe)
{
@@ -1483,7 +1489,7 @@ public class EntityValue extends Value
EntityEventsGroup.Event event = EntityEventsGroup.Event.byName.get(eventName);
if (event == null)
throw new InternalExpressionException("Unknown entity event: " + eventName);
((EntityInterface)entity).getEventContainer().addEvent(event, cc.host, fun, args);
((EntityInterface)getEntity()).getEventContainer().addEvent(event, cc.host, fun, args);
}
@Override
@@ -1492,7 +1498,7 @@ public class EntityValue extends Value
if (!force) throw new NBTSerializableValue.IncompatibleTypeException(this);
CompoundTag tag = new CompoundTag();
tag.put("Data", getEntity().toTag( new CompoundTag()));
tag.put("Name", StringTag.of(Registry.ENTITY_TYPE.getId(entity.getType()).toString()));
tag.put("Name", StringTag.of(Registry.ENTITY_TYPE.getId(getEntity().getType()).toString()));
return tag;
}
}
@@ -133,7 +133,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
}
@Override
public Value slice(long from, long to)
public Value slice(long from, Long to)
{
throw new InternalExpressionException("Cannot slice a function");
}
@@ -129,9 +129,9 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
}
@Override
public Value slice(long from, long to)
public Value slice(long from, Long to)
{
if (to < 0) to = Integer.MAX_VALUE;
if (to == null || to < 0) to = (long) Integer.MAX_VALUE;
if (from < 0) from = 0;
if (from > to)
return ListValue.of();
@@ -289,27 +289,22 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
items.add(v);
}
public void addAtIndex(int index, List<Value> subList)
/**
* Finds a proper list index >=0 and < len that correspont to the rolling index value of idx
*
* @param idx
* @param len
* @return
*/
public static int normalizeIndex(long idx, int len)
{
int numitems = items.size();
long range = abs(index)/numitems;
index += (range+2)*numitems;
index = index % numitems;
for (Value v: subList)
{
if (index < numitems)
{
items.set(index, v);
}
else
{
items.add(v);
}
index++;
}
if (idx >=0 && idx < len) return (int)idx;
long range = abs(idx)/len;
idx += (range+2)*len;
idx = idx % len;
return (int)idx;
}
public static class ListConstructorValue extends ListValue
{
public ListConstructorValue(Collection<? extends Value> list)
@@ -339,15 +334,17 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
}
@Override
public Value slice(long from, long to)
public Value slice(long fromDesc, Long toDesc)
{
List<Value> items = getItems();
int size = items.size();
if (to < 0 || to > size) to = size;
if (from < 0 || from > size) from = size;
int from = normalizeIndex(fromDesc, size);
if (toDesc == null)
return new ListValue((Collection<? extends Value>) getItems().subList(from, size));
int to = normalizeIndex(toDesc, size);
if (from > to)
return ListValue.of();
return new ListValue((Collection<? extends Value>) getItems().subList((int)from, (int) to));
return new ListValue((Collection<? extends Value>) getItems().subList(from, to));
}
@Override
@@ -395,10 +392,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
return false;
int index = (int)((NumericValue) ind).getLong();
if (index < 0)
{
long range = abs(index) / numitems;
index += (range + 2) * numitems;
index = index % numitems;
{// only for values < 0
index = normalizeIndex(index, numitems);
}
if (replace)
{
@@ -424,11 +419,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
public Value get(Value value)
{
long index = NumericValue.asNumber(value, "'address' to a list index").getLong();
int numitems = items.size();
long range = abs(index)/numitems;
index += (range+2)*numitems;
index = index % numitems;
return items.get((int)index);
return items.get(normalizeIndex(index, items.size()));
}
@Override
@@ -443,11 +434,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
{
if (!(where instanceof NumericValue) || items.isEmpty()) return false;
long index = ((NumericValue) where).getLong();
int numitems = items.size();
long range = abs(index)/numitems;
index += (range+2)*numitems;
index = index % numitems;
items.remove((int)index);
items.remove(normalizeIndex(index, items.size()));
return true;
}
@@ -198,7 +198,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
}
@Override
public Value slice(long from, long to)
public Value slice(long from, Long to)
{
throw new InternalExpressionException("Cannot slice a map value");
}
@@ -5,6 +5,8 @@ import net.minecraft.nbt.Tag;
public class StringValue extends Value
{
public static Value EMPTY = StringValue.of("");
private String str;
@Override
+6 -7
View File
@@ -178,16 +178,15 @@ public abstract class Value implements Comparable<Value>, Cloneable
return getString().length();
}
public Value slice(long from, long to)
public Value slice(long fromDesc, Long toDesc)
{
String value = this.getString();
int size = value.length();
if (to > size) to = -1;
if (from < 0) from = 0;
if (from > size) from = size;
if (to>=0)
return new StringValue(value.substring((int)from, (int)to));
return new StringValue(value.substring((int)from));
int from = ListValue.normalizeIndex(fromDesc, size);
if (toDesc == null) return new StringValue(value.substring(from));
int to = ListValue.normalizeIndex(toDesc, size);
if (from > to) return StringValue.EMPTY;
return new StringValue(value.substring(from, to));
}
public double readDoubleNumber()
{