Merge branch 'master' into future
This commit is contained in:
commit
6a03675b4f
16 files changed
+161
-36
No files matched your search
@@ -1,5 +1,13 @@
|
|||||||
|
<img src="./src/main/resources/assets/carpet/icon.png" align="right" width="128px"/>
|
||||||
|
|
||||||
# Fabric Carpet
|
# Fabric Carpet
|
||||||
|
|
||||||
|
[](https://github.com/gnembon/fabric-carpet/actions?query=workflow%3A%22Development+Builds%22)
|
||||||
|
[](https://www.curseforge.com/minecraft/mc-mods/carpet)
|
||||||
|
[](https://github.com/gnembon/fabric-carpet/releases)
|
||||||
|
[](https://github.com/gnembon/fabric-carpet/graphs/contributors)
|
||||||
|
[](https://discord.gg/gn99m4QRY4)
|
||||||
|
|
||||||
Cause all carpets are made of fabric?
|
Cause all carpets are made of fabric?
|
||||||
This is the [Fabric](https://fabricmc.net/) version of Carpet Mod, for Minecraft 1.14.X, 1.15.X, 1.16.X and above.
|
This is the [Fabric](https://fabricmc.net/) version of Carpet Mod, for Minecraft 1.14.X, 1.15.X, 1.16.X and above.
|
||||||
|
|
||||||
@@ -15,6 +23,8 @@ Carpet Mod is a mod for vanilla Minecraft that allows you to take full control o
|
|||||||
|
|
||||||
For core carpet functionality, this is the right place. Check available downloads on the [release page](https://github.com/gnembon/fabric-carpet/releases)
|
For core carpet functionality, this is the right place. Check available downloads on the [release page](https://github.com/gnembon/fabric-carpet/releases)
|
||||||
|
|
||||||
|
<img src="https://raw.githubusercontent.com/gnembon/carpet-extra/master/src/main/resources/assets/carpet-extra/icon.png" align="right" width="128px"/>
|
||||||
|
|
||||||
## carpet-extra
|
## carpet-extra
|
||||||
|
|
||||||
Check [carpet-extra](https://github.com/gnembon/carpet-extra/) add-on mod for more whacky and crazy features, including autocrafting, block-placing dispensers, and even chicken-shearing!
|
Check [carpet-extra](https://github.com/gnembon/carpet-extra/) add-on mod for more whacky and crazy features, including autocrafting, block-placing dispensers, and even chicken-shearing!
|
||||||
|
|||||||
@@ -540,6 +540,8 @@ Returns server tick counter. Can be used to run certain operations every n-th ti
|
|||||||
|
|
||||||
### `world_time()`
|
### `world_time()`
|
||||||
|
|
||||||
|
_**Deprecated**. Use `system_info('world_time')` instead._
|
||||||
|
|
||||||
Returns dimension-specific tick counter.
|
Returns dimension-specific tick counter.
|
||||||
|
|
||||||
### `day_time(new_time?)`
|
### `day_time(new_time?)`
|
||||||
@@ -549,6 +551,8 @@ to that value. Daytime clocks are shared between all dimensions.
|
|||||||
|
|
||||||
### `last_tick_times()`
|
### `last_tick_times()`
|
||||||
|
|
||||||
|
_**Deprecated**. Use `system_info('server_last_tick_times')` instead._
|
||||||
|
|
||||||
Returns a 100-long array of recent tick times, in milliseconds. First item on the list is the most recent tick
|
Returns a 100-long array of recent tick times, in milliseconds. First item on the list is the most recent tick
|
||||||
If called outside of the main tick (either throgh scheduled tasks, or async execution), then the first item on the
|
If called outside of the main tick (either throgh scheduled tasks, or async execution), then the first item on the
|
||||||
list may refer to the previous tick performance. In this case the last entry (tick 100) would refer to the most current
|
list may refer to the previous tick performance. In this case the last entry (tick 100) would refer to the most current
|
||||||
@@ -600,6 +604,9 @@ world-localized block, so not `block('stone')`, or a string representing a dimen
|
|||||||
Throws `unknown_dimension` if provided dimension can't be found.
|
Throws `unknown_dimension` if provided dimension can't be found.
|
||||||
|
|
||||||
### `view_distance()`
|
### `view_distance()`
|
||||||
|
|
||||||
|
_**Deprecated**. Use `system_info('server_view_distance')` instead._
|
||||||
|
|
||||||
Returns the view distance of the server.
|
Returns the view distance of the server.
|
||||||
|
|
||||||
### `get_mob_counts()`, `get_mob_counts(category)` 1.16+
|
### `get_mob_counts()`, `get_mob_counts(category)` 1.16+
|
||||||
@@ -659,6 +666,7 @@ Available options in the scarpet app space:
|
|||||||
* `world_carpet_rules` - returns all Carpet rules in a map form (`rule`->`value`). Note that the values are always returned as strings, so you can't do boolean comparisons directly. Includes rules from extensions with their namespace (`namespace:rule`->`value`). You can later listen to rule changes with the `on_carpet_rule_changes(rule, newValue)` event.
|
* `world_carpet_rules` - returns all Carpet rules in a map form (`rule`->`value`). Note that the values are always returned as strings, so you can't do boolean comparisons directly. Includes rules from extensions with their namespace (`namespace:rule`->`value`). You can later listen to rule changes with the `on_carpet_rule_changes(rule, newValue)` event.
|
||||||
* `world_gamerules` - returns all gamerules in a map form (`rule`->`value`). Like carpet rules, values are returned as strings, so you can use appropriate value conversions using `bool()` or `number()` to convert them to other values. Gamerules are read-only to discourage app programmers to mess up with the settings intentionally applied by server admins. Isn't that just super annoying when a datapack messes up with your gamerule settings? It is still possible to change them though using `run('gamerule ...`.
|
* `world_gamerules` - returns all gamerules in a map form (`rule`->`value`). Like carpet rules, values are returned as strings, so you can use appropriate value conversions using `bool()` or `number()` to convert them to other values. Gamerules are read-only to discourage app programmers to mess up with the settings intentionally applied by server admins. Isn't that just super annoying when a datapack messes up with your gamerule settings? It is still possible to change them though using `run('gamerule ...`.
|
||||||
* `world_spawn_point` - world spawn point
|
* `world_spawn_point` - world spawn point
|
||||||
|
* `world_time` - Returns dimension-specific tick counter.
|
||||||
|
|
||||||
Relevant gameplay related properties
|
Relevant gameplay related properties
|
||||||
* `game_difficulty` - current difficulty of the game: `'peaceful'`, `'easy'`, `'normal'`, or `'hard'`
|
* `game_difficulty` - current difficulty of the game: `'peaceful'`, `'easy'`, `'normal'`, or `'hard'`
|
||||||
@@ -686,6 +694,11 @@ Available options in the scarpet app space:
|
|||||||
* `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.
|
* `server_dev_environment` - boolean indicating whether this server is in a development environment.
|
||||||
* `server_mods` - map with all loaded mods mapped to their versions as strings
|
* `server_mods` - map with all loaded mods mapped to their versions as strings
|
||||||
|
* `server_last_tick_times` - Returns a 100-long array of recent tick times, in milliseconds. First item on the list is the most recent tick
|
||||||
|
If called outside of the main tick (either throgh scheduled tasks, or async execution), then the first item on the
|
||||||
|
list may refer to the previous tick performance. In this case the last entry (tick 100) would refer to the most current
|
||||||
|
tick. For all intent and purpose, `system_info('last_tick_times'):0` should be used as last tick execution time, but
|
||||||
|
individual tick times may vary greatly, and these need to be taken with the little grain of averaging.
|
||||||
|
|
||||||
System related properties
|
System related properties
|
||||||
* `java_max_memory` - maximum allowed memory accessible by JVM
|
* `java_max_memory` - maximum allowed memory accessible by JVM
|
||||||
|
|||||||
@@ -513,6 +513,9 @@ public class CarpetSettings
|
|||||||
@Rule(desc = "placing blocks cause block updates", category = CREATIVE)
|
@Rule(desc = "placing blocks cause block updates", category = CREATIVE)
|
||||||
public static boolean interactionUpdates = true;
|
public static boolean interactionUpdates = true;
|
||||||
|
|
||||||
|
@Rule(desc = "Disables breaking of blocks caused by flowing liquids", category = CREATIVE)
|
||||||
|
public static boolean liquidDamageDisabled = false;
|
||||||
|
|
||||||
@Rule(
|
@Rule(
|
||||||
desc = "smooth client animations with low tps settings",
|
desc = "smooth client animations with low tps settings",
|
||||||
extra = "works only in SP, and will slow down players",
|
extra = "works only in SP, and will slow down players",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static net.minecraft.server.command.CommandManager.argument;
|
import static net.minecraft.server.command.CommandManager.argument;
|
||||||
import static net.minecraft.server.command.CommandManager.literal;
|
import static net.minecraft.server.command.CommandManager.literal;
|
||||||
@@ -46,6 +47,10 @@ public class PlayerCommand
|
|||||||
// TODO: allow any order like execute
|
// TODO: allow any order like execute
|
||||||
public static void register(CommandDispatcher<ServerCommandSource> dispatcher)
|
public static void register(CommandDispatcher<ServerCommandSource> dispatcher)
|
||||||
{
|
{
|
||||||
|
final String[] gamemodeStrings = Arrays.stream(GameMode.values())
|
||||||
|
.map(GameMode::getName)
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.toArray(new String[]{});
|
||||||
LiteralArgumentBuilder<ServerCommandSource> literalargumentbuilder = literal("player")
|
LiteralArgumentBuilder<ServerCommandSource> literalargumentbuilder = literal("player")
|
||||||
.requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandPlayer))
|
.requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandPlayer))
|
||||||
.then(argument("player", StringArgumentType.word())
|
.then(argument("player", StringArgumentType.word())
|
||||||
@@ -93,10 +98,18 @@ public class PlayerCommand
|
|||||||
.then(literal("left").executes(c -> manipulate(c, ap -> ap.setStrafing(1))))
|
.then(literal("left").executes(c -> manipulate(c, ap -> ap.setStrafing(1))))
|
||||||
.then(literal("right").executes(c -> manipulate(c, ap -> ap.setStrafing(-1))))
|
.then(literal("right").executes(c -> manipulate(c, ap -> ap.setStrafing(-1))))
|
||||||
).then(literal("spawn").executes(PlayerCommand::spawn)
|
).then(literal("spawn").executes(PlayerCommand::spawn)
|
||||||
|
.then(literal("in").requires((player) -> player.hasPermissionLevel(2))
|
||||||
|
.then(argument("gamemode", StringArgumentType.word())
|
||||||
|
.suggests( (c, b) -> suggestMatching(gamemodeStrings, b))
|
||||||
|
.executes(PlayerCommand::spawn)))
|
||||||
.then(literal("at").then(argument("position", Vec3ArgumentType.vec3()).executes(PlayerCommand::spawn)
|
.then(literal("at").then(argument("position", Vec3ArgumentType.vec3()).executes(PlayerCommand::spawn)
|
||||||
.then(literal("facing").then(argument("direction", RotationArgumentType.rotation()).executes(PlayerCommand::spawn)
|
.then(literal("facing").then(argument("direction", RotationArgumentType.rotation()).executes(PlayerCommand::spawn)
|
||||||
.then(literal("in").then(argument("dimension", DimensionArgumentType.dimension()).executes(PlayerCommand::spawn)))
|
.then(literal("in").then(argument("dimension", DimensionArgumentType.dimension()).executes(PlayerCommand::spawn)
|
||||||
))
|
.then(literal("in").requires((player) -> player.hasPermissionLevel(2))
|
||||||
|
.then(argument("gamemode", StringArgumentType.word()).suggests( (c, b) -> suggestMatching(gamemodeStrings, b))
|
||||||
|
.executes(PlayerCommand::spawn)
|
||||||
|
)))
|
||||||
|
)))
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -273,6 +286,20 @@ public class PlayerCommand
|
|||||||
flying = player.getAbilities().flying;
|
flying = player.getAbilities().flying;
|
||||||
}
|
}
|
||||||
catch (CommandSyntaxException ignored) {}
|
catch (CommandSyntaxException ignored) {}
|
||||||
|
try {
|
||||||
|
String opGameMode = StringArgumentType.getString(context, "gamemode");
|
||||||
|
mode = GameMode.byName(opGameMode, null);
|
||||||
|
if(mode == null)
|
||||||
|
{
|
||||||
|
Messenger.m(context.getSource(), "rb Invalid game mode: "+opGameMode+".");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException ignored) {}
|
||||||
|
if(mode == GameMode.SPECTATOR)
|
||||||
|
{
|
||||||
|
// Force override flying to true for spectator players, or they will fell out of the world.
|
||||||
|
flying = true;
|
||||||
|
}
|
||||||
String playerName = StringArgumentType.getString(context, "player");
|
String playerName = StringArgumentType.getString(context, "player");
|
||||||
if (playerName.length()>maxPlayerLength(source.getServer()))
|
if (playerName.length()>maxPlayerLength(source.getServer()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package carpet.mixins;
|
||||||
|
|
||||||
|
import carpet.CarpetSettings;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Material;
|
||||||
|
import net.minecraft.fluid.FlowableFluid;
|
||||||
|
import net.minecraft.fluid.Fluid;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(FlowableFluid.class)
|
||||||
|
public class FlowableFluid_liquidDamageDisabledMixin
|
||||||
|
{
|
||||||
|
@Inject(
|
||||||
|
method = "canFill",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/block/Material;blocksMovement()Z"
|
||||||
|
),
|
||||||
|
cancellable = true
|
||||||
|
)
|
||||||
|
private void stopBreakingBlock(BlockView world, BlockPos pos, BlockState state, Fluid fluid, CallbackInfoReturnable<Boolean> cir)
|
||||||
|
{
|
||||||
|
if (CarpetSettings.liquidDamageDisabled)
|
||||||
|
{
|
||||||
|
Material material = state.getMaterial();
|
||||||
|
cir.setReturnValue(material == Material.AIR || material.isLiquid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,9 @@ import carpet.helpers.EntityPlayerActionPack;
|
|||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.server.network.ServerPlayerInteractionManager;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@@ -16,7 +16,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
@Mixin(ServerPlayerEntity.class)
|
@Mixin(ServerPlayerEntity.class)
|
||||||
public abstract class ServerPlayerEntityMixin implements ServerPlayerEntityInterface
|
public abstract class ServerPlayerEntityMixin implements ServerPlayerEntityInterface
|
||||||
{
|
{
|
||||||
|
@Unique
|
||||||
public EntityPlayerActionPack actionPack;
|
public EntityPlayerActionPack actionPack;
|
||||||
|
@Override
|
||||||
public EntityPlayerActionPack getActionPack()
|
public EntityPlayerActionPack getActionPack()
|
||||||
{
|
{
|
||||||
return actionPack;
|
return actionPack;
|
||||||
@@ -41,15 +43,11 @@ public abstract class ServerPlayerEntityMixin implements ServerPlayerEntityInter
|
|||||||
}
|
}
|
||||||
catch (StackOverflowError soe)
|
catch (StackOverflowError soe)
|
||||||
{
|
{
|
||||||
CarpetSettings.LOG.fatal("Caused stack overflow when performing player action");
|
CarpetSettings.LOG.fatal("Caused stack overflow when performing player action", soe);
|
||||||
}
|
}
|
||||||
catch (Throwable exc)
|
catch (Throwable exc)
|
||||||
{
|
{
|
||||||
CarpetSettings.LOG.fatal("Error executing player tasks "+ exc.getMessage());
|
CarpetSettings.LOG.fatal("Error executing player tasks", exc);
|
||||||
exc.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -96,8 +96,7 @@ public abstract class StructureFeatureMixin<C extends FeatureConfig> implements
|
|||||||
}
|
}
|
||||||
catch (Exception booboo)
|
catch (Exception booboo)
|
||||||
{
|
{
|
||||||
CarpetSettings.LOG.error("Unknown Exception while plopping structure: "+booboo);
|
CarpetSettings.LOG.error("Unknown Exception while plopping structure: "+booboo, booboo);
|
||||||
booboo.printStackTrace();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
@@ -1174,7 +1174,7 @@ public class CarpetEventServer
|
|||||||
}
|
}
|
||||||
catch (NullPointerException | InvalidCallbackException | IntegrityException error)
|
catch (NullPointerException | InvalidCallbackException | IntegrityException error)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.error("Got exception: "+error.getMessage());
|
CarpetScriptServer.LOG.error("Got exception when running event call ", error);
|
||||||
return CallbackResult.FAIL;
|
return CallbackResult.FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ public class Expression
|
|||||||
if (exc instanceof ResolvedException)
|
if (exc instanceof ResolvedException)
|
||||||
return exc;
|
return exc;
|
||||||
// unexpected really - should be caught earlier and converted to InternalExpressionException
|
// unexpected really - should be caught earlier and converted to InternalExpressionException
|
||||||
exc.printStackTrace();
|
CarpetSettings.LOG.error("Unexpected exception while running Scarpet code", exc);
|
||||||
return new ExpressionException(c, e, token, "Error while evaluating expression: "+exc);
|
return new ExpressionException(c, e, token, "Error while evaluating expression: "+exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import carpet.script.exception.InternalExpressionException;
|
|||||||
import carpet.script.exception.ThrowStatement;
|
import carpet.script.exception.ThrowStatement;
|
||||||
import carpet.script.exception.Throwables;
|
import carpet.script.exception.Throwables;
|
||||||
import carpet.script.utils.SnoopyCommandSource;
|
import carpet.script.utils.SnoopyCommandSource;
|
||||||
|
import carpet.script.utils.SystemInfo;
|
||||||
import carpet.script.utils.InputValidator;
|
import carpet.script.utils.InputValidator;
|
||||||
import carpet.script.utils.ScarpetJsonDeserializer;
|
import carpet.script.utils.ScarpetJsonDeserializer;
|
||||||
import carpet.script.utils.ShapeDispatcher;
|
import carpet.script.utils.ShapeDispatcher;
|
||||||
@@ -655,8 +656,10 @@ public class Auxiliary {
|
|||||||
expression.addContextFunction("tick_time", 0, (c, t, lv) ->
|
expression.addContextFunction("tick_time", 0, (c, t, lv) ->
|
||||||
new NumericValue(((CarpetContext) c).s.getServer().getTicks()));
|
new NumericValue(((CarpetContext) c).s.getServer().getTicks()));
|
||||||
|
|
||||||
expression.addContextFunction("world_time", 0, (c, t, lv) ->
|
expression.addContextFunction("world_time", 0, (c, t, lv) -> {
|
||||||
new NumericValue(((CarpetContext) c).s.getWorld().getTime()));
|
c.host.issueDeprecation("world_time()");
|
||||||
|
return new NumericValue(((CarpetContext) c).s.getWorld().getTime());
|
||||||
|
});
|
||||||
|
|
||||||
expression.addContextFunction("day_time", -1, (c, t, lv) ->
|
expression.addContextFunction("day_time", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
@@ -672,16 +675,8 @@ public class Auxiliary {
|
|||||||
|
|
||||||
expression.addContextFunction("last_tick_times", -1, (c, t, lv) ->
|
expression.addContextFunction("last_tick_times", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
//assuming we are in the tick world section
|
c.host.issueDeprecation("last_tick_times()");
|
||||||
// might be off one tick when run in the off tasks or asynchronously.
|
return SystemInfo.get("last_tick_times", (CarpetContext)c);
|
||||||
int currentReportedTick = ((CarpetContext) c).s.getServer().getTicks()-1;
|
|
||||||
List<Value> ticks = new ArrayList<>(100);
|
|
||||||
final long[] tickArray = ((CarpetContext) c).s.getServer().lastTickLengths;
|
|
||||||
for (int i=currentReportedTick+100; i > currentReportedTick; i--)
|
|
||||||
{
|
|
||||||
ticks.add(new NumericValue(((double)tickArray[i % 100])/1000000.0));
|
|
||||||
}
|
|
||||||
return ListValue.wrap(ticks);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -742,8 +737,10 @@ public class Auxiliary {
|
|||||||
expression.addContextFunction("current_dimension", 0, (c, t, lv) ->
|
expression.addContextFunction("current_dimension", 0, (c, t, lv) ->
|
||||||
ValueConversions.of( ((CarpetContext)c).s.getWorld()));
|
ValueConversions.of( ((CarpetContext)c).s.getWorld()));
|
||||||
|
|
||||||
expression.addContextFunction("view_distance", 0, (c, t, lv) ->
|
expression.addContextFunction("view_distance", 0, (c, t, lv) -> {
|
||||||
new NumericValue(((CarpetContext)c).s.getServer().getPlayerManager().getViewDistance()));
|
c.host.issueDeprecation("view_distance()");
|
||||||
|
return new NumericValue(((CarpetContext)c).s.getServer().getPlayerManager().getViewDistance());
|
||||||
|
});
|
||||||
|
|
||||||
// lazy due to passthrough and context changing ability
|
// lazy due to passthrough and context changing ability
|
||||||
expression.addLazyFunction("in_dimension", 2, (c, t, lv) -> {
|
expression.addLazyFunction("in_dimension", 2, (c, t, lv) -> {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import carpet.script.utils.SimplexNoiseSampler;
|
|||||||
import carpet.script.value.BooleanValue;
|
import carpet.script.value.BooleanValue;
|
||||||
import carpet.script.value.FunctionValue;
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.ListValue;
|
import carpet.script.value.ListValue;
|
||||||
|
import carpet.script.value.MapValue;
|
||||||
import carpet.script.value.NullValue;
|
import carpet.script.value.NullValue;
|
||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
@@ -56,6 +57,10 @@ public class Sys {
|
|||||||
if (num.isInteger()) return new NumericValue(num.getLong());
|
if (num.isInteger()) return new NumericValue(num.getLong());
|
||||||
return new NumericValue(num.getDouble());
|
return new NumericValue(num.getDouble());
|
||||||
}
|
}
|
||||||
|
if (v instanceof ListValue || v instanceof MapValue)
|
||||||
|
{
|
||||||
|
return new NumericValue(v.length());
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new NumericValue(v.getString());
|
return new NumericValue(v.getString());
|
||||||
|
|||||||
@@ -23,9 +23,11 @@ import net.minecraft.world.WorldProperties;
|
|||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -58,6 +60,7 @@ public class SystemInfo {
|
|||||||
WorldProperties prop = c.s.getServer().getOverworld().getLevelProperties();
|
WorldProperties prop = c.s.getServer().getOverworld().getLevelProperties();
|
||||||
return ListValue.of(NumericValue.of(prop.getSpawnX()), NumericValue.of(prop.getSpawnY()), NumericValue.of(prop.getSpawnZ()));
|
return ListValue.of(NumericValue.of(prop.getSpawnX()), NumericValue.of(prop.getSpawnY()), NumericValue.of(prop.getSpawnZ()));
|
||||||
});
|
});
|
||||||
|
put("world_time", c -> new NumericValue(c.s.getWorld().getTime()));
|
||||||
|
|
||||||
put("game_difficulty", c -> StringValue.of(c.s.getServer().getSaveProperties().getDifficulty().getName()));
|
put("game_difficulty", c -> StringValue.of(c.s.getServer().getSaveProperties().getDifficulty().getName()));
|
||||||
put("game_hardcore", c -> BooleanValue.of(c.s.getServer().getSaveProperties().isHardcore()));
|
put("game_hardcore", c -> BooleanValue.of(c.s.getServer().getSaveProperties().isHardcore()));
|
||||||
@@ -114,6 +117,18 @@ public class SystemInfo {
|
|||||||
ret.put(new StringValue(mod.getMetadata().getName()), new StringValue(mod.getMetadata().getVersion().getFriendlyString()));
|
ret.put(new StringValue(mod.getMetadata().getName()), new StringValue(mod.getMetadata().getVersion().getFriendlyString()));
|
||||||
return MapValue.wrap(ret);
|
return MapValue.wrap(ret);
|
||||||
});
|
});
|
||||||
|
put("server_last_tick_times", c -> {
|
||||||
|
//assuming we are in the tick world section
|
||||||
|
// might be off one tick when run in the off tasks or asynchronously.
|
||||||
|
int currentReportedTick = c.s.getServer().getTicks()-1;
|
||||||
|
List<Value> ticks = new ArrayList<>(100);
|
||||||
|
final long[] tickArray = c.s.getServer().lastTickLengths;
|
||||||
|
for (int i=currentReportedTick+100; i > currentReportedTick; i--)
|
||||||
|
{
|
||||||
|
ticks.add(new NumericValue(((double)tickArray[i % 100])/1000000.0));
|
||||||
|
}
|
||||||
|
return ListValue.wrap(ticks);
|
||||||
|
});
|
||||||
|
|
||||||
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()));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
|
import carpet.CarpetSettings;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
@@ -42,7 +43,7 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
|||||||
catch (CloneNotSupportedException e)
|
catch (CloneNotSupportedException e)
|
||||||
{
|
{
|
||||||
// should not happen
|
// should not happen
|
||||||
e.printStackTrace();
|
CarpetSettings.LOG.catching(e);
|
||||||
throw new InternalExpressionException("Variable of type "+getTypeString()+" is not cloneable. Tell gnembon about it, this shoudn't happen");
|
throw new InternalExpressionException("Variable of type "+getTypeString()+" is not cloneable. Tell gnembon about it, this shoudn't happen");
|
||||||
}
|
}
|
||||||
copy.boundVariable = var;
|
copy.boundVariable = var;
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import com.mojang.brigadier.context.CommandContext;
|
|||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
|
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
@@ -35,15 +37,19 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static carpet.utils.Translations.tr;
|
import static carpet.utils.Translations.tr;
|
||||||
import static carpet.script.CarpetEventServer.Event.CARPET_RULE_CHANGES;
|
import static carpet.script.CarpetEventServer.Event.CARPET_RULE_CHANGES;
|
||||||
@@ -315,8 +321,7 @@ public class SettingsManager
|
|||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
CarpetSettings.LOG.error("[CM]: failed write "+identifier+".conf config file", e);
|
||||||
CarpetSettings.LOG.error("[CM]: failed write "+identifier+".conf config file");
|
|
||||||
}
|
}
|
||||||
///todo is it really needed? resendCommandTree();
|
///todo is it really needed? resendCommandTree();
|
||||||
}
|
}
|
||||||
@@ -474,7 +479,7 @@ public class SettingsManager
|
|||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
CarpetSettings.LOG.error("Exception while loading Carpet rules from config", e);
|
||||||
return new ConfigReadResult(new HashMap<>(), false);
|
return new ConfigReadResult(new HashMap<>(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -544,6 +549,20 @@ public class SettingsManager
|
|||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CompletableFuture<Suggestions> suggestMatchingContains(Stream<String> stream, SuggestionsBuilder suggestionsBuilder) {
|
||||||
|
String query = suggestionsBuilder.getRemaining().toLowerCase(Locale.ROOT);
|
||||||
|
var filteredSuggestionList = stream.filter((listItem) -> { //Regex camelCase Search
|
||||||
|
var words = Arrays.stream(listItem.split("(?<!^)(?=[A-Z])")).map(s -> s.toLowerCase(Locale.ROOT)).collect(Collectors.toList());
|
||||||
|
var prefixes = new ArrayList<String>(words.size());
|
||||||
|
for (int i = 0; i < words.size(); i++)
|
||||||
|
prefixes.add(String.join("",words.subList(i, words.size())));
|
||||||
|
return prefixes.stream().anyMatch(s -> s.startsWith(query));
|
||||||
|
});
|
||||||
|
Objects.requireNonNull(suggestionsBuilder);
|
||||||
|
filteredSuggestionList.forEach(suggestionsBuilder::suggest);
|
||||||
|
return suggestionsBuilder.buildFuture();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the the settings command for this {@link SettingsManager}.<br>
|
* Registers the the settings command for this {@link SettingsManager}.<br>
|
||||||
* It is handled automatically by Carpet.
|
* It is handled automatically by Carpet.
|
||||||
@@ -576,17 +595,17 @@ public class SettingsManager
|
|||||||
then(literal("removeDefault").
|
then(literal("removeDefault").
|
||||||
requires(s -> !locked).
|
requires(s -> !locked).
|
||||||
then(argument("rule", StringArgumentType.word()).
|
then(argument("rule", StringArgumentType.word()).
|
||||||
suggests( (c, b) -> suggestMatching(getRules().stream().map(r -> r.name), b)).
|
suggests( (c, b) -> suggestMatchingContains(getRules().stream().map(r -> r.name), b)).
|
||||||
executes((c) -> removeDefault(c.getSource(), contextRule(c))))).
|
executes((c) -> removeDefault(c.getSource(), contextRule(c))))).
|
||||||
then(literal("setDefault").
|
then(literal("setDefault").
|
||||||
requires(s -> !locked).
|
requires(s -> !locked).
|
||||||
then(argument("rule", StringArgumentType.word()).
|
then(argument("rule", StringArgumentType.word()).
|
||||||
suggests( (c, b) -> suggestMatching(getRules().stream().map(r -> r.name), b)).
|
suggests( (c, b) -> suggestMatchingContains(getRules().stream().map(r -> r.name), b)).
|
||||||
then(argument("value", StringArgumentType.greedyString()).
|
then(argument("value", StringArgumentType.greedyString()).
|
||||||
suggests((c, b)-> suggestMatching(contextRule(c).options, b)).
|
suggests((c, b)-> suggestMatching(contextRule(c).options, b)).
|
||||||
executes((c) -> setDefault(c.getSource(), contextRule(c), StringArgumentType.getString(c, "value")))))).
|
executes((c) -> setDefault(c.getSource(), contextRule(c), StringArgumentType.getString(c, "value")))))).
|
||||||
then(argument("rule", StringArgumentType.word()).
|
then(argument("rule", StringArgumentType.word()).
|
||||||
suggests( (c, b) -> suggestMatching(getRules().stream().map(r -> r.name), b)).
|
suggests( (c, b) -> suggestMatchingContains(getRules().stream().map(r -> r.name), b)).
|
||||||
requires(s -> !locked ).
|
requires(s -> !locked ).
|
||||||
executes( (c) -> displayRuleMenu(c.getSource(), contextRule(c))).
|
executes( (c) -> displayRuleMenu(c.getSource(), contextRule(c))).
|
||||||
then(argument("value", StringArgumentType.greedyString()).
|
then(argument("value", StringArgumentType.greedyString()).
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ import net.minecraft.world.gen.feature.StructureFeature;
|
|||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import carpet.CarpetSettings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -462,7 +464,7 @@ public class SpawnReporter
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
exception.printStackTrace();
|
CarpetSettings.LOG.warn("Exception while creating mob for spawn reporter", exception);
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,7 +521,7 @@ public class SpawnReporter
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
exception.printStackTrace();
|
CarpetSettings.LOG.warn("Exception while creating mob for spawn reporter", exception);
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
"Structure_fillUpdatesMixin",
|
"Structure_fillUpdatesMixin",
|
||||||
"ServerPlayNetworkHandler_interactionUpdatesMixin",
|
"ServerPlayNetworkHandler_interactionUpdatesMixin",
|
||||||
|
|
||||||
|
"FlowableFluid_liquidDamageDisabledMixin",
|
||||||
|
|
||||||
"ServerMetadata_motdMixin",
|
"ServerMetadata_motdMixin",
|
||||||
"MinecraftServer_pingPlayerSampleLimit",
|
"MinecraftServer_pingPlayerSampleLimit",
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user