From 990a377f0befd14ec57bcb309e9f433cf580b5f1 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 7 Dec 2020 13:38:02 +0100 Subject: [PATCH 1/6] Adding convert_date and unix_time to docs (#614) --- docs/scarpet/resources/editors/idea/2.txt | 4 +++- docs/scarpet/resources/editors/npp/scarpet.xml | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/scarpet/resources/editors/idea/2.txt b/docs/scarpet/resources/editors/idea/2.txt index 397c1760..25f4e954 100644 --- a/docs/scarpet/resources/editors/idea/2.txt +++ b/docs/scarpet/resources/editors/idea/2.txt @@ -15,6 +15,7 @@ blocks_movement bossbar brightness chunk_tickets +convert_date crafting_remaining_item create_marker current_dimension @@ -125,8 +126,9 @@ ticks_randomly top transparent update +unix_time view_distance volume without_updates world_time -write_file \ No newline at end of file +write_file diff --git a/docs/scarpet/resources/editors/npp/scarpet.xml b/docs/scarpet/resources/editors/npp/scarpet.xml index 759e69d0..81706a3d 100644 --- a/docs/scarpet/resources/editors/npp/scarpet.xml +++ b/docs/scarpet/resources/editors/npp/scarpet.xml @@ -58,6 +58,8 @@ structure_eligibility structures structure_references set_structure reset_chunk reload_chunk custom_dimension add_chunk_ticket + convert_date unix_time + display_title scoreboard scoreboard_add scoreboard_remove scoreboard_display From bf0b75ebff7d878415db99ecbb40c0dd95293913 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 7 Dec 2020 13:39:04 +0100 Subject: [PATCH 2/6] adding dev_environment (#615) --- docs/scarpet/api/Auxiliary.md | 1 + src/main/java/carpet/script/utils/SystemInfo.java | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index 06fa8784..49a24255 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -507,6 +507,7 @@ Available options in the scarpet app space: * `server_whitelist` - list of players allowed to log in * `server_banned_players` - list of banned player names * `server_banned_ips` - list of banned IP addresses + * `server_dev_environment` - boolean indicating whether this server is in a development environment. System related properties * `java_max_memory` - maximum allowed memory accessible by JVM diff --git a/src/main/java/carpet/script/utils/SystemInfo.java b/src/main/java/carpet/script/utils/SystemInfo.java index e5984e7b..8d1ac7c2 100644 --- a/src/main/java/carpet/script/utils/SystemInfo.java +++ b/src/main/java/carpet/script/utils/SystemInfo.java @@ -12,6 +12,7 @@ import carpet.script.value.Value; import carpet.settings.ParsedRule; import carpet.settings.SettingsManager; import com.sun.management.OperatingSystemMXBean; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.util.WorldSavePath; import net.minecraft.world.GameRules; @@ -82,6 +83,7 @@ public class SystemInfo { } return whitelist; }); + put("server_dev_environment", c-> new NumericValue(FabricLoader.getInstance().isDevelopmentEnvironment())); put("java_max_memory", c -> new NumericValue(Runtime.getRuntime().maxMemory())); put("java_allocated_memory", c -> new NumericValue(Runtime.getRuntime().totalMemory())); @@ -117,7 +119,7 @@ public class SystemInfo { CarpetServer.extensions.forEach(e -> { SettingsManager manager = e.customSettingsManager(); if (manager == null) return; - + Collection> extensionRules = manager.getRules(); extensionRules.forEach(rule -> { carpetRules.put(new StringValue(manager.getIdentifier()+":"+rule.name), new StringValue(rule.getAsString())); From c7554c888e065c9b1c4e806e5434c495c2131ae8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Dec 2020 12:39:25 +0000 Subject: [PATCH 3/6] Merge docs for 'adding dev_environment (#615)' --- docs/scarpet/Full.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index 78b53a0d..5b25bd4e 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -4929,6 +4929,7 @@ Available options in the scarpet app space: * `server_whitelist` - list of players allowed to log in * `server_banned_players` - list of banned player names * `server_banned_ips` - list of banned IP addresses + * `server_dev_environment` - boolean indicating whether this server is in a development environment. System related properties * `java_max_memory` - maximum allowed memory accessible by JVM From f54a0989483eb9119bd206031b345a252780fd16 Mon Sep 17 00:00:00 2001 From: gnembon Date: Mon, 7 Dec 2020 16:03:42 -0400 Subject: [PATCH 4/6] allow apps define their own command permission level, fixes #542 --- docs/scarpet/api/Overview.md | 20 ++++++-- .../java/carpet/script/CarpetScriptHost.java | 48 ++++++++++++++++++- .../carpet/script/CarpetScriptServer.java | 14 +++++- 3 files changed, 74 insertions(+), 8 deletions(-) diff --git a/docs/scarpet/api/Overview.md b/docs/scarpet/api/Overview.md index 4f1da73c..7ec68245 100644 --- a/docs/scarpet/api/Overview.md +++ b/docs/scarpet/api/Overview.md @@ -38,10 +38,9 @@ To access global/server state for a player app, which you shouldn't do, you need so either use a command block, or any arbitrary entity: `/execute as @e[type=bat,limit=1] run script in globals` for instance, however running anything in the global scope for a `'player'` scoped app is not intended. -* `'stay_loaded'`: defaults to `false`. If true, and `/carpet scriptsAutoload` is turned on, the following apps will +* `'stay_loaded'`: defaults to `true`. If true, and `/carpet scriptsAutoload` is turned on, the following apps will stay loaded after startup. Otherwise, after reading the app the first time, and fetching the config, server will drop them down. -This is to allow to store multiple apps on the server/world and selectively decide which one should be running at -startup. WARNING: all apps will run once at startup anyways, so be aware that their actions that are called + WARNING: all apps will run once at startup anyways, so be aware that their actions that are called statically, will be performed once anyways. Only apps present in the world's `scripts` folder will be autoloaded. * `'legacy_command_type_support'` - if `true`, and the app defines the legacy command system via `__command()` function, all parameters of command functions will be interpreted and used using brigadier / vanilla style argument parser and their type @@ -52,9 +51,20 @@ conflicts and ambiguities between different paths of execution. While ambiguous and they tend to execute correctly, the suggestion support works really poorly in these situations and scarpet will warn and prevent such apps from loading with an error message. If `allow_command_conflicts` is specified and `true`, then scarpet will load all provided commands regardless. +* `'command_permission'` - indicates a custom permission to run the command. It can either be a number indicating +permission level (from 1 to 4) or a string value, one of: `'all'` (default), `'ops'` (default opped player with permission level of 2), +`'server'` - command accessible only through the server console and commandblocks, but not in chat, `'players'` - opposite +of the former, allowing only use in player chat. It can also be a function (lambda function or function value, not function name) +that takes 1 parameter, which represents the calling player, or `'null'` if the command represents a server call. +The function will prevent the command from running if it evaluates to `false`. +Please note, that Minecraft evaluates eligible commands for players when they join, or on reload/restart, so if you use a +predicate that is volatile and might change, the command might falsely do or do not indicate that it is available to the player, +however player will always be able to type it in and either succeed, or fail, based on their current permissions. +Custom permission applies to legacy commands with `'legacy_command_type_support'` as well +as for the custom commands defined with `'commands'`, see below. * `'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 `/` command, see below +as for the custom commands defined with `'commands'`, see below. +* `'commands'` - defines custom commands for the app to be executed with `/` command, see below. ## Custom app commands diff --git a/src/main/java/carpet/script/CarpetScriptHost.java b/src/main/java/carpet/script/CarpetScriptHost.java index 12eff864..09e08153 100644 --- a/src/main/java/carpet/script/CarpetScriptHost.java +++ b/src/main/java/carpet/script/CarpetScriptHost.java @@ -11,6 +11,7 @@ import carpet.script.exception.CarpetExpressionException; import carpet.script.exception.ExpressionException; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.InvalidCallbackException; +import carpet.script.value.EntityValue; import carpet.script.value.FunctionValue; import carpet.script.value.MapValue; import carpet.script.value.NumericValue; @@ -38,6 +39,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @@ -163,8 +165,9 @@ public class CarpetScriptHost extends ScriptHost ) throws CommandSyntaxException { String hostName = main.getName(); + Function configValidator = getCommandConfigPermissions(); LiteralArgumentBuilder command = literal(hostName). - requires((player) -> CarpetServer.scriptServer.modules.containsKey(hostName) && useValidator.apply(player)); + requires((player) -> CarpetServer.scriptServer.modules.containsKey(hostName) && useValidator.apply(player) && configValidator.apply(player)); for (Pair,FunctionArgument> commandData : entries) { command = this.addPathToCommand(command, commandData.getKey(), commandData.getValue()); @@ -172,6 +175,49 @@ public class CarpetScriptHost extends ScriptHost return command; } + public Function getCommandConfigPermissions() throws CommandSyntaxException + { + Value confValue = appConfig.get(StringValue.of("command_permission")); + if (confValue == null) return s -> true; + if (confValue instanceof NumericValue) + { + int level = ((NumericValue) confValue).getInt(); + if (level < 1 || level > 4) throw CommandArgument.error("Numeric permission level for custom commands should be between 1 and 4"); + return s -> s.hasPermissionLevel(level); + } + if (!(confValue instanceof FunctionValue)) + { + String perm = confValue.getString().toLowerCase(Locale.ROOT); + switch (perm) + { + case "ops": return s -> s.hasPermissionLevel(2); + case "server": return s -> !(s.getEntity() instanceof ServerPlayerEntity); + case "players": return s -> s.getEntity() instanceof ServerPlayerEntity; + case "all": return s -> true; + default: throw CommandArgument.error("Unknown command permission: "+perm); + } + } + FunctionValue fun = (FunctionValue) confValue; + if (fun.getNumParams() != 1) throw CommandArgument.error("Custom command permission function should expect 1 argument"); + String hostName = getName(); + return s -> { + try + { + CarpetScriptHost cHost = null; + cHost = CarpetServer.scriptServer.modules.get(hostName).retrieveOwnForExecution(s); + Value response = cHost.handleCommand(s, fun, Collections.singletonList( + (s.getEntity() instanceof ServerPlayerEntity)?new EntityValue(s.getEntity()):Value.NULL) + ); + return response.getBoolean(); + } + catch (CommandSyntaxException e) + { + Messenger.m(s, "rb Unable to run app command: "+e.getMessage()); + return false; + } + }; + } + @Override protected ScriptHost duplicate() { diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index 41b2fc34..7f0a3f2c 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -221,7 +221,6 @@ public class CarpetScriptServer public boolean addScriptHost(ServerCommandSource source, String name, Function commandValidator, boolean perPlayer, boolean autoload, boolean isRuleApp) { - //TODO add per player modules to support player actions better on a server if (commandValidator == null) commandValidator = p -> true; long start = System.nanoTime(); name = name.toLowerCase(Locale.ROOT); @@ -325,8 +324,19 @@ public class CarpetScriptServer return true; } + Function configValidator; + try + { + configValidator = host.getCommandConfigPermissions(); + } + catch (CommandSyntaxException e) + { + Messenger.m(source, "rb "+e.getMessage()); + return false; + } + LiteralArgumentBuilder command = literal(hostName). - requires((player) -> modules.containsKey(hostName) && useValidator.apply(player)). + requires((player) -> modules.containsKey(hostName) && useValidator.apply(player) && configValidator.apply(player)). executes( (c) -> { CarpetScriptHost targetHost = modules.get(hostName).retrieveOwnForExecution(c.getSource()); From 15853095920ba4215a365b761469f5a7bd7ca1e8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Dec 2020 16:04:19 +0000 Subject: [PATCH 5/6] Merge docs for 'allow apps define their own command permission level, fixes #542' --- docs/scarpet/Full.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index 5b25bd4e..14f87168 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -1789,10 +1789,9 @@ To access global/server state for a player app, which you shouldn't do, you need so either use a command block, or any arbitrary entity: `/execute as @e[type=bat,limit=1] run script in globals` for instance, however running anything in the global scope for a `'player'` scoped app is not intended. -* `'stay_loaded'`: defaults to `false`. If true, and `/carpet scriptsAutoload` is turned on, the following apps will +* `'stay_loaded'`: defaults to `true`. If true, and `/carpet scriptsAutoload` is turned on, the following apps will stay loaded after startup. Otherwise, after reading the app the first time, and fetching the config, server will drop them down. -This is to allow to store multiple apps on the server/world and selectively decide which one should be running at -startup. WARNING: all apps will run once at startup anyways, so be aware that their actions that are called + WARNING: all apps will run once at startup anyways, so be aware that their actions that are called statically, will be performed once anyways. Only apps present in the world's `scripts` folder will be autoloaded. * `'legacy_command_type_support'` - if `true`, and the app defines the legacy command system via `__command()` function, all parameters of command functions will be interpreted and used using brigadier / vanilla style argument parser and their type @@ -1803,9 +1802,20 @@ conflicts and ambiguities between different paths of execution. While ambiguous and they tend to execute correctly, the suggestion support works really poorly in these situations and scarpet will warn and prevent such apps from loading with an error message. If `allow_command_conflicts` is specified and `true`, then scarpet will load all provided commands regardless. +* `'command_permission'` - indicates a custom permission to run the command. It can either be a number indicating +permission level (from 1 to 4) or a string value, one of: `'all'` (default), `'ops'` (default opped player with permission level of 2), +`'server'` - command accessible only through the server console and commandblocks, but not in chat, `'players'` - opposite +of the former, allowing only use in player chat. It can also be a function (lambda function or function value, not function name) +that takes 1 parameter, which represents the calling player, or `'null'` if the command represents a server call. +The function will prevent the command from running if it evaluates to `false`. +Please note, that Minecraft evaluates eligible commands for players when they join, or on reload/restart, so if you use a +predicate that is volatile and might change, the command might falsely do or do not indicate that it is available to the player, +however player will always be able to type it in and either succeed, or fail, based on their current permissions. +Custom permission applies to legacy commands with `'legacy_command_type_support'` as well +as for the custom commands defined with `'commands'`, see below. * `'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 `/` command, see below +as for the custom commands defined with `'commands'`, see below. +* `'commands'` - defines custom commands for the app to be executed with `/` command, see below. ## Custom app commands From bf9aa3207a37d4c2a4d511a6eab0f333c972e83d Mon Sep 17 00:00:00 2001 From: altrisi Date: Mon, 7 Dec 2020 22:30:04 +0100 Subject: [PATCH 6/6] Fix optimizedTNT entity behaviour (#617) Fixes gnembon#616 --- src/main/java/carpet/helpers/OptimizedExplosion.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/carpet/helpers/OptimizedExplosion.java b/src/main/java/carpet/helpers/OptimizedExplosion.java index ddaaa92d..3130f30a 100644 --- a/src/main/java/carpet/helpers/OptimizedExplosion.java +++ b/src/main/java/carpet/helpers/OptimizedExplosion.java @@ -132,7 +132,8 @@ public class OptimizedExplosion if (d12 <= 1.0D) { double d5 = entity.getX() - eAccess.getX(); - double d7 = entity.getY() + (double) entity.getStandingEyeHeight() - eAccess.getY(); + // Change in 1.16 snapshots to fix a bug with TNT jumping + double d7 = (entity instanceof TntEntity ? entity.getY() : entity.getEyeY()) - eAccess.getY(); double d9 = entity.getZ() - eAccess.getZ(); double d13 = (double) MathHelper.sqrt(d5 * d5 + d7 * d7 + d9 * d9);