Merge branch 'master' into 1.17
This commit is contained in:
commit
947474e9e9
9 files changed
+101
-16
No files matched your search
+16
-5
@@ -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
|
so either use a command block, or any
|
||||||
arbitrary entity: `/execute as @e[type=bat,limit=1] run script in <app> globals` for instance, however
|
arbitrary entity: `/execute as @e[type=bat,limit=1] run script in <app> globals` for instance, however
|
||||||
running anything in the global scope for a `'player'` scoped app is not intended.
|
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.
|
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
|
WARNING: all apps will run once at startup anyways, so be aware that their actions that are called
|
||||||
startup. 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.
|
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,
|
* `'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
|
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
|
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
|
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.
|
`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
|
* `'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
|
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
|
* `'commands'` - defines custom commands for the app to be executed with `/<app>` command, see below.
|
||||||
|
|
||||||
## Custom app commands
|
## Custom app commands
|
||||||
|
|
||||||
@@ -4929,6 +4939,7 @@ Available options in the scarpet app space:
|
|||||||
* `server_whitelist` - list of players allowed to log in
|
* `server_whitelist` - list of players allowed to log in
|
||||||
* `server_banned_players` - list of banned player names
|
* `server_banned_players` - list of banned player names
|
||||||
* `server_banned_ips` - list of banned IP addresses
|
* `server_banned_ips` - list of banned IP addresses
|
||||||
|
* `server_dev_environment` - boolean indicating whether this server is in a development environment.
|
||||||
|
|
||||||
System related properties
|
System related properties
|
||||||
* `java_max_memory` - maximum allowed memory accessible by JVM
|
* `java_max_memory` - maximum allowed memory accessible by JVM
|
||||||
|
|||||||
@@ -507,6 +507,7 @@ Available options in the scarpet app space:
|
|||||||
* `server_whitelist` - list of players allowed to log in
|
* `server_whitelist` - list of players allowed to log in
|
||||||
* `server_banned_players` - list of banned player names
|
* `server_banned_players` - list of banned player names
|
||||||
* `server_banned_ips` - list of banned IP addresses
|
* `server_banned_ips` - list of banned IP addresses
|
||||||
|
* `server_dev_environment` - boolean indicating whether this server is in a development environment.
|
||||||
|
|
||||||
System related properties
|
System related properties
|
||||||
* `java_max_memory` - maximum allowed memory accessible by JVM
|
* `java_max_memory` - maximum allowed memory accessible by JVM
|
||||||
|
|||||||
@@ -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
|
so either use a command block, or any
|
||||||
arbitrary entity: `/execute as @e[type=bat,limit=1] run script in <app> globals` for instance, however
|
arbitrary entity: `/execute as @e[type=bat,limit=1] run script in <app> globals` for instance, however
|
||||||
running anything in the global scope for a `'player'` scoped app is not intended.
|
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.
|
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
|
WARNING: all apps will run once at startup anyways, so be aware that their actions that are called
|
||||||
startup. 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.
|
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,
|
* `'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
|
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
|
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
|
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.
|
`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
|
* `'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
|
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
|
* `'commands'` - defines custom commands for the app to be executed with `/<app>` command, see below.
|
||||||
|
|
||||||
## Custom app commands
|
## Custom app commands
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ blocks_movement
|
|||||||
bossbar
|
bossbar
|
||||||
brightness
|
brightness
|
||||||
chunk_tickets
|
chunk_tickets
|
||||||
|
convert_date
|
||||||
crafting_remaining_item
|
crafting_remaining_item
|
||||||
create_marker
|
create_marker
|
||||||
current_dimension
|
current_dimension
|
||||||
@@ -125,8 +126,9 @@ ticks_randomly
|
|||||||
top
|
top
|
||||||
transparent
|
transparent
|
||||||
update
|
update
|
||||||
|
unix_time
|
||||||
view_distance
|
view_distance
|
||||||
volume
|
volume
|
||||||
without_updates
|
without_updates
|
||||||
world_time
|
world_time
|
||||||
write_file
|
write_file
|
||||||
@@ -58,6 +58,8 @@
|
|||||||
structure_eligibility structures structure_references set_structure reset_chunk reload_chunk custom_dimension
|
structure_eligibility structures structure_references set_structure reset_chunk reload_chunk custom_dimension
|
||||||
add_chunk_ticket
|
add_chunk_ticket
|
||||||
|
|
||||||
|
convert_date unix_time
|
||||||
|
|
||||||
display_title
|
display_title
|
||||||
|
|
||||||
scoreboard scoreboard_add scoreboard_remove scoreboard_display
|
scoreboard scoreboard_add scoreboard_remove scoreboard_display
|
||||||
|
|||||||
@@ -132,7 +132,8 @@ public class OptimizedExplosion
|
|||||||
|
|
||||||
if (d12 <= 1.0D) {
|
if (d12 <= 1.0D) {
|
||||||
double d5 = entity.getX() - eAccess.getX();
|
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 d9 = entity.getZ() - eAccess.getZ();
|
||||||
double d13 = (double) MathHelper.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
|
double d13 = (double) MathHelper.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import carpet.script.exception.CarpetExpressionException;
|
|||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.exception.InvalidCallbackException;
|
import carpet.script.exception.InvalidCallbackException;
|
||||||
|
import carpet.script.value.EntityValue;
|
||||||
import carpet.script.value.FunctionValue;
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.MapValue;
|
import carpet.script.value.MapValue;
|
||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
@@ -38,6 +39,7 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -163,8 +165,9 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
) throws CommandSyntaxException
|
) throws CommandSyntaxException
|
||||||
{
|
{
|
||||||
String hostName = main.getName();
|
String hostName = main.getName();
|
||||||
|
Function<ServerCommandSource, Boolean> configValidator = getCommandConfigPermissions();
|
||||||
LiteralArgumentBuilder<ServerCommandSource> command = literal(hostName).
|
LiteralArgumentBuilder<ServerCommandSource> 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<List<CommandToken>,FunctionArgument<Value>> commandData : entries)
|
for (Pair<List<CommandToken>,FunctionArgument<Value>> commandData : entries)
|
||||||
{
|
{
|
||||||
command = this.addPathToCommand(command, commandData.getKey(), commandData.getValue());
|
command = this.addPathToCommand(command, commandData.getKey(), commandData.getValue());
|
||||||
@@ -172,6 +175,49 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Function<ServerCommandSource, Boolean> 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
|
@Override
|
||||||
protected ScriptHost duplicate()
|
protected ScriptHost duplicate()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -221,7 +221,6 @@ public class CarpetScriptServer
|
|||||||
public boolean addScriptHost(ServerCommandSource source, String name, Function<ServerCommandSource, Boolean> commandValidator,
|
public boolean addScriptHost(ServerCommandSource source, String name, Function<ServerCommandSource, Boolean> commandValidator,
|
||||||
boolean perPlayer, boolean autoload, boolean isRuleApp)
|
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;
|
if (commandValidator == null) commandValidator = p -> true;
|
||||||
long start = System.nanoTime();
|
long start = System.nanoTime();
|
||||||
name = name.toLowerCase(Locale.ROOT);
|
name = name.toLowerCase(Locale.ROOT);
|
||||||
@@ -325,8 +324,19 @@ public class CarpetScriptServer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Function<ServerCommandSource, Boolean> configValidator;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
configValidator = host.getCommandConfigPermissions();
|
||||||
|
}
|
||||||
|
catch (CommandSyntaxException e)
|
||||||
|
{
|
||||||
|
Messenger.m(source, "rb "+e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LiteralArgumentBuilder<ServerCommandSource> command = literal(hostName).
|
LiteralArgumentBuilder<ServerCommandSource> command = literal(hostName).
|
||||||
requires((player) -> modules.containsKey(hostName) && useValidator.apply(player)).
|
requires((player) -> modules.containsKey(hostName) && useValidator.apply(player) && configValidator.apply(player)).
|
||||||
executes( (c) ->
|
executes( (c) ->
|
||||||
{
|
{
|
||||||
CarpetScriptHost targetHost = modules.get(hostName).retrieveOwnForExecution(c.getSource());
|
CarpetScriptHost targetHost = modules.get(hostName).retrieveOwnForExecution(c.getSource());
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import carpet.script.value.Value;
|
|||||||
import carpet.settings.ParsedRule;
|
import carpet.settings.ParsedRule;
|
||||||
import carpet.settings.SettingsManager;
|
import carpet.settings.SettingsManager;
|
||||||
import com.sun.management.OperatingSystemMXBean;
|
import com.sun.management.OperatingSystemMXBean;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.util.WorldSavePath;
|
import net.minecraft.util.WorldSavePath;
|
||||||
import net.minecraft.world.GameRules;
|
import net.minecraft.world.GameRules;
|
||||||
|
|
||||||
@@ -82,6 +83,7 @@ public class SystemInfo {
|
|||||||
}
|
}
|
||||||
return whitelist;
|
return whitelist;
|
||||||
});
|
});
|
||||||
|
put("server_dev_environment", c-> new NumericValue(FabricLoader.getInstance().isDevelopmentEnvironment()));
|
||||||
|
|
||||||
put("java_max_memory", c -> new NumericValue(Runtime.getRuntime().maxMemory()));
|
put("java_max_memory", c -> new NumericValue(Runtime.getRuntime().maxMemory()));
|
||||||
put("java_allocated_memory", c -> new NumericValue(Runtime.getRuntime().totalMemory()));
|
put("java_allocated_memory", c -> new NumericValue(Runtime.getRuntime().totalMemory()));
|
||||||
@@ -117,7 +119,7 @@ public class SystemInfo {
|
|||||||
CarpetServer.extensions.forEach(e -> {
|
CarpetServer.extensions.forEach(e -> {
|
||||||
SettingsManager manager = e.customSettingsManager();
|
SettingsManager manager = e.customSettingsManager();
|
||||||
if (manager == null) return;
|
if (manager == null) return;
|
||||||
|
|
||||||
Collection<ParsedRule<?>> extensionRules = manager.getRules();
|
Collection<ParsedRule<?>> extensionRules = manager.getRules();
|
||||||
extensionRules.forEach(rule -> {
|
extensionRules.forEach(rule -> {
|
||||||
carpetRules.put(new StringValue(manager.getIdentifier()+":"+rule.name), new StringValue(rule.getAsString()));
|
carpetRules.put(new StringValue(manager.getIdentifier()+":"+rule.name), new StringValue(rule.getAsString()));
|
||||||
|
|||||||
Reference in new issue
Block a user