Merge branch 'master' into 1.17

# Conflicts:
#	src/main/java/carpet/script/api/Auxiliary.java
#	src/main/java/carpet/script/api/Inventories.java
#	src/main/java/carpet/script/api/WorldAccess.java
#	src/main/java/carpet/script/value/EntityValue.java
This commit is contained in:
gnembon committed 2021-07-05 16:53:01 -03:00
commit 33500dde29
7 files changed
+81 -62

No files matched your search

+34 -13
View File
@@ -1464,6 +1464,10 @@ but if symbols are used directly in the module body rather than functions, it ma
Returns full list of available symbols that could be imported from this module, which can be used to debug import
issues, and list contents of libraries.
You can load and import functions from dependencies in a remote app store's source specified in your config's `libraries` block, but make sure
to place your config _before_ the import in order to allow the remote dependency to be downloaded (currently, app resources are only downloaded
when using the `/carpet download` command).
### `call(function, ? args ...)`
calls a user defined function with specified arguments. It is equivalent to calling `function(args...)` directly
@@ -2019,30 +2023,46 @@ in a list and contain of map-like resources descriptors, looking like
'resources' -> [
{
'source' -> 'https://raw.githubusercontent.com/gnembon/fabric-carpet/master/src/main/resources/assets/carpet/icon.png',
'type' -> 'url',
'target' -> 'foo/photos.zip/foo/cm.png',
},
{
'source' -> 'survival/README.md',
'type' -> 'store',
'source' -> '/survival/README.md',
'target' -> 'survival_readme.md',
'shared' -> true,
},
{
'source' -> 'carpets.sc',
'type' -> 'app',
'target' -> 'apps/flying_carpets.sc',
'shared' -> true,
'source' -> 'circle.sc', // Relative path
'target' -> 'apps/circle.sc', // This won't install the app, use 'libraries' for that
},
]
```
`source` and `type` indicate resource location: either an arbitrary url (type `'url'`),
absolute location of a file in the app store (type `'store'`),
or a relative location in the same folder as the app in question (type `'app'`).
`'target'` points to the path in app data, or shared app data folder
`source` indicates resource location: either an arbitrary url (starting with `http://` or `https://`),
absolute location of a file in the app store (starting with a slash `/`),
or a relative location in the same folder as the app in question (the relative location directly).
`'target'` points to the path in app data, or shared app data folder. If not specified it will place the app into the main data folder with the name it has.
if `'shared'` is specified and `true`. When re-downloading the app, all resources will be re-downloaded as well.
Currently, app resources
are only downloaded when using `/carpet download` command.
Currently, app resources are only downloaded when using `/carpet download` command.
* `libraries` - list of libraries or apps to be downloaded when installing the app from the app store. It needs to be a list of map-like resource
descriptors, like the above `resources` field.
```
'libraries' -> [
{
'source' -> '/tutorial/carpets.sc'
},
{
'source' -> '/fundamentals/heap.sc',
'target' -> 'heap-lib.sc'
}
]
```
`source` indicates resource location and must point to a scarpet app or library. It can be either an arbitrary url (starting with `http://`
or `https://`), absolute location of a file in the app store (starting with a slash `/`), or a relative location in the same folder as the app
in question (the relative location directly).
`target` is an optional field indicating the new name of the app. If not specified it will place the app into the main data folder with the name it has.
If the app has relative resources dependencies, Carpet will use the app's path for relatives if the app was loaded from the same app store, or none if the
app was loaded from an external url.
If you need to `import()` from dependencies indicated in this block, make sure to have the `__config()` map before any import that references your
remote dependencies, in order to allow them to be downloaded and initialized before the import is executed.
* `'arguments'` - defines custom argument types for legacy commands with `'legacy_command_type_support'` as well
as for the custom commands defined with `'commands'`, see below.
* `'commands'` - defines custom commands for the app to be executed with `/<app>` command, see below.
@@ -2223,6 +2243,7 @@ Here is a list of built-in types, with their return value formats, as well as a
* `'dimension'`: string representing a valid dimension in the world.
* `'anchor'`: string of `feet` or `eyes`.
* `'entitytype'`: string representing a type of entity
* `'entities'`: entity selector, returns a list of entities directly. Can be configured with `'single'` to only accept a single entity (will return the entity instead of a singleton) and with `'players'` to only accept players.
* `'floatrange'`: pair of two numbers where one is smaller than the other
* `'players'`: returning a list of valid player name string, logged in or not. If configured with `'single'` returns only one player or `null`.
* `'intrange'`: same as `'floatrange'`, but requiring integers.
+5 -12
View File
@@ -162,7 +162,7 @@ public class Auxiliary {
return ListValue.wrap(Registry.SOUND_EVENT.getIds().stream().map(ValueConversions::of));
}
String rawString = lv.get(0).getString();
Identifier soundName = new Identifier(rawString);
Identifier soundName = InputValidator.identifierOf(rawString);
Vector3Argument locator = Vector3Argument.findIn(lv, 1);
if (Registry.SOUND_EVENT.get(soundName) == null)
throw new ThrowStatement(rawString, Throwables.UNKNOWN_SOUND);
@@ -973,15 +973,8 @@ public class Auxiliary {
if (player == null) return Value.NULL;
Identifier category;
Identifier statName;
try
{
category = new Identifier(lv.get(1).getString());
statName = new Identifier(lv.get(2).getString());
}
catch (InvalidIdentifierException e)
{
return Value.NULL;
}
category = InputValidator.identifierOf(lv.get(1).getString());
statName = InputValidator.identifierOf(lv.get(2).getString());
StatType<?> type = Registry.STAT_TYPE.get(category);
if (type == null) return Value.NULL;
Stat<?> stat = getStat(type, statName);
@@ -1034,12 +1027,12 @@ public class Auxiliary {
if (lv.size() == 0)
return ListValue.wrap(storage.getIds().map(i -> new StringValue(nameFromRegistryId(i))).collect(Collectors.toList()));
String key = lv.get(0).getString();
NbtCompound old_nbt = storage.get(new Identifier(key));
NbtCompound old_nbt = storage.get(InputValidator.identifierOf(key));
if (lv.size() == 2) {
Value nbt = lv.get(1);
NBTSerializableValue new_nbt = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt
: NBTSerializableValue.parseString(nbt.getString(), true);
storage.set(new Identifier(key), new_nbt.getCompoundTag());
storage.set(InputValidator.identifierOf(key), new_nbt.getCompoundTag());
}
return NBTSerializableValue.of(old_nbt);
});
@@ -7,6 +7,7 @@ import carpet.script.Expression;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.utils.InputValidator;
import carpet.script.value.BooleanValue;
import carpet.script.value.ListValue;
import carpet.script.value.NBTSerializableValue;
@@ -67,7 +68,7 @@ public class Inventories {
CarpetContext cc = (CarpetContext)c;
TagManager tagManager = cc.s.getServer().getTagManager();
String tag = lv.get(0).getString();
net.minecraft.tag.Tag<Item> itemTag = tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTag(new Identifier(tag));
net.minecraft.tag.Tag<Item> itemTag = tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTag(InputValidator.identifierOf(tag));
if (itemTag == null) return Value.NULL;
return ListValue.wrap(itemTag.values().stream().map(b -> ValueConversions.of(Registry.ITEM.getId(b))).collect(Collectors.toList()));
});
@@ -82,7 +83,7 @@ public class Inventories {
if (lv.size() == 1)
return ListValue.wrap(tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTags().entrySet().stream().filter(e -> e.getValue().contains(item)).map(e -> ValueConversions.of(e.getKey())).collect(Collectors.toList()));
String tag = lv.get(1).getString();
net.minecraft.tag.Tag<Item> itemTag = tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTag(new Identifier(tag));
net.minecraft.tag.Tag<Item> itemTag = tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTag(InputValidator.identifierOf(tag));
if (itemTag == null) return Value.NULL;
return BooleanValue.of(itemTag.contains(item));
});
@@ -96,17 +97,10 @@ public class Inventories {
if (lv.size() > 1)
{
String recipeType = lv.get(1).getString();
try
{
type = Registry.RECIPE_TYPE.get(new Identifier(recipeType));
}
catch (InvalidIdentifierException ignored)
{
throw new InternalExpressionException("Unknown crafting category: " + recipeType);
}
type = Registry.RECIPE_TYPE.get(InputValidator.identifierOf(recipeType));
}
List<Recipe<?>> recipes;
recipes = ((RecipeManagerInterface) cc.s.getServer().getRecipeManager()).getAllMatching(type, new Identifier(recipeName));
recipes = ((RecipeManagerInterface) cc.s.getServer().getRecipeManager()).getAllMatching(type, InputValidator.identifierOf(recipeName));
if (recipes.isEmpty())
return Value.NULL;
List<Value> recipesOutput = new ArrayList<>();
@@ -176,7 +170,7 @@ public class Inventories {
{
String itemStr = v.getString();
Item item;
Identifier id = new Identifier(itemStr);
Identifier id = InputValidator.identifierOf(itemStr);
item = Registry.ITEM.getOrEmpty(id).orElseThrow(() -> new ThrowStatement(itemStr, Throwables.UNKNOWN_ITEM));
if (!item.hasRecipeRemainder()) return Value.NULL;
return new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.ITEM.getId(item.getRecipeRemainder())));
@@ -9,6 +9,7 @@ import carpet.script.LazyValue;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.utils.InputValidator;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
import carpet.script.value.ListValue;
@@ -407,14 +408,7 @@ public class Scoreboards {
String id = lv.get(0).getString();
Identifier identifier;
try
{
identifier = new Identifier(id);
}
catch (InvalidIdentifierException invalidIdentifierException)
{
return Value.NULL;
}
identifier = InputValidator.identifierOf(id);
if(lv.size() == 1)
{
@@ -22,6 +22,7 @@ import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.utils.BiomeInfo;
import carpet.script.utils.InputValidator;
import carpet.script.utils.WorldTools;
import carpet.script.value.BlockValue;
import carpet.script.value.BooleanValue;
@@ -323,7 +324,7 @@ public class WorldAccess {
String poiType = lv.get(locator.offset+1).getString().toLowerCase(Locale.ROOT);
if (!"any".equals(poiType))
{
PointOfInterestType type = Registry.POINT_OF_INTEREST_TYPE.getOrEmpty(new Identifier(poiType))
PointOfInterestType type = Registry.POINT_OF_INTEREST_TYPE.getOrEmpty(InputValidator.identifierOf(poiType))
.orElseThrow(() -> new ThrowStatement(poiType, Throwables.UNKNOWN_POI));
condition = (tt) -> tt == type;
}
@@ -373,7 +374,7 @@ public class WorldAccess {
return Value.TRUE;
}
String poiTypeString = poi.getString().toLowerCase(Locale.ROOT);
PointOfInterestType type = Registry.POINT_OF_INTEREST_TYPE.getOrEmpty(new Identifier(poiTypeString))
PointOfInterestType type = Registry.POINT_OF_INTEREST_TYPE.getOrEmpty(InputValidator.identifierOf(poiTypeString))
.orElseThrow(() -> new ThrowStatement(poiTypeString, Throwables.UNKNOWN_POI));
int occupancy = 0;
if (locator.offset + 1 < lv.size())
@@ -828,7 +829,7 @@ public class WorldAccess {
{
playerBreak = true;
String itemString = val.getString();
item = Registry.ITEM.getOrEmpty(new Identifier(itemString))
item = Registry.ITEM.getOrEmpty(InputValidator.identifierOf(itemString))
.orElseThrow(() -> new ThrowStatement(itemString, Throwables.UNKNOWN_ITEM));
}
}
@@ -1137,7 +1138,7 @@ public class WorldAccess {
CarpetContext cc = (CarpetContext)c;
TagManager tagManager = cc.s.getServer().getTagManager();
String tag = lv.get(0).getString();
net.minecraft.tag.Tag<Block> blockTag = tagManager.getOrCreateTagGroup(Registry.BLOCK_KEY).getTag(new Identifier(tag));
net.minecraft.tag.Tag<Block> blockTag = tagManager.getOrCreateTagGroup(Registry.BLOCK_KEY).getTag(InputValidator.identifierOf(tag));
if (blockTag == null) return Value.NULL;
return ListValue.wrap(blockTag.values().stream().map(b -> ValueConversions.of(Registry.BLOCK.getId(b))).collect(Collectors.toList()));
});
@@ -1155,7 +1156,7 @@ public class WorldAccess {
return ListValue.wrap(tagManager.getOrCreateTagGroup(Registry.BLOCK_KEY).getTags().entrySet().stream().filter(e -> e.getValue().contains(target)).map(e -> ValueConversions.of(e.getKey())).collect(Collectors.toList()));
}
String tag = lv.get(blockLocator.offset).getString();
Tag<Block> blockTag = tagManager.getOrCreateTagGroup(Registry.BLOCK_KEY).getTag(new Identifier(tag));
Tag<Block> blockTag = tagManager.getOrCreateTagGroup(Registry.BLOCK_KEY).getTag(InputValidator.identifierOf(tag));
if (blockTag == null) return Value.NULL;
return BooleanValue.of(blockLocator.block.getBlockState().isIn(blockTag));
});
@@ -1171,7 +1172,7 @@ public class WorldAccess {
Biome biome;
if (locator.replacement != null)
{
biome = world.getRegistryManager().get(Registry.BIOME_KEY).get(new Identifier(locator.replacement));
biome = world.getRegistryManager().get(Registry.BIOME_KEY).get(InputValidator.identifierOf(locator.replacement));
if (biome == null) throw new ThrowStatement(locator.replacement, Throwables.UNKNOWN_BIOME) ;
}
else
@@ -1199,7 +1200,7 @@ public class WorldAccess {
throw new InternalExpressionException("'set_biome' needs a biome name as an argument");
String biomeName = lv.get(locator.offset+0).getString();
// from locatebiome command code
Biome biome = cc.s.getServer().getRegistryManager().get(Registry.BIOME_KEY).getOrEmpty(new Identifier(biomeName))
Biome biome = cc.s.getServer().getRegistryManager().get(Registry.BIOME_KEY).getOrEmpty(InputValidator.identifierOf(biomeName))
.orElseThrow(() -> new ThrowStatement(biomeName, Throwables.UNKNOWN_BIOME));
boolean doImmediateUpdate = true;
if (lv.size() > locator.offset+1)
@@ -1236,7 +1237,7 @@ public class WorldAccess {
String simpleStructureName = lv.get(locator.offset).getString().toLowerCase(Locale.ROOT);
//CarpetSettings.LOG.error(FeatureGenerator.featureToStructure.keySet().stream().collect(Collectors.joining(",")));
//CarpetSettings.LOG.error(FeatureGenerator.featureToStructure.values().stream().collect(Collectors.joining(",")));
StructureFeature<?> structureName = Registry.STRUCTURE_FEATURE.get(new Identifier(simpleStructureName));
StructureFeature<?> structureName = Registry.STRUCTURE_FEATURE.get(InputValidator.identifierOf(simpleStructureName));
if (structureName == null) return Value.NULL;
LongSet structureReferences = references.get(structureName);
if (structureReferences == null || structureReferences.isEmpty()) return ListValue.of();
@@ -1265,7 +1266,7 @@ public class WorldAccess {
if (!(requested instanceof NullValue))
{
String reqString = requested.getString();
structure = Registry.STRUCTURE_FEATURE.getOrEmpty(new Identifier(reqString))
structure = Registry.STRUCTURE_FEATURE.getOrEmpty(InputValidator.identifierOf(reqString))
.orElseThrow(() -> new ThrowStatement(reqString, Throwables.UNKNOWN_STRUCTURE));
}
if (lv.size() > locator.offset+1)
@@ -1326,7 +1327,7 @@ public class WorldAccess {
return MapValue.wrap(structureList);
}
String structureName = lv.get(locator.offset).getString().toLowerCase(Locale.ROOT);
return ValueConversions.of(structures.get(Registry.STRUCTURE_FEATURE.get(new Identifier(structureName))));
return ValueConversions.of(structures.get(Registry.STRUCTURE_FEATURE.get(InputValidator.identifierOf(structureName))));
});
expression.addContextFunction("set_structure", -1, (c, t, lv) ->
@@ -1,6 +1,9 @@
package carpet.script.utils;
import carpet.script.exception.InternalExpressionException;
import net.minecraft.util.Identifier;
import net.minecraft.util.InvalidIdentifierException;
import org.lwjgl.system.CallbackI;
import java.util.Locale;
@@ -13,4 +16,16 @@ public class InputValidator {
return simplified;
}
public static Identifier identifierOf(String string)
{
try
{
return new Identifier(string);
}
catch (InvalidIdentifierException iie)
{
throw new InternalExpressionException("Incorrect identifier format '"+string+"': "+iie.getMessage());
}
}
}
@@ -17,6 +17,7 @@ import carpet.script.CarpetScriptServer;
import carpet.script.EntityEventsGroup;
import carpet.script.argument.Vector3Argument;
import carpet.script.exception.InternalExpressionException;
import carpet.script.utils.InputValidator;
import com.google.common.collect.Sets;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -251,7 +252,7 @@ public class EntityValue extends Value
positive = false;
who = who.substring(1);
}
Tag<EntityType<?>> eTag = server.getTagManager().getOrCreateTagGroup(Registry.ENTITY_TYPE_KEY).getTag(new Identifier(who));
Tag<EntityType<?>> eTag = server.getTagManager().getOrCreateTagGroup(Registry.ENTITY_TYPE_KEY).getTag(InputValidator.identifierOf(who));
if (eTag == null) throw new InternalExpressionException(who+" is not a valid entity descriptor");
if (positive)
{
@@ -460,7 +461,7 @@ public class EntityValue extends Value
put("has_scoreboard_tag", (e, a) -> BooleanValue.of(e.getScoreboardTags().contains(a.getString())));
put("has_entity_tag", (e, a) -> {
Tag<EntityType<?>> tag = e.getServer().getTagManager().getOrCreateTagGroup(Registry.ENTITY_TYPE_KEY).getTag(new Identifier(a.getString()));
Tag<EntityType<?>> tag = e.getServer().getTagManager().getOrCreateTagGroup(Registry.ENTITY_TYPE_KEY).getTag(InputValidator.identifierOf(a.getString()));
if (tag == null) return Value.NULL;
return BooleanValue.of(e.getType().isIn(tag));
});
@@ -628,7 +629,7 @@ public class EntityValue extends Value
put("brain", (e, a) -> {
String module = a.getString();
MemoryModuleType<?> moduleType = Registry.MEMORY_MODULE_TYPE.get(new Identifier(module));
MemoryModuleType<?> moduleType = Registry.MEMORY_MODULE_TYPE.get(InputValidator.identifierOf(module));
if (moduleType == MemoryModuleType.DUMMY) return Value.NULL;
if (e instanceof LivingEntity)
{
@@ -723,7 +724,7 @@ public class EntityValue extends Value
return ListValue.wrap(effects);
}
String effectName = a.getString();
StatusEffect potion = Registry.STATUS_EFFECT.get(new Identifier(effectName));
StatusEffect potion = Registry.STATUS_EFFECT.get(InputValidator.identifierOf(effectName));
if (potion == null)
throw new InternalExpressionException("No such an effect: "+effectName);
if (!((LivingEntity) e).hasStatusEffect(potion))
@@ -867,7 +868,7 @@ public class EntityValue extends Value
AttributeContainer container = el.getAttributes();
return MapValue.wrap(Registry.ATTRIBUTE.stream().filter(container::hasAttribute).collect(Collectors.toMap(aa -> ValueConversions.of(Registry.ATTRIBUTE.getId(aa)), aa -> NumericValue.of(container.getValue(aa)))));
}
Identifier id = new Identifier(a.getString());
Identifier id = InputValidator.identifierOf(a.getString());
EntityAttribute attrib = Registry.ATTRIBUTE.getOrEmpty(id).orElseThrow(
() -> new InternalExpressionException("Unknown attribute: "+a.getString())
);
@@ -1379,7 +1380,7 @@ public class EntityValue extends Value
if (lv.size() >= 1 && lv.size() <= 6)
{
String effectName = lv.get(0).getString();
StatusEffect effect = Registry.STATUS_EFFECT.get(new Identifier(effectName));
StatusEffect effect = Registry.STATUS_EFFECT.get(InputValidator.identifierOf(effectName));
if (effect == null)
throw new InternalExpressionException("Wrong effect name: "+effectName);
if (lv.size() == 1)
@@ -1412,7 +1413,7 @@ public class EntityValue extends Value
else
{
String effectName = v.getString();
StatusEffect effect = Registry.STATUS_EFFECT.get(new Identifier(effectName));
StatusEffect effect = Registry.STATUS_EFFECT.get(InputValidator.identifierOf(effectName));
if (effect == null)
throw new InternalExpressionException("Wrong effect name: "+effectName);
le.removeStatusEffect(effect);