From 49ffa4f10907798185a36d4b79d758fe90b8b424 Mon Sep 17 00:00:00 2001 From: altrisi Date: Mon, 11 Jan 2021 19:46:39 +0100 Subject: [PATCH 1/7] Add new split functions --- .../script/language/DataStructures.java | 23 ++++++------------- .../java/carpet/script/value/ListValue.java | 18 +++++++++++++++ .../java/carpet/script/value/MapValue.java | 5 ++++ .../java/carpet/script/value/NullValue.java | 7 ++++++ src/main/java/carpet/script/value/Value.java | 15 ++++++++++++ 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/main/java/carpet/script/language/DataStructures.java b/src/main/java/carpet/script/language/DataStructures.java index 95b18749..90d02d99 100644 --- a/src/main/java/carpet/script/language/DataStructures.java +++ b/src/main/java/carpet/script/language/DataStructures.java @@ -14,10 +14,8 @@ import carpet.script.value.StringValue; import carpet.script.value.Value; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.regex.PatternSyntaxException; import java.util.stream.Collectors; public class DataStructures { @@ -54,30 +52,23 @@ public class DataStructures { expression.addFunction("split", (lv) -> { - String delimiter; - String hwat; + Value delimiter; + Value hwat; if (lv.size() == 1) { - hwat = lv.get(0).getString(); - delimiter = ""; + hwat = lv.get(0); + delimiter = StringValue.EMPTY; } else if (lv.size() == 2) { - delimiter = lv.get(0).getString(); - hwat = lv.get(1).getString(); + delimiter = lv.get(0); + hwat = lv.get(1); } else { throw new InternalExpressionException("'split' takes 1 or 2 arguments"); } - try - { - return ListValue.wrap(Arrays.stream(hwat.split(delimiter)).map(StringValue::new).collect(Collectors.toList())); - } - catch (PatternSyntaxException pse) - { - throw new InternalExpressionException("Incorrect pattern for 'split': "+pse.getMessage()); - } + return hwat.split(delimiter); }); expression.addFunction("slice", (lv) -> diff --git a/src/main/java/carpet/script/value/ListValue.java b/src/main/java/carpet/script/value/ListValue.java index a036af56..c3b23438 100644 --- a/src/main/java/carpet/script/value/ListValue.java +++ b/src/main/java/carpet/script/value/ListValue.java @@ -347,6 +347,24 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf return new ListValue((Collection) getItems().subList(from, to)); } + @Override + public Value split(Value delimiter) { + ListValue result = new ListValue(); + int startIndex = 0; + int index = 0; + for (Value val : this.items) + { + index++; + if (val.equals(delimiter)) + { + result.items.add(ListValue.wrap(this.items.subList(startIndex, index-1))); + startIndex = index; + } + } + result.items.add(ListValue.wrap(this.items.subList(startIndex, length()))); + return result; + } + @Override public double readDoubleNumber() { diff --git a/src/main/java/carpet/script/value/MapValue.java b/src/main/java/carpet/script/value/MapValue.java index abefe087..81375bdc 100644 --- a/src/main/java/carpet/script/value/MapValue.java +++ b/src/main/java/carpet/script/value/MapValue.java @@ -203,6 +203,11 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa throw new InternalExpressionException("Cannot slice a map value"); } + @Override + public Value split(Value delimiter) { + throw new InternalExpressionException("Cannot split a map value"); + } + @Override public double readDoubleNumber() { diff --git a/src/main/java/carpet/script/value/NullValue.java b/src/main/java/carpet/script/value/NullValue.java index 95df97c9..c810dc09 100644 --- a/src/main/java/carpet/script/value/NullValue.java +++ b/src/main/java/carpet/script/value/NullValue.java @@ -1,5 +1,7 @@ package carpet.script.value; +import java.util.ArrayList; + import com.google.gson.JsonElement; import com.google.gson.JsonNull; import net.minecraft.nbt.StringTag; @@ -63,6 +65,11 @@ public class NullValue extends NumericValue // TODO check nonsingleton code return StringTag.of("null"); } + @Override + public Value split(Value delimiter) { + return ListValue.wrap(new ArrayList()); + } + @Override public JsonElement toJson() { diff --git a/src/main/java/carpet/script/value/Value.java b/src/main/java/carpet/script/value/Value.java index 8f79f462..b9ac965c 100644 --- a/src/main/java/carpet/script/value/Value.java +++ b/src/main/java/carpet/script/value/Value.java @@ -6,10 +6,12 @@ import com.google.gson.JsonPrimitive; import net.minecraft.nbt.Tag; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; public abstract class Value implements Comparable, Cloneable { @@ -188,6 +190,19 @@ public abstract class Value implements Comparable, Cloneable if (from > to) return StringValue.EMPTY; return new StringValue(value.substring(from, to)); } + + public Value split(Value delimiter) + { + try + { + return ListValue.wrap(Arrays.stream(getString().split(delimiter.getString())).map(StringValue::new).collect(Collectors.toList())); + } + catch (PatternSyntaxException pse) + { + throw new InternalExpressionException("Incorrect pattern for 'split': "+pse.getMessage()); + } + } + public double readDoubleNumber() { String s = getString(); From 0563590fe7b0fa4c184385b1d36191dfc747c3d5 Mon Sep 17 00:00:00 2001 From: altrisi Date: Mon, 11 Jan 2021 19:53:43 +0100 Subject: [PATCH 2/7] Document new split functions --- docs/scarpet/language/Containers.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/scarpet/language/Containers.md b/docs/scarpet/language/Containers.md index f017adaf..07d6993a 100644 --- a/docs/scarpet/language/Containers.md +++ b/docs/scarpet/language/Containers.md @@ -160,11 +160,19 @@ join('-', 'foo', 'bar') => foo-bar Splits a string under `expr` by `delim` which can be a regular expression. If no delimiter is specified, it splits by characters. +If `expr` is a list, it will split the list into multiple sublists by the element (s) which equal `delim`, or which equal the empty string +in case no delimiter is specified. + +Splitting a `null` value will return an empty list. +
 split('foo') => [f, o, o]
 split('','foo')  => [f, o, o]
 split('.','foo.bar')  => []
 split('\\.','foo.bar')  => [foo, bar]
+split(1,[2,5,1,2,3,1,5,6]) => [[2,5],[2,3],[5,6]]
+split(1,[1,2,3,1,4,5,1] => [[], [2,3], [4,5], []]
+split(null) => []
 
### `slice(expr, from, to?)` From df20f9e4e4cb680b7f28ccab3253a6d025ee8f35 Mon Sep 17 00:00:00 2001 From: Andrew S Date: Wed, 13 Jan 2021 20:07:42 -0500 Subject: [PATCH 3/7] Add the `lightEngineMaxBatchSize` rule (#654) * Apply light batch sizes after start region has been created * Add light batch rules --- src/main/java/carpet/CarpetSettings.java | 53 +++++++++++++++++++ .../mixins/MinecraftServer_coreMixin.java | 2 + 2 files changed, 55 insertions(+) diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index a202e209..32dba3cc 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -19,6 +19,7 @@ import net.minecraft.world.World; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.Iterator; import java.util.Locale; import static carpet.settings.RuleCategory.BUGFIX; @@ -638,6 +639,58 @@ public class CarpetSettings ) public static int spawnChunksSize = 11; + public static class LightBatchValidator extends Validator { + public static void applyLightBatchSizes() + { + Iterator iterator = CarpetServer.minecraft_server.getWorlds().iterator(); + + while (iterator.hasNext()) + { + ServerWorld serverWorld = iterator.next(); + serverWorld.getChunkManager().getLightingProvider().setTaskBatchSize(lightEngineMaxBatchSize); + } + } + @Override public Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { + if (source == null) return newValue; + if (newValue < 0) + { + Messenger.m(source, "r light batch size has to be at least 0"); + return null; + } + if (currentRule.get().intValue() == newValue.intValue()) + { + //must been some startup thing + return newValue; + } + if (CarpetServer.minecraft_server == null) return newValue; + + // Set the field before we apply. + try + { + currentRule.field.set(null, newValue.intValue()); + } + catch (IllegalAccessException e) + { + Messenger.m(source, "r Unable to access setting for "+currentRule.name); + return null; + } + + applyLightBatchSizes(); // Apply new settings + + return newValue; + } + } + + @Rule( + desc = "Changes maximum light tasks batch size", + extra = {"Allows for a higher light suppression tolerance", "setting it to 5 - Default limit defined by the game"}, + category = {EXPERIMENTAL, OPTIMIZATION}, + strict = false, + options = {"5", "50", "100", "200"}, + validate = LightBatchValidator.class + ) + public static int lightEngineMaxBatchSize = 5; + @Rule(desc = "Coral structures will grow with bonemeal from coral plants", category = FEATURE) public static boolean renewableCoral = false; diff --git a/src/main/java/carpet/mixins/MinecraftServer_coreMixin.java b/src/main/java/carpet/mixins/MinecraftServer_coreMixin.java index e638ec63..0638d9b9 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_coreMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_coreMixin.java @@ -52,5 +52,7 @@ public abstract class MinecraftServer_coreMixin { if (CarpetSettings.spawnChunksSize != 11) CarpetSettings.ChangeSpawnChunksValidator.changeSpawnSize(CarpetSettings.spawnChunksSize); + + CarpetSettings.LightBatchValidator.applyLightBatchSizes(); } } From 2121a91a55a8d0b65b36964152dccf8d4734b354 Mon Sep 17 00:00:00 2001 From: BisUmTo <31419791+BisUmTo@users.noreply.github.com> Date: Thu, 14 Jan 2021 02:14:57 +0100 Subject: [PATCH 4/7] Added nbt_storage() scapet function (#655) * Added storage() scarpet function Allows you to easly manage vanilla data command storage * Added docs and uniformed with scoreboard() storage(key, nbt) will now return the previous value to be consistant with the scoreboard() command. * Included imports * Renamed storage function to nbt_storage * Update docs/scarpet/api/Auxiliary.md Co-authored-by: gnembon <41132274+gnembon@users.noreply.github.com> --- docs/scarpet/api/Auxiliary.md | 6 +++++ docs/scarpet/resources/editors/idea/2.txt | 1 + .../scarpet/resources/editors/npp/scarpet.xml | 2 ++ .../java/carpet/script/api/Auxiliary.java | 26 +++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index 399d5fc1..cede1808 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -540,3 +540,9 @@ Available options in the scarpet app space: Scarpet related properties * `scarpet_version` - returns the version of the carpet your scarpet comes with. + +## NBT Storage + +### `nbt_storage()`, `nbt_storage(key)`, `nbt_storage(key, nbt)` +Displays or modifies individual storage NBT tags. With no arguments, returns the list of current NBT storages. With specified `key`, returns the `nbt` associated with current `key`, or `null` if storage does not exist. With specified `key` and `nbt`, sets a new `nbt` value, returning previous value associated with the `key`. +NOTE: This NBT storage is shared with all vanilla datapacks and scripts of the entire server and is persistent between restarts and reloads. You can also access this NBT storage with vanilla `/data storage ...` command. diff --git a/docs/scarpet/resources/editors/idea/2.txt b/docs/scarpet/resources/editors/idea/2.txt index 25f4e954..4186fa25 100644 --- a/docs/scarpet/resources/editors/idea/2.txt +++ b/docs/scarpet/resources/editors/idea/2.txt @@ -67,6 +67,7 @@ map_colour material modify nbt +nbt_storage neighbours opacity parse_nbt diff --git a/docs/scarpet/resources/editors/npp/scarpet.xml b/docs/scarpet/resources/editors/npp/scarpet.xml index 83cceb54..eeb7ca64 100644 --- a/docs/scarpet/resources/editors/npp/scarpet.xml +++ b/docs/scarpet/resources/editors/npp/scarpet.xml @@ -86,6 +86,8 @@ load_app_data store_app_data read_file write_file delete_file list_files escape_nbt parse_nbt encode_nbt tag_matches statistic + + nbt_storage euler pi null true false x y z p diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index 7625ea94..a0268cc7 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -36,12 +36,14 @@ import carpet.script.value.Value; import carpet.script.value.ValueConversions; import carpet.utils.Messenger; import net.minecraft.block.BlockState; +import net.minecraft.command.DataCommandStorage; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtHelper; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; @@ -86,6 +88,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.Stream; +import static carpet.script.value.NBTSerializableValue.nameFromRegistryId; import static java.lang.Math.max; import static java.lang.Math.min; @@ -1022,6 +1025,29 @@ public class Auxiliary { Value ret = new NumericValue(counts); return (c_, t_) -> ret; }); + + // nbt_storage() + // nbt_storage(key) + // nbt_storage(key, nbt) + expression.addLazyFunction("nbt_storage", -1, (c, t, lv) -> { + if (lv.size() > 2) throw new InternalExpressionException("'nbt_storage' requires 0, 1 or 2 arguments."); + CarpetContext cc = (CarpetContext) c; + DataCommandStorage storage = cc.s.getMinecraftServer().getDataCommandStorage(); + if (lv.size() == 0) { + Value ret = ListValue.wrap(storage.getIds().map(i -> new StringValue(nameFromRegistryId(i))).collect(Collectors.toList())); + return (_c, _t) -> ret; + } + String key = lv.get(0).evalValue(c).getString(); + CompoundTag old_nbt = storage.get(new Identifier(key)); + if (lv.size() == 2) { + Value nbt = lv.get(1).evalValue(c); + NBTSerializableValue new_nbt = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt + : NBTSerializableValue.parseString(nbt.getString(), true); + storage.set(new Identifier(key), new_nbt.getCompoundTag()); + } + if (old_nbt == null) return LazyValue.NULL; + return (_c, _t) -> new NBTSerializableValue(old_nbt); + }); } private static Stat getStat(StatType type, Identifier id) From 69d2b6df11e6d9e2c3f42738609ac65250f6eb9a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 14 Jan 2021 01:15:14 +0000 Subject: [PATCH 5/7] Merge docs for 'Added nbt_storage() scapet function (#655) * Added storage() scarpet function Allows you to easly manage vanilla data command storage * Added docs and uniformed with scoreboard() storage(key, nbt) will now return the previous value to be consistant with the scoreboard() command. * Included imports * Renamed storage function to nbt_storage * Update docs/scarpet/api/Auxiliary.md Co-authored-by: gnembon <41132274+gnembon@users.noreply.github.com>' --- docs/scarpet/Full.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index 0c427544..b762d444 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -3138,6 +3138,10 @@ Boolean, true if the entity is silent. Boolean, true if the entity is affected by gravity, like most entities are. +### `query(e, 'invulnerable')` + +Boolean, true if the entity is invulnerable. + ### `query(e, 'immune_to_fire')` Boolean, true if the entity is immune to fire. @@ -3618,6 +3622,10 @@ Silences or unsilences the entity. Toggles gravity for the entity. +### `modify(e, 'invulnerable', boolean)` + +Toggles invulnerability for the entity. + ### `modify(e, 'fire', ticks)` Will set entity on fire for `ticks` ticks. Set to 0 to extinguish. @@ -5006,6 +5014,12 @@ Available options in the scarpet app space: Scarpet related properties * `scarpet_version` - returns the version of the carpet your scarpet comes with. + +## NBT Storage + +### `nbt_storage()`, `nbt_storage(key)`, `nbt_storage(key, nbt)` +Displays or modifies individual storage NBT tags. With no arguments, returns the list of current NBT storages. With specified `key`, returns the `nbt` associated with current `key`, or `null` if storage does not exist. With specified `key` and `nbt`, sets a new `nbt` value, returning previous value associated with the `key`. +NOTE: This NBT storage is shared with all vanilla datapacks and scripts of the entire server and is persistent between restarts and reloads. You can also access this NBT storage with vanilla `/data storage ...` command. # `/script run` command Primary way to input commands. The command executes in the context, position, and dimension of the executing player, From c0e2d17377e6b58f3c6b5eefcbfbd92b7cd669c7 Mon Sep 17 00:00:00 2001 From: replaceitem <40722305+replaceitem@users.noreply.github.com> Date: Thu, 14 Jan 2021 02:17:39 +0100 Subject: [PATCH 6/7] Fixed null acting as a string with matching operator (~) and split() (#662) * Fixed null acting as a string with matching operator (~) --- src/main/java/carpet/script/value/NullValue.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/carpet/script/value/NullValue.java b/src/main/java/carpet/script/value/NullValue.java index 95df97c9..48bb5d2e 100644 --- a/src/main/java/carpet/script/value/NullValue.java +++ b/src/main/java/carpet/script/value/NullValue.java @@ -44,6 +44,11 @@ public class NullValue extends NumericValue // TODO check nonsingleton code return o instanceof NullValue ? 0 : -1; } + @Override + public Value in(Value value) { + return Value.NULL; + } + @Override public String getTypeString() { From 97609d9c44823bb67ac3f9f1398c8e92f689d8c5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 14 Jan 2021 01:25:00 +0000 Subject: [PATCH 7/7] Merge docs for 'Merge pull request #666 from altrisi/extra-splitting [Suggestion] Allow splitting lists by element value' --- docs/scarpet/Full.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index b762d444..4fa89e32 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -1655,11 +1655,19 @@ join('-', 'foo', 'bar') => foo-bar Splits a string under `expr` by `delim` which can be a regular expression. If no delimiter is specified, it splits by characters. +If `expr` is a list, it will split the list into multiple sublists by the element (s) which equal `delim`, or which equal the empty string +in case no delimiter is specified. + +Splitting a `null` value will return an empty list. +
 split('foo') => [f, o, o]
 split('','foo')  => [f, o, o]
 split('.','foo.bar')  => []
 split('\\.','foo.bar')  => [foo, bar]
+split(1,[2,5,1,2,3,1,5,6]) => [[2,5],[2,3],[5,6]]
+split(1,[1,2,3,1,4,5,1] => [[], [2,3], [4,5], []]
+split(null) => []
 
### `slice(expr, from, to?)`