Merge remote-tracking branch 'upstream/master' into 26.3
Development Builds / Build (push) Canceled after 0s

This commit is contained in:
iceBear67 committed 2026-09-26 03:10:41 +00:00
commit 3729e96e81
62 files changed
+649 -833

No files matched your search

+4 -4
View File
@@ -7,12 +7,12 @@ org.gradle.configuration-cache=false
# Fabric Properties # Fabric Properties
# check https://fabricmc.net/develop/ # check https://fabricmc.net/develop/
minecraft_version=26.3-snapshot-9 minecraft_version=26.3
loader_version=0.19.3 loader_version=0.19.5
loom_version=1.17-SNAPSHOT loom_version=1.17-SNAPSHOT
# Mod Properties # Mod Properties
mod_version = 26.3-beta-3 mod_version = 26.3
maven_group = carpet maven_group = carpet
archives_base_name = fabric-carpet archives_base_name = fabric-carpet
@@ -20,7 +20,7 @@ org.gradle.configuration-cache=false
# The Curseforge versions "names" or ids for the main branch (comma separated: 1.16.4,1.16.5) # The Curseforge versions "names" or ids for the main branch (comma separated: 1.16.4,1.16.5)
# This is needed because CF uses too vague names for prereleases and release candidates # This is needed because CF uses too vague names for prereleases and release candidates
# Can also be the version ID directly coming from https://minecraft.curseforge.com/api/game/versions?token=[API_TOKEN] # Can also be the version ID directly coming from https://minecraft.curseforge.com/api/game/versions?token=[API_TOKEN]
release-curse-versions = Minecraft 26.3:26.3-Snapshot release-curse-versions = Minecraft 26.3:26.3
# Whether or not to build another branch on release # Whether or not to build another branch on release
release-extra-branch = false release-extra-branch = false
# The name of the second branch to release # The name of the second branch to release
@@ -1,7 +0,0 @@
package carpet.fakes;
import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
public interface RandomStateVisitorAccessor {
DensityFunction.Visitor getVisitor();
}
@@ -49,11 +49,11 @@ public abstract class Explosion_scarpetEventMixin
} }
@Inject(method = "explode", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerExplosion;hurtEntities()V", shift = At.Shift.AFTER)) @Inject(method = "explode", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerExplosion;hurtEntities()V", shift = At.Shift.AFTER))
private void onExplosionDone(CallbackInfoReturnable<Integer> cir, List list) private void onExplosionDone(CallbackInfoReturnable<Integer> cir, List toBlow)
{ {
if (EXPLOSION_OUTCOME.isNeeded() && !level.isClientSide()) if (EXPLOSION_OUTCOME.isNeeded() && !level.isClientSide())
{ {
EXPLOSION_OUTCOME.onExplosion((ServerLevel) level, source, this::getIndirectSourceEntity, center, radius, fire, list, affectedEntities, blockInteraction); EXPLOSION_OUTCOME.onExplosion((ServerLevel) level, source, this::getIndirectSourceEntity, center, radius, fire, toBlow, affectedEntities, blockInteraction);
} }
} }
} }
@@ -18,21 +18,28 @@ public abstract class Inventory_scarpetEventMixin
{ {
@Shadow @Final public Player player; @Shadow @Final public Player player;
@Shadow
@Final
public static int NOT_FOUND_INDEX;
@Shadow
public abstract boolean add(int slot, ItemStack itemStack);
@Redirect(method = "add(Lnet/minecraft/world/item/ItemStack;)Z", at = @At( @Redirect(method = "add(Lnet/minecraft/world/item/ItemStack;)Z", at = @At(
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/world/entity/player/Inventory;add(ILnet/minecraft/world/item/ItemStack;)Z" target = "Lnet/minecraft/world/entity/player/Inventory;add(ILnet/minecraft/world/item/ItemStack;)Z"
)) ))
private boolean onItemAcquired(Inventory playerInventory, int slot, ItemStack stack) private boolean onItemAcquired(Inventory playerInventory, int slot, ItemStack itemStack)
{ {
if (!PLAYER_PICKS_UP_ITEM.isNeeded() || !(player instanceof ServerPlayer)) if (!PLAYER_PICKS_UP_ITEM.isNeeded() || !(player instanceof final ServerPlayer serverPlayer))
return playerInventory.add(-1, stack); return add(NOT_FOUND_INDEX, itemStack);
int count = stack.getCount(); int count = itemStack.getCount();
ItemStack previous = stack.copy(); ItemStack prevStack = itemStack.copy();
boolean res = playerInventory.add(-1, stack); boolean res = add(NOT_FOUND_INDEX, itemStack);
if (count != stack.getCount()) // res returns false for larger item adding to a almost full ineventory if (count != itemStack.getCount()) // res returns false for larger item adding to a almost full ineventory
{ {
ItemStack diffStack = previous.copyWithCount(count - stack.getCount()); ItemStack diffStack = prevStack.copyWithCount(count - itemStack.getCount());
PLAYER_PICKS_UP_ITEM.onItemAction((ServerPlayer) player, null, diffStack); PLAYER_PICKS_UP_ITEM.onItemAction(serverPlayer, null, diffStack);
} }
return res; return res;
} }
@@ -30,7 +30,7 @@ public class PersistentEntitySectionManager_scarpetMixin
} }
else else
{ {
CarpetScriptServer.LOG.error("Failed to handle entity type " + entity.getType().getDescriptionId()); CarpetScriptServer.LOG.error("Failed to handle entity type {}", entity.getType().getDescriptionId());
} }
event = CarpetEventServer.Event.ENTITY_LOAD.get(entity.getType()); event = CarpetEventServer.Event.ENTITY_LOAD.get(entity.getType());
@@ -43,7 +43,7 @@ public class PersistentEntitySectionManager_scarpetMixin
} }
else else
{ {
CarpetScriptServer.LOG.error("Failed to handle entity type " + entity.getType().getDescriptionId()); CarpetScriptServer.LOG.error("Failed to handle entity type {}", entity.getType().getDescriptionId());
} }
} }
@@ -1,33 +0,0 @@
package carpet.mixins;
import carpet.fakes.RandomStateVisitorAccessor;
import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
import net.minecraft.world.level.levelgen.RandomState;
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.ModifyArg;
@Mixin(RandomState.class)
public class RandomState_ScarpetMixin implements RandomStateVisitorAccessor {
@Unique
private DensityFunction.Visitor visitor;
@ModifyArg(
method = "<init>",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/levelgen/NoiseRouter;mapAll(Lnet/minecraft/world/level/levelgen/densityfunction/DensityFunction$Visitor;)Lnet/minecraft/world/level/levelgen/NoiseRouter;"
),
index = 0
)
private DensityFunction.Visitor captureVisitor(DensityFunction.Visitor visitor) {
this.visitor = visitor;
return visitor;
}
@Override
public DensityFunction.Visitor getVisitor() {
return this.visitor;
}
}
@@ -27,7 +27,7 @@ public abstract class ServerChunkCacheMixin
@Shadow @Final private DistanceManager distanceManager; @Shadow @Final private DistanceManager distanceManager;
@Redirect(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At( @Redirect(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At(
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/server/level/DistanceManager;getNaturalSpawnChunkCount()I" target = "Lnet/minecraft/server/level/DistanceManager;getNaturalSpawnChunkCount()I"
)) ))
@@ -54,7 +54,7 @@ public abstract class ServerChunkCacheMixin
} }
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At("RETURN")) @Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At("RETURN"))
private void onFinishSpawnWorldCycle(CallbackInfo ci) private void onFinishSpawnWorldCycle(CallbackInfo ci)
{ {
LevelData levelData = this.level.getLevelData(); // levelProperies class LevelData levelData = this.level.getLevelData(); // levelProperies class
@@ -19,13 +19,13 @@ public abstract class ServerChunkCache_profilerMixin
CarpetProfiler.ProfilerToken currentSection; CarpetProfiler.ProfilerToken currentSection;
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At("HEAD")) @Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At("HEAD"))
private void startSpawningSection(CallbackInfo ci) private void startSpawningSection(CallbackInfo ci)
{ {
currentSection = CarpetProfiler.start_section(level, "Spawning", CarpetProfiler.TYPE.GENERAL); currentSection = CarpetProfiler.start_section(level, "Spawning", CarpetProfiler.TYPE.GENERAL);
} }
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At("RETURN")) @Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At("RETURN"))
private void stopSpawningSection(CallbackInfo ci) private void stopSpawningSection(CallbackInfo ci)
{ {
if (currentSection != null) if (currentSection != null)
@@ -48,7 +48,7 @@ public abstract class ServerGamePacketListenerImpl_antiCheatDisabledMixin extend
return isSingleplayerOwner() || CarpetSettings.antiCheatDisabled; return isSingleplayerOwner() || CarpetSettings.antiCheatDisabled;
} }
@Redirect(method = "handleMovePlayer", require = 0, // don't crash with immersive portals, @Redirect(method = "handlePlayerPositionChange", require = 0, // don't crash with immersive portals,
at = @At( at = @At(
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/server/level/ServerPlayer;isChangingDimension()Z")) target = "Lnet/minecraft/server/level/ServerPlayer;isChangingDimension()Z"))
@@ -122,11 +122,11 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
} }
@Inject(method = "handleMovePlayer", at = @At( @Inject(method = "handlePlayerPositionChange", at = @At(
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/server/level/ServerPlayer;jumpFromGround()V" target = "Lnet/minecraft/server/level/ServerPlayer;jumpFromGround()V"
)) ))
private void onJump(ServerboundMovePlayerPacket playerMoveC2SPacket_1, CallbackInfo ci) private void onJump(double requestedX, double requestedY, double requestedZ, float requestedYRot, float requestedXRot, boolean isOnGround, boolean horizontalCollision, CallbackInfo ci)
{ {
PLAYER_JUMPS.onPlayerEvent(player); PLAYER_JUMPS.onPlayerEvent(player);
} }
@@ -152,28 +152,29 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
{ {
if (PLAYER_RELEASED_ITEM.isNeeded()) if (PLAYER_RELEASED_ITEM.isNeeded())
{ {
InteractionHand hand = serverPlayerEntity.getUsedItemHand(); InteractionHand hand = player.getUsedItemHand();
ItemStack stack = serverPlayerEntity.getUseItem().copy(); ItemStack stack = player.getUseItem().copy();
serverPlayerEntity.releaseUsingItem(); player.releaseUsingItem();
PLAYER_RELEASED_ITEM.onItemAction(player, hand, stack); PLAYER_RELEASED_ITEM.onItemAction(player, hand, stack);
} }
else else
{ {
serverPlayerEntity.releaseUsingItem(); player.releaseUsingItem();
} }
} }
@Inject(method = "handleUseItemOn", cancellable = true, at = @At( @Inject(method = "handleUseItemOn", cancellable = true, at = @At(
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/server/level/ServerPlayerGameMode;useItemOn(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/InteractionResult;" target = "Lnet/minecraft/server/level/ServerPlayerGameMode;useItemOn(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/InteractionResult;",
shift = At.Shift.BEFORE
)) ))
private void onBlockInteracted(ServerboundUseItemOnPacket playerInteractBlockC2SPacket_1, CallbackInfo ci) private void onBlockInteracted(ServerboundUseItemOnPacket packet, CallbackInfo ci)
{ {
if (PLAYER_RIGHT_CLICKS_BLOCK.isNeeded()) if (PLAYER_RIGHT_CLICKS_BLOCK.isNeeded())
{ {
InteractionHand hand = playerInteractBlockC2SPacket_1.hand(); InteractionHand handd = packet.hand();
BlockHitResult hitRes = playerInteractBlockC2SPacket_1.hitResult(); BlockHitResult hitRes = packet.hitResult();
if(PLAYER_RIGHT_CLICKS_BLOCK.onBlockHit(player, hand, hitRes)) { if(PLAYER_RIGHT_CLICKS_BLOCK.onBlockHit(player, handd, hitRes)) {
ci.cancel(); ci.cancel();
} }
} }
@@ -183,11 +184,11 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/server/level/ServerPlayer;resetLastActionTime()V" target = "Lnet/minecraft/server/level/ServerPlayer;resetLastActionTime()V"
)) ))
private void onItemClicked(ServerboundUseItemPacket playerInteractItemC2SPacket_1, CallbackInfo ci) private void onItemClicked(ServerboundUseItemPacket packet, CallbackInfo ci)
{ {
if (PLAYER_USES_ITEM.isNeeded()) if (PLAYER_USES_ITEM.isNeeded())
{ {
InteractionHand hand = playerInteractItemC2SPacket_1.hand(); InteractionHand hand = packet.hand();
if(PLAYER_USES_ITEM.onItemAction(player, hand, player.getItemInHand(hand).copy())) { if(PLAYER_USES_ITEM.onItemAction(player, hand, player.getItemInHand(hand).copy())) {
ci.cancel(); ci.cancel();
} }
@@ -283,10 +284,10 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
@Inject(method = "lambda$handleChatCommand$0", // lambda of handleChatCommand(ServerboundChatCommandPacket) @Inject(method = "lambda$handleChatCommand$0", // lambda of handleChatCommand(ServerboundChatCommandPacket)
at = @At(value = "HEAD") at = @At(value = "HEAD")
) )
private void onChatCommandMessage(ServerboundChatCommandPacket serverboundChatCommandPacket, CallbackInfo ci) { private void onChatCommandMessage(ServerboundChatCommandPacket packet, CallbackInfo ci) {
if (PLAYER_COMMAND.isNeeded()) if (PLAYER_COMMAND.isNeeded())
{ {
PLAYER_COMMAND.onPlayerMessage(player, serverboundChatCommandPacket.command()); PLAYER_COMMAND.onPlayerMessage(player, packet.command());
} }
} }
} }
@@ -69,10 +69,10 @@ public abstract class ServerLevel_scarpetMixin extends Level
} }
@Inject(method = "explode", at = @At("HEAD"), cancellable = true) @Inject(method = "explode", at = @At("HEAD"), cancellable = true)
private void handleExplosion(Entity entity, DamageSource damageSource, ExplosionDamageCalculator explosionDamageCalculator, double x, double y, double z, float g, boolean bl, ExplosionInteraction explosionInteraction, ParticleOptions particleOptions, ParticleOptions particleOptions2, WeightedList<ExplosionParticleInfo> weightedList, Holder<SoundEvent> holder, CallbackInfo ci) private void handleExplosion(Entity source, DamageSource damageSource, ExplosionDamageCalculator damageCalculator, double x, double y, double z, float r, boolean fire, ExplosionInteraction interactionType, ParticleOptions smallExplosionParticles, ParticleOptions largeExplosionParticles, WeightedList<ExplosionParticleInfo> blockParticles, Holder<SoundEvent> explosionSound, CallbackInfo ci)
{ {
if (EXPLOSION.isNeeded()) { if (EXPLOSION.isNeeded()) {
Explosion.BlockInteraction var10000 = switch (explosionInteraction) { Explosion.BlockInteraction var10000 = switch (interactionType) {
case NONE -> Explosion.BlockInteraction.KEEP; case NONE -> Explosion.BlockInteraction.KEEP;
case BLOCK -> this.getCMDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY); case BLOCK -> this.getCMDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY);
case MOB -> this.getGameRules().get(GameRules.MOB_GRIEFING) ? this.getCMDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP; case MOB -> this.getGameRules().get(GameRules.MOB_GRIEFING) ? this.getCMDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP;
@@ -80,7 +80,7 @@ public abstract class ServerLevel_scarpetMixin extends Level
case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK; case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK;
}; };
boolean cancelled = EXPLOSION.onExplosion((ServerLevel) (Object) this, entity, null, new Vec3(x, y, z), g, bl, null, null, var10000); boolean cancelled = EXPLOSION.onExplosion((ServerLevel) (Object) this, source, null, new Vec3(x, y, z), r, fire, null, null, var10000);
if (cancelled) ci.cancel(); if (cancelled) ci.cancel();
} }
} }
@@ -88,8 +88,7 @@ public class CarpetEventServer
public static class Callback public static class Callback
{ {
public final String host; public final String host;
@Nullable public final @Nullable String optionalTarget;
public final String optionalTarget;
public final FunctionValue function; public final FunctionValue function;
public final List<Value> parametrizedArgs; public final List<Value> parametrizedArgs;
public final CarpetScriptServer scriptServer; public final CarpetScriptServer scriptServer;
@@ -382,15 +381,15 @@ public class CarpetEventServer
public void removeEventCall(String hostName, String target, String funName) public void removeEventCall(String hostName, String target, String funName)
{ {
removeCallsIf((c) -> c.function.getString().equals(funName) removeCallsIf((c) -> c.function.getString().equals(funName)
&& (Objects.equals(c.host, hostName)) && Objects.equals(c.host, hostName)
&& (Objects.equals(c.optionalTarget, target)) && Objects.equals(c.optionalTarget, target)
); );
} }
public void removeAllCalls(CarpetScriptHost host) public void removeAllCalls(CarpetScriptHost host)
{ {
removeCallsIf((c) -> (Objects.equals(c.host, host.getName())) removeCallsIf((c) -> Objects.equals(c.host, host.getName())
&& (Objects.equals(c.optionalTarget, host.user))); && Objects.equals(c.optionalTarget, host.user));
} }
public void createChildEvents(CarpetScriptHost host) public void createChildEvents(CarpetScriptHost host)
@@ -398,7 +397,7 @@ public class CarpetEventServer
List<Callback> copyCalls = new ArrayList<>(); List<Callback> copyCalls = new ArrayList<>();
callList.forEach((c) -> callList.forEach((c) ->
{ {
if ((Objects.equals(c.host, host.getName())) // TODO fix me if (Objects.equals(c.host, host.getName()) // TODO fix me
&& c.optionalTarget == null) && c.optionalTarget == null)
{ {
copyCalls.add(new Callback(c.host, host.user, c.function, c.parametrizedArgs, host.scriptServer())); copyCalls.add(new Callback(c.host, host.user, c.function, c.parametrizedArgs, host.scriptServer()));
@@ -772,62 +772,50 @@ public class CarpetScriptHost extends ScriptHost
String sign = ""; String sign = "";
for (Token tok : Tokenizer.simple(arg).parseTokens()) for (Token tok : Tokenizer.simple(arg).parseTokens())
{ {
switch (tok.type) switch (tok.type) {
{ case VARIABLE -> {
case VARIABLE:
LazyValue variable = getGlobalVariable(tok.surface); LazyValue variable = getGlobalVariable(tok.surface);
if (variable != null) if (variable != null) {
{
argv.add(variable); argv.add(variable);
} }
break; }
case STRINGPARAM: case STRINGPARAM -> {
argv.add((c, t) -> new StringValue(tok.surface)); argv.add((c, t) -> new StringValue(tok.surface));
sign = ""; sign = "";
break; }
case LITERAL -> {
case LITERAL: try {
try
{
String finalSign = sign; String finalSign = sign;
argv.add((c, t) -> new NumericValue(finalSign + tok.surface)); argv.add((c, t) -> new NumericValue(finalSign + tok.surface));
sign = ""; sign = "";
} } catch (NumberFormatException exception) {
catch (NumberFormatException exception)
{
throw new CarpetExpressionException("Fail: " + sign + tok.surface + " seems like a number but it is" + throw new CarpetExpressionException("Fail: " + sign + tok.surface + " seems like a number but it is" +
" not a number. Use quotes to ensure its a string", null); " not a number. Use quotes to ensure its a string", null);
} }
break; }
case HEX_LITERAL: case HEX_LITERAL -> {
try try {
{
String finalSign = sign; String finalSign = sign;
argv.add((c, t) -> new NumericValue(new BigInteger(finalSign + tok.surface.substring(2), 16).doubleValue())); argv.add((c, t) -> new NumericValue(new BigInteger(finalSign + tok.surface.substring(2), 16).doubleValue()));
sign = ""; sign = "";
} } catch (NumberFormatException exception) {
catch (NumberFormatException exception)
{
throw new CarpetExpressionException("Fail: " + sign + tok.surface + " seems like a number but it is" + throw new CarpetExpressionException("Fail: " + sign + tok.surface + " seems like a number but it is" +
" not a number. Use quotes to ensure its a string", null); " not a number. Use quotes to ensure its a string", null);
} }
break; }
case OPERATOR, UNARY_OPERATOR: case OPERATOR, UNARY_OPERATOR -> {
if ((tok.surface.equals("-") || tok.surface.equals("-u")) && sign.isEmpty()) if ((tok.surface.equals("-") || tok.surface.equals("-u")) && sign.isEmpty()) {
{
sign = "-"; sign = "-";
} } else {
else
{
throw new CarpetExpressionException("Fail: operators, like " + tok.surface + " are not " + throw new CarpetExpressionException("Fail: operators, like " + tok.surface + " are not " +
"allowed in invoke", null); "allowed in invoke", null);
} }
break; }
case FUNCTION: case FUNCTION ->
throw new CarpetExpressionException("Fail: passing functions like " + tok.surface + "() to invoke is " + throw new CarpetExpressionException("Fail: passing functions like " + tok.surface + "() to invoke is " +
"not allowed", null); "not allowed", null);
case OPEN_PAREN, COMMA, CLOSE_PAREN, MARKER: case OPEN_PAREN, COMMA, CLOSE_PAREN, MARKER ->
throw new CarpetExpressionException("Fail: " + tok.surface + " is not allowed in invoke", null); throw new CarpetExpressionException("Fail: " + tok.surface + " is not allowed in invoke", null);
} }
} }
List<String> args = function.getArguments(); List<String> args = function.getArguments();
@@ -1109,7 +1097,7 @@ public class CarpetScriptHost extends ScriptHost
} }
/** /**
* <p>Creates a {@link Component} using {@link carper.utils.Messenger} that has the locals in the {@code line} snippet with a hover over * <p>Creates a {@link Component} using carpet.utils.Messenger that has the locals in the {@code line} snippet with a hover over
* tooltip with the value of the local at that location</p> * tooltip with the value of the local at that location</p>
* *
* @param line The line to find references to locals on * @param line The line to find references to locals on
@@ -1189,7 +1177,7 @@ public class CarpetScriptHost extends ScriptHost
} }
else else
{ {
CarpetScriptServer.LOG.error(intro + ": " + exception.getMessage()); CarpetScriptServer.LOG.error("{}", intro, exception);
} }
} }
@@ -83,7 +83,7 @@ public class CarpetScriptServer extends ScriptServer
/** /**
* Registers a Scarpet App to be used as a Rule App (to be controlled with the value of a Carpet rule). * Registers a Scarpet App to be used as a Rule App (to be controlled with the value of a Carpet rule).
* Libraries should be registered with {@link #registerBuiltInScript(BundledModule)} instead * Libraries should be registered with #registerBuiltInScript(BundledModule) instead
* *
* @param app The {@link Module} of the app. * @param app The {@link Module} of the app.
* @see Module#fromJarPath(String, String, boolean) * @see Module#fromJarPath(String, String, boolean)
@@ -159,7 +159,7 @@ public class CarpetScriptServer extends ScriptServer
} }
} }
Module globalModule = Carpet.fetchGlobalModule(name, allowLibraries); Module globalModule = fetchGlobalModule(server, name, allowLibraries);
if (globalModule != null) if (globalModule != null)
{ {
return globalModule; return globalModule;
@@ -179,6 +179,53 @@ public class CarpetScriptServer extends ScriptServer
return null; return null;
} }
public static @Nullable Module fetchGlobalModule(MinecraftServer server, String name, boolean allowLibraries) throws IOException
{
Path globalFolder = Carpet.fetchGlobalPath(server);
if (globalFolder == null)
{
return null;
}
if (!Files.exists(globalFolder))
{
Files.createDirectories(globalFolder);
}
try (Stream<Path> folderWalker = Files.walk(globalFolder))
{
Optional<Path> scriptPath = folderWalker
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
.findFirst();
if (scriptPath.isPresent())
{
return Module.fromPath(scriptPath.get());
}
}
return null;
}
public static void addGlobalModules(final MinecraftServer server, final List<String> moduleNames, boolean includeBuiltIns) throws IOException
{
if (!includeBuiltIns)
{
return;
}
final Path globalScripts = Carpet.fetchGlobalPath(server);
if (globalScripts == null) {
return;
}
if (!Files.exists(globalScripts))
{
Files.createDirectories(globalScripts);
}
try (Stream<Path> folderWalker = Files.walk(globalScripts, FileVisitOption.FOLLOW_LINKS))
{
folderWalker
.filter(f -> f.toString().endsWith(".sc"))
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$", "").toLowerCase(Locale.ROOT)));
}
}
public Module getRuleModule(String name) public Module getRuleModule(String name)
{ {
for (Module moduleData : ruleModuleData) for (Module moduleData : ruleModuleData)
@@ -218,7 +265,7 @@ public class CarpetScriptServer extends ScriptServer
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$", "").toLowerCase(Locale.ROOT))); .forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$", "").toLowerCase(Locale.ROOT)));
} }
Carpet.addGlobalModules(moduleNames, includeBuiltIns); addGlobalModules(server, moduleNames, includeBuiltIns);
} }
catch (IOException e) catch (IOException e)
@@ -330,7 +377,7 @@ public class CarpetScriptServer extends ScriptServer
} }
token.run(); token.run();
long end = System.nanoTime(); long end = System.nanoTime();
LOG.info("App " + name + " loaded in " + (end - start) / 1000000 + " ms"); LOG.info("App {} loaded in {} ms", name, (end - start) / 1000000);
return 1; return 1;
} }
+67 -109
View File
@@ -71,8 +71,7 @@ public class Expression
private boolean allowNewlineSubstitutions = true; private boolean allowNewlineSubstitutions = true;
private boolean allowComments = false; private boolean allowComments = false;
@Nullable public @Nullable Module module = null;
public Module module = null;
public String getModuleName() public String getModuleName()
{ {
@@ -93,11 +92,9 @@ public class Expression
/** /**
* Cached AST (Abstract Syntax Tree) (root) of the expression * Cached AST (Abstract Syntax Tree) (root) of the expression
*/ */
@Nullable private @Nullable LazyValue ast = null;
private LazyValue ast = null;
@Nullable private @Nullable ExpressionNode root = null;
private ExpressionNode root = null;
/** /**
* script specific operatos and built-in functions * script specific operatos and built-in functions
@@ -1102,118 +1099,94 @@ public class Expression
Token previousToken = null; Token previousToken = null;
for (Token token : tokens) for (Token token : tokens)
{ {
switch (token.type) switch (token.type) {
{ case STRINGPARAM,
case STRINGPARAM: //stack.push(token); // changed that so strings are treated like literals
//stack.push(token); // changed that so strings are treated like literals //break;
//break; LITERAL, HEX_LITERAL -> {
case LITERAL, HEX_LITERAL:
if (previousToken != null && ( if (previousToken != null && (
previousToken.type == Token.TokenType.LITERAL || previousToken.type == Token.TokenType.LITERAL ||
previousToken.type == Token.TokenType.HEX_LITERAL || previousToken.type == Token.TokenType.HEX_LITERAL ||
previousToken.type == Token.TokenType.STRINGPARAM)) previousToken.type == Token.TokenType.STRINGPARAM)) {
{
throw new ExpressionException(c, this, token, "Missing operator"); throw new ExpressionException(c, this, token, "Missing operator");
} }
outputQueue.add(token); outputQueue.add(token);
break; }
case VARIABLE: case VARIABLE -> outputQueue.add(token);
outputQueue.add(token); case FUNCTION -> {
break;
case FUNCTION:
stack.push(token); stack.push(token);
lastFunction = token; lastFunction = token;
break; }
case COMMA: case COMMA -> {
if (previousToken != null && previousToken.type == Token.TokenType.OPERATOR) if (previousToken != null && previousToken.type == Token.TokenType.OPERATOR) {
{
throw new ExpressionException(c, this, previousToken, "Missing parameter(s) for operator "); throw new ExpressionException(c, this, previousToken, "Missing parameter(s) for operator ");
} }
while (!stack.isEmpty() && stack.top().type != Token.TokenType.OPEN_PAREN) while (!stack.isEmpty() && stack.top().type != Token.TokenType.OPEN_PAREN) {
{
outputQueue.add(stack.pop()); outputQueue.add(stack.pop());
} }
if (stack.isEmpty()) if (stack.isEmpty()) {
{ if (lastFunction == null) {
if (lastFunction == null)
{
throw new ExpressionException(c, this, token, "Unexpected comma"); throw new ExpressionException(c, this, token, "Unexpected comma");
} } else {
else
{
throw new ExpressionException(c, this, lastFunction, "Parse error for function"); throw new ExpressionException(c, this, lastFunction, "Parse error for function");
} }
} }
break; }
case OPERATOR: case OPERATOR -> {
{
if (previousToken != null if (previousToken != null
&& (previousToken.type == Token.TokenType.COMMA || previousToken.type == Token.TokenType.OPEN_PAREN)) && (previousToken.type == Token.TokenType.COMMA || previousToken.type == Token.TokenType.OPEN_PAREN)) {
{
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator '" + token + "'"); throw new ExpressionException(c, this, token, "Missing parameter(s) for operator '" + token + "'");
} }
ILazyOperator o1 = operators.get(token.surface); ILazyOperator o1 = operators.get(token.surface);
if (o1 == null) if (o1 == null) {
{
throw new ExpressionException(c, this, token, "Unknown operator '" + token + "'"); throw new ExpressionException(c, this, token, "Unknown operator '" + token + "'");
} }
shuntOperators(outputQueue, stack, o1); shuntOperators(outputQueue, stack, o1);
stack.push(token); stack.push(token);
break;
} }
case UNARY_OPERATOR: case UNARY_OPERATOR -> {
{
if (previousToken != null && previousToken.type != Token.TokenType.OPERATOR if (previousToken != null && previousToken.type != Token.TokenType.OPERATOR
&& previousToken.type != Token.TokenType.COMMA && previousToken.type != Token.TokenType.OPEN_PAREN) && previousToken.type != Token.TokenType.COMMA && previousToken.type != Token.TokenType.OPEN_PAREN) {
{
throw new ExpressionException(c, this, token, "Invalid position for unary operator " + token); throw new ExpressionException(c, this, token, "Invalid position for unary operator " + token);
} }
ILazyOperator o1 = operators.get(token.surface); ILazyOperator o1 = operators.get(token.surface);
if (o1 == null) if (o1 == null) {
{
throw new ExpressionException(c, this, token, "Unknown unary operator '" + token.surface.substring(0, token.surface.length() - 1) + "'"); throw new ExpressionException(c, this, token, "Unknown unary operator '" + token.surface.substring(0, token.surface.length() - 1) + "'");
} }
shuntOperators(outputQueue, stack, o1); shuntOperators(outputQueue, stack, o1);
stack.push(token); stack.push(token);
break;
} }
case OPEN_PAREN: case OPEN_PAREN -> {
// removed implicit multiplication in this missing code block // removed implicit multiplication in this missing code block
if (previousToken != null && previousToken.type == Token.TokenType.FUNCTION) if (previousToken != null && previousToken.type == Token.TokenType.FUNCTION) {
{
outputQueue.add(token); outputQueue.add(token);
} }
stack.push(token); stack.push(token);
break; }
case CLOSE_PAREN: case CLOSE_PAREN -> {
if (previousToken != null && previousToken.type == Token.TokenType.OPERATOR) if (previousToken != null && previousToken.type == Token.TokenType.OPERATOR) {
{
throw new ExpressionException(c, this, previousToken, "Missing parameter(s) for operator " + previousToken); throw new ExpressionException(c, this, previousToken, "Missing parameter(s) for operator " + previousToken);
} }
while (!stack.isEmpty() && stack.top().type != Token.TokenType.OPEN_PAREN) while (!stack.isEmpty() && stack.top().type != Token.TokenType.OPEN_PAREN) {
{
outputQueue.add(stack.pop()); outputQueue.add(stack.pop());
} }
if (stack.isEmpty()) if (stack.isEmpty()) {
{
throw new ExpressionException(c, this, "Mismatched parentheses"); throw new ExpressionException(c, this, "Mismatched parentheses");
} }
stack.pop(); stack.pop();
if (!stack.isEmpty() && stack.top().type == Token.TokenType.FUNCTION) if (!stack.isEmpty() && stack.top().type == Token.TokenType.FUNCTION) {
{
outputQueue.add(stack.pop()); outputQueue.add(stack.pop());
} }
break; }
case MARKER: case MARKER -> {
if ("$".equals(token.surface)) if ("$".equals(token.surface)) {
{
StringBuilder sb = new StringBuilder(expression); StringBuilder sb = new StringBuilder(expression);
sb.setCharAt(token.pos, '\n'); sb.setCharAt(token.pos, '\n');
expression = sb.toString(); expression = sb.toString();
} }
break; }
} }
if (token.type != Token.TokenType.MARKER) if (token.type != Token.TokenType.MARKER)
{ {
@@ -1437,7 +1410,7 @@ public class Expression
} }
else else
{ {
ExpressionNode newNode = new ExpressionNode(((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t)), Collections.emptyList(), token); ExpressionNode newNode = new ExpressionNode((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t), Collections.emptyList(), token);
token.node = newNode; token.node = newNode;
nodeStack.push(newNode); nodeStack.push(newNode);
} }
@@ -1767,7 +1740,7 @@ public class Expression
boolean leftOptimizable = operators.get(operator).isLeftAssoc(); boolean leftOptimizable = operators.get(operator).isLeftAssoc();
ExpressionNode optimizedChild = node.args.get(leftOptimizable ? 0 : (node.args.size() - 1)); ExpressionNode optimizedChild = node.args.get(leftOptimizable ? 0 : (node.args.size() - 1));
String type = optimizedChild.token.surface; String type = optimizedChild.token.surface;
if ((type.equals(operator) || type.equals(function)) && (!(optimizedChild.op instanceof LazyValue.ContextFreeLazyValue))) if ((type.equals(operator) || type.equals(function)) && !(optimizedChild.op instanceof LazyValue.ContextFreeLazyValue))
{ {
List<ExpressionNode> newargs = new ArrayList<>(); List<ExpressionNode> newargs = new ArrayList<>();
if (leftOptimizable) if (leftOptimizable)
@@ -1883,9 +1856,9 @@ public class Expression
// applying argument unpacking // applying argument unpacking
args = AbstractLazyFunction.lazify(AbstractLazyFunction.unpackLazy(args, ctx, requestedType)); args = AbstractLazyFunction.lazify(AbstractLazyFunction.unpackLazy(args, ctx, requestedType));
Value result; Value result;
if (operation instanceof ILazyFunction) if (operation instanceof final ILazyFunction iLazyFunction)
{ {
result = ((ILazyFunction) operation).lazyEval(ctx, expectedType, this, node.token, args).evalValue(null, expectedType); result = iLazyFunction.lazyEval(ctx, expectedType, this, node.token, args).evalValue(null, expectedType);
} }
else if (args.size() == 1) else if (args.size() == 1)
{ {
@@ -1922,38 +1895,31 @@ public class Expression
return (c, t) -> ret; return (c, t) -> ret;
} }
Token token = node.token; Token token = node.token;
switch (token.type) return switch (token.type) {
{ case UNARY_OPERATOR -> {
case UNARY_OPERATOR:
{
ILazyOperator op = operators.get(token.surface); ILazyOperator op = operators.get(token.surface);
Context.Type requestedType = op.staticType(expectedType); Context.Type requestedType = op.staticType(expectedType);
LazyValue arg = extractOp(ctx, node.args.get(0), requestedType); LazyValue arg = extractOp(ctx, node.args.get(0), requestedType);
return (c, t) -> op.lazyEval(c, t, this, token, arg, null).evalValue(c, t); yield (c, t) -> op.lazyEval(c, t, this, token, arg, null).evalValue(c, t);
} }
case OPERATOR: case OPERATOR -> {
{
ILazyOperator op = operators.get(token.surface); ILazyOperator op = operators.get(token.surface);
Context.Type requestedType = op.staticType(expectedType); Context.Type requestedType = op.staticType(expectedType);
LazyValue arg = extractOp(ctx, node.args.get(0), requestedType); LazyValue arg = extractOp(ctx, node.args.get(0), requestedType);
LazyValue arh = extractOp(ctx, node.args.get(1), requestedType); LazyValue arh = extractOp(ctx, node.args.get(1), requestedType);
return (c, t) -> op.lazyEval(c, t, this, token, arg, arh).evalValue(c, t); yield (c, t) -> op.lazyEval(c, t, this, token, arg, arh).evalValue(c, t);
} }
case VARIABLE: case VARIABLE -> (c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t);
return (c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t); case FUNCTION -> {
case FUNCTION:
{
ILazyFunction f = functions.get(token.surface); ILazyFunction f = functions.get(token.surface);
Context.Type requestedType = f.staticType(expectedType); Context.Type requestedType = f.staticType(expectedType);
List<LazyValue> params = node.args.stream().map(n -> extractOp(ctx, n, requestedType)).collect(Collectors.toList()); List<LazyValue> params = node.args.stream().map(n -> extractOp(ctx, n, requestedType)).collect(Collectors.toList());
return (c, t) -> f.lazyEval(c, t, this, token, params).evalValue(c, t); yield (c, t) -> f.lazyEval(c, t, this, token, params).evalValue(c, t);
} }
case CONSTANT: case CONSTANT -> node.op;
return node.op; default ->
default: throw new ExpressionException(ctx, this, node.token, "Unexpected token '" + node.token.type + " " + node.token.surface + "'");
throw new ExpressionException(ctx, this, node.token, "Unexpected token '" + node.token.type + " " + node.token.surface + "'"); };
}
} }
private void validate(Context c, List<Token> rpn) private void validate(Context c, List<Token> rpn)
@@ -1973,27 +1939,23 @@ public class Expression
for (Token token : rpn) for (Token token : rpn)
{ {
switch (token.type) switch (token.type) {
{ case UNARY_OPERATOR -> {
case UNARY_OPERATOR: if (stack.topInt() < 1) {
if (stack.topInt() < 1)
{
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator " + token); throw new ExpressionException(c, this, token, "Missing parameter(s) for operator " + token);
} }
break; }
case OPERATOR: case OPERATOR -> {
if (stack.topInt() < 2) if (stack.topInt() < 2) {
{ if (token.surface.equals(";")) {
if (token.surface.equals(";"))
{
throw new ExpressionException(c, this, token, "Empty expression found for ';'"); throw new ExpressionException(c, this, token, "Empty expression found for ';'");
} }
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator " + token); throw new ExpressionException(c, this, token, "Missing parameter(s) for operator " + token);
} }
// pop the operator's 2 parameters and add the result // pop the operator's 2 parameters and add the result
stack.set(stack.size() - 1, stack.topInt() - 2 + 1); stack.set(stack.size() - 1, stack.topInt() - 2 + 1);
break; }
case FUNCTION: case FUNCTION -> {
//ILazyFunction f = functions.get(token.surface);// don't validate global - userdef functions //ILazyFunction f = functions.get(token.surface);// don't validate global - userdef functions
//int numParams = stack.pop(); //int numParams = stack.pop();
//if (f != null && !f.numParamsVaries() && numParams != f.getNumParams()) //if (f != null && !f.numParamsVaries() && numParams != f.getNumParams())
@@ -2004,18 +1966,14 @@ public class Expression
// due to unpacking, all functions can have variable number of arguments // due to unpacking, all functions can have variable number of arguments
// we will be checking that at runtime. // we will be checking that at runtime.
// TODO try analyze arguments and assess if its possible that they are static // TODO try analyze arguments and assess if its possible that they are static
if (stack.size() <= 0) if (stack.size() <= 0) {
{
throw new ExpressionException(c, this, token, "Too many function calls, maximum scope exceeded"); throw new ExpressionException(c, this, token, "Too many function calls, maximum scope exceeded");
} }
// push the result of the function // push the result of the function
stack.set(stack.size() - 1, stack.topInt() + 1); stack.set(stack.size() - 1, stack.topInt() + 1);
break; }
case OPEN_PAREN: case OPEN_PAREN -> stack.push(0);
stack.push(0); default -> stack.set(stack.size() - 1, stack.topInt() + 1);
break;
default:
stack.set(stack.size() - 1, stack.topInt() + 1);
} }
} }
+3 -3
View File
@@ -40,7 +40,7 @@ public record Module(String name, String code, boolean library)
* *
* @param scriptName A {@link String} being the name of the script. The extension will be autocompleted * @param scriptName A {@link String} being the name of the script. The extension will be autocompleted
* @param isLibrary A {@link boolean} indicating whether or not the script is a library * @param isLibrary A {@link boolean} indicating whether or not the script is a library
* @return The created {@link BundledModule} * @return The created BundledModule
*/ */
public static Module carpetNative(String scriptName, boolean isLibrary) public static Module carpetNative(String scriptName, boolean isLibrary)
{ {
@@ -53,7 +53,7 @@ public record Module(String name, String code, boolean library)
* @param path A {@link String} being the path to the directory where the app is located. * @param path A {@link String} being the path to the directory where the app is located.
* @param scriptName A {@link String} being the name of the script. The extension will be autocompleted * @param scriptName A {@link String} being the name of the script. The extension will be autocompleted
* @param isLibrary A {@link boolean} indicating whether or not the script is a library * @param isLibrary A {@link boolean} indicating whether or not the script is a library
* @return The created {@link BundledModule} * @return The created BundledModule
* @see #fromJarPathWithCustomName(String, String, boolean) * @see #fromJarPathWithCustomName(String, String, boolean)
*/ */
public static Module fromJarPath(String path, String scriptName, boolean isLibrary) public static Module fromJarPath(String path, String scriptName, boolean isLibrary)
@@ -90,7 +90,7 @@ public record Module(String name, String code, boolean library)
public static Tag getData(Module module, ScriptServer scriptServer) public static Tag getData(Module module, ScriptServer scriptServer)
{ {
Path dataFile = resolveResource(module, scriptServer); Path dataFile = resolveResource(module, scriptServer);
if (dataFile == null || !Files.exists(dataFile) || !(Files.isRegularFile(dataFile))) if (dataFile == null || !Files.exists(dataFile) || !Files.isRegularFile(dataFile))
{ {
return null; return null;
} }
@@ -61,7 +61,7 @@ public class ScriptCommand
static static
{ {
Set<String> allFunctions = (new CarpetExpression(null, "null", null, null)).getExpr().getFunctionNames(); Set<String> allFunctions = new CarpetExpression(null, "null", null, null).getExpr().getFunctionNames();
scarpetFunctions = new TreeSet<>(Expression.none.getFunctionNames()); scarpetFunctions = new TreeSet<>(Expression.none.getFunctionNames());
APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new)); APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new));
} }
@@ -123,7 +123,7 @@ public class ScriptCommand
} }
/** /**
* A method to suggest the available scarpet scripts based off of the current player input and {@link AppStoreManager#APP_STORE_ROOT} * A method to suggest the available scarpet scripts based off of the current player input and AppStoreManager#APP_STORE_ROOT
* variable. * variable.
*/ */
private static CompletableFuture<Suggestions> suggestDownloadableApps( private static CompletableFuture<Suggestions> suggestDownloadableApps(
+6 -10
View File
@@ -48,7 +48,7 @@ public abstract class ScriptHost
{ {
randomizers.clear(); randomizers.clear();
} }
return randomizers.computeIfAbsent(aLong, Random::new); return randomizers.computeIfAbsent(aLong, seed -> new Random(seed));
} }
public boolean resetRandom(long aLong) public boolean resetRandom(long aLong)
@@ -134,8 +134,7 @@ public abstract class ScriptHost
return main == null; return main == null;
} }
@Nullable public final @Nullable Module main;
public final Module main;
@FunctionalInterface @FunctionalInterface
public interface ErrorSnooper public interface ErrorSnooper
@@ -234,8 +233,7 @@ public abstract class ScriptHost
protected abstract void runModuleCode(Context c, Module module); // this should be shell out in the executor protected abstract void runModuleCode(Context c, Module module); // this should be shell out in the executor
@Nullable public @Nullable FunctionValue getFunction(String name)
public FunctionValue getFunction(String name)
{ {
return getFunction(main, name); return getFunction(main, name);
} }
@@ -257,8 +255,7 @@ public abstract class ScriptHost
return ret; return ret;
} }
@Nullable private @Nullable FunctionValue getFunction(Module module, String name)
private FunctionValue getFunction(Module module, String name)
{ {
ModuleData local = getModuleData(module); ModuleData local = getModuleData(module);
FunctionValue ret = local.globalFunctions.get(name); // most uses would be from local scope anyways FunctionValue ret = local.globalFunctions.get(name); // most uses would be from local scope anyways
@@ -291,8 +288,7 @@ public abstract class ScriptHost
return target.globalFunctions.get(name); return target.globalFunctions.get(name);
} }
@Nullable private @Nullable ModuleData findModuleDataFromFunctionImports(String name, ModuleData source, int ttl)
private ModuleData findModuleDataFromFunctionImports(String name, ModuleData source, int ttl)
{ {
if (ttl > 64) if (ttl > 64)
{ {
@@ -570,7 +566,7 @@ public abstract class ScriptHost
return false; return false;
} }
deprecations.add(feature); deprecations.add(feature);
DEPRECATION_LOG.warn("App '" + getVisualName() + "' uses '" + feature + "', which is deprecated for removal. Check the docs for a replacement"); DEPRECATION_LOG.warn("App '{}' uses '{}', which is deprecated for removal. Check the docs for a replacement", getVisualName(), feature);
return true; return true;
} }
@@ -34,15 +34,13 @@ final class ListConverter<T> implements ValueConverter<List<T>>
return (allowSingletonCreation ? itemConverter.getTypeName() + " or " : "") + "list of " + itemConverter.getTypeName() + "s"; return (allowSingletonCreation ? itemConverter.getTypeName() + " or " : "") + "list of " + itemConverter.getTypeName() + "s";
} }
@Nullable
@Override @Override
public List<T> convert(Value value, @Nullable Context context) public @Nullable List<T> convert(Value value, @Nullable Context context)
{ {
return value instanceof ListValue ? convertListValue((ListValue) value, context) : allowSingletonCreation ? convertSingleton(value, context) : null; return value instanceof final ListValue listValue ? convertListValue(listValue, context) : allowSingletonCreation ? convertSingleton(value, context) : null;
} }
@Nullable private @Nullable List<T> convertListValue(ListValue values, @Nullable Context context)
private List<T> convertListValue(ListValue values, @Nullable Context context)
{ {
List<T> list = new ArrayList<>(values.getItems().size()); List<T> list = new ArrayList<>(values.getItems().size());
for (Value value : values) for (Value value : values)
@@ -57,8 +55,7 @@ final class ListConverter<T> implements ValueConverter<List<T>>
return list; return list;
} }
@Nullable private @Nullable List<T> convertSingleton(Value val, @Nullable Context context)
private List<T> convertSingleton(Value val, @Nullable Context context)
{ {
T converted = itemConverter.convert(val, context); T converted = itemConverter.convert(val, context);
if (converted == null) if (converted == null)
@@ -42,9 +42,9 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
public Map<K, V> convert(Value value, @Nullable Context context) public Map<K, V> convert(Value value, @Nullable Context context)
{ {
Map<K, V> result = new HashMap<>(); Map<K, V> result = new HashMap<>();
if (value instanceof MapValue) if (value instanceof MapValue mapValue)
{ {
for (Entry<Value, Value> entry : ((MapValue) value).getMap().entrySet()) for (Entry<Value, Value> entry : mapValue.getMap().entrySet())
{ {
K key = keyConverter.convert(entry.getKey(), context); K key = keyConverter.convert(entry.getKey(), context);
V val = valueConverter.convert(entry.getValue(), context); V val = valueConverter.convert(entry.getValue(), context);
@@ -106,17 +106,14 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
return acceptMultiParam; return acceptMultiParam;
} }
@Nullable
@Override @Override
public Map<K, V> convert(Value value, @Nullable Context context) { public @Nullable Map<K, V> convert(Value value, @Nullable Context context) {
return value instanceof MapValue ? super.convert(value, context) return value instanceof MapValue ? super.convert(value, context)
: value instanceof ListValue ? convertList(((ListValue)value).getItems(), context) : value instanceof final ListValue listValue ? convertList(listValue.getItems(), context)
: null; // Multiparam mode can only be used in evalAndConvert : null; // Multiparam mode can only be used in evalAndConvert
} }
private @Nullable Map<K, V> convertList(List<Value> valueList, @Nullable Context context)
@Nullable
private Map<K, V> convertList(List<Value> valueList, @Nullable Context context)
{ {
if (valueList.size() % 2 == 1) if (valueList.size() % 2 == 1)
{ {
@@ -137,9 +134,8 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
return map; return map;
} }
@Nullable
@Override @Override
public Map<K, V> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT) public @Nullable Map<K, V> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
{ {
if (!valueIterator.hasNext()) if (!valueIterator.hasNext())
{ {
@@ -51,9 +51,8 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
* @implNote Unlike most other converters, {@link OptionalConverter} will not call this method from * @implNote Unlike most other converters, {@link OptionalConverter} will not call this method from
* {@link #checkAndConvert(Iterator, Context, Context.Type)} and is only used as a fallback in types that don't support it. * {@link #checkAndConvert(Iterator, Context, Context.Type)} and is only used as a fallback in types that don't support it.
*/ */
@Nullable
@Override @Override
public Optional<R> convert(Value value, @Nullable Context context) public @Nullable Optional<R> convert(Value value, @Nullable Context context)
{ {
if (value.isNull()) if (value.isNull())
{ {
@@ -67,9 +66,8 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
return Optional.of(converted); return Optional.of(converted);
} }
@Nullable
@Override @Override
public Optional<R> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT) public @Nullable Optional<R> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
{ {
if (!valueIterator.hasNext() || valueIterator.next().isNull()) if (!valueIterator.hasNext() || valueIterator.next().isNull())
{ {
@@ -146,9 +146,8 @@ public interface Param
*/ */
static final ValueConverter<Context> CONTEXT_PROVIDER = new ValueConverter<>() static final ValueConverter<Context> CONTEXT_PROVIDER = new ValueConverter<>()
{ {
@Nullable
@Override @Override
public String getTypeName() public @Nullable String getTypeName()
{ {
return null; return null;
} }
@@ -178,9 +177,8 @@ public interface Param
*/ */
static final ValueConverter<Context.Type> CONTEXT_TYPE_PROVIDER = new ValueConverter<>() static final ValueConverter<Context.Type> CONTEXT_TYPE_PROVIDER = new ValueConverter<>()
{ {
@Nullable
@Override @Override
public String getTypeName() public @Nullable String getTypeName()
{ {
return null; return null;
} }
@@ -106,10 +106,9 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
return (SimpleTypeConverter<Value, R>) byResult.get(outputType); return (SimpleTypeConverter<Value, R>) byResult.get(outputType);
} }
@Nullable
@Override @Override
@SuppressWarnings("unchecked") // more than checked. not using class.cast because then "method is too big" for inlining, because javac is useless @SuppressWarnings("unchecked") // more than checked. not using class.cast because then "method is too big" for inlining, because javac is useless
public R convert(Value value, @Nullable Context context) // and adds millions of casts. This one is even removed public @Nullable R convert(Value value, @Nullable Context context) // and adds millions of casts. This one is even removed
{ {
return valueClass.isInstance(value) ? converter.apply((T)value, context) : null; return valueClass.isInstance(value) ? converter.apply((T)value, context) : null;
} }
@@ -80,10 +80,9 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
return (ValueCaster<R>) byResult.get(outputType); return (ValueCaster<R>) byResult.get(outputType);
} }
@Nullable
@Override @Override
@SuppressWarnings("unchecked") // more than checked, see SimpleTypeConverter#converter for reasoning @SuppressWarnings("unchecked") // more than checked, see SimpleTypeConverter#converter for reasoning
public R convert(Value value, @Nullable Context context) public @Nullable R convert(Value value, @Nullable Context context)
{ {
if (!outputType.isInstance(value)) if (!outputType.isInstance(value))
{ {
@@ -77,9 +77,8 @@ public interface ValueConverter<R>
* @return A converted value * @return A converted value
* @deprecated Calling this method instead of {@link #convert(Value, Context)} may not return values for some converters * @deprecated Calling this method instead of {@link #convert(Value, Context)} may not return values for some converters
*/ */
@Nullable
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
default R convert(Value value) default @Nullable R convert(Value value)
{ {
try try
{ {
@@ -211,8 +210,7 @@ public interface ValueConverter<R>
* @implNote This method's default implementation runs the {@link #convert(Value, Context)} function in the next {@link Value} ignoring {@link Context} and * @implNote This method's default implementation runs the {@link #convert(Value, Context)} function in the next {@link Value} ignoring {@link Context} and
* {@code theLazyT}. * {@code theLazyT}.
*/ */
@Nullable default @Nullable R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type contextType)
default R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type contextType)
{ {
return !valueIterator.hasNext() ? null : convert(valueIterator.next(), context); return !valueIterator.hasNext() ? null : convert(valueIterator.next(), context);
} }
+25 -35
View File
@@ -207,7 +207,7 @@ public class Auxiliary
Vec3 vec = locator.vec; Vec3 vec = locator.vec;
if (player == null) if (player == null)
{ {
for (ServerPlayer p : (world.players())) for (ServerPlayer p : world.players())
{ {
world.sendParticles(p, particle, true, true, vec.x, vec.y, vec.z, count, world.sendParticles(p, particle, true, true, vec.x, vec.y, vec.z, count,
spread, spread, spread, speed); spread, spread, spread, speed);
@@ -346,7 +346,7 @@ public class Auxiliary
} }
ShapeDispatcher.sendShape( ShapeDispatcher.sendShape(
(playerTargets.isEmpty()) ? cc.level().players() : playerTargets, playerTargets.isEmpty() ? cc.level().players() : playerTargets,
shapes, cc.registryAccess() shapes, cc.registryAccess()
); );
return Value.TRUE; return Value.TRUE;
@@ -469,8 +469,8 @@ public class Auxiliary
{ {
return Value.FALSE; return Value.FALSE;
} }
Tag source = ((NBTSerializableValue) (NBTSerializableValue.fromValue(lv.get(0)))).getTag(); Tag source = ((NBTSerializableValue) NBTSerializableValue.fromValue(lv.get(0))).getTag();
Tag match = ((NBTSerializableValue) (NBTSerializableValue.fromValue(lv.get(1)))).getTag(); Tag match = ((NBTSerializableValue) NBTSerializableValue.fromValue(lv.get(1))).getTag();
return BooleanValue.of(NbtUtils.compareNbt(match, source, numParam == 2 || lv.get(2).getBoolean())); return BooleanValue.of(NbtUtils.compareNbt(match, source, numParam == 2 || lv.get(2).getBoolean()));
}); });
@@ -560,39 +560,30 @@ public class Auxiliary
}); });
Function<Component, Packet<?>> packetGetter = null; Function<Component, Packet<?>> packetGetter = null;
String actionString = lv.get(1).getString().toLowerCase(Locale.ROOT); String actionString = lv.get(1).getString().toLowerCase(Locale.ROOT);
switch (actionString) switch (actionString) {
{ case "title" -> {
case "title":
packetGetter = ClientboundSetTitleTextPacket::new; packetGetter = ClientboundSetTitleTextPacket::new;
if (lv.size() < 3) if (lv.size() < 3) {
{
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type"); throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
} }
}
break; case "subtitle" -> {
case "subtitle":
packetGetter = ClientboundSetSubtitleTextPacket::new; packetGetter = ClientboundSetSubtitleTextPacket::new;
if (lv.size() < 3) if (lv.size() < 3) {
{
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type"); throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
} }
}
break; case "actionbar" -> {
case "actionbar":
packetGetter = ClientboundSetActionBarTextPacket::new; packetGetter = ClientboundSetActionBarTextPacket::new;
if (lv.size() < 3) if (lv.size() < 3) {
{
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type"); throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
} }
}
break; case "clear" -> packetGetter = x -> new ClientboundClearTitlesPacket(true); // resetting default fade
case "clear": case "player_list_header", "player_list_footer" -> {
packetGetter = x -> new ClientboundClearTitlesPacket(true); // resetting default fade }
break; default ->
case "player_list_header", "player_list_footer": throw new InternalExpressionException("'display_title' requires 'title', 'subtitle', 'actionbar', 'player_list_header', 'player_list_footer' or 'clear' as second argument");
break;
default:
throw new InternalExpressionException("'display_title' requires 'title', 'subtitle', 'actionbar', 'player_list_header', 'player_list_footer' or 'clear' as second argument");
} }
Component title; Component title;
boolean soundsTrue = false; boolean soundsTrue = false;
@@ -915,7 +906,7 @@ public class Auxiliary
if (lv.size() == 1) if (lv.size() == 1)
{ {
res = lv.get(0); res = lv.get(0);
CarpetScriptServer.LOG.info(res.getString()); CarpetScriptServer.LOG.info("{}", res.getString());
} }
else if (lv.size() == 2) else if (lv.size() == 2)
{ {
@@ -923,11 +914,11 @@ public class Auxiliary
res = lv.get(1); res = lv.get(1);
switch (level) switch (level)
{ {
case "debug" -> CarpetScriptServer.LOG.debug(res.getString()); case "debug" -> CarpetScriptServer.LOG.debug("{}", res.getString());
case "warn" -> CarpetScriptServer.LOG.warn(res.getString()); case "warn" -> CarpetScriptServer.LOG.warn("{}", res.getString());
case "info" -> CarpetScriptServer.LOG.info(res.getString()); case "info" -> CarpetScriptServer.LOG.info("{}", res.getString());
// Somehow issue deprecation // Somehow issue deprecation
case "fatal", "error" -> CarpetScriptServer.LOG.error(res.getString()); case "fatal", "error" -> CarpetScriptServer.LOG.error("{}", res.getString());
default -> throw new InternalExpressionException("Unknown log level for 'logger': " + level); default -> throw new InternalExpressionException("Unknown log level for 'logger': " + level);
} }
} }
@@ -1386,8 +1377,7 @@ public class Auxiliary
} }
} }
@Nullable private static <T> @Nullable Stat<T> getStat(StatType<T> type, Identifier id)
private static <T> Stat<T> getStat(StatType<T> type, Identifier id)
{ {
T key = type.getRegistry().getValue(id); T key = type.getRegistry().getValue(id);
if (key == null || !type.contains(key)) if (key == null || !type.contains(key))
@@ -365,7 +365,7 @@ public class Inventories
amount = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong(); amount = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong();
} }
// not enough // not enough
if (((amount == 1) && (!inventoryLocator.inventory().hasAnyOf(Set.of(searchItem.getItem())))) if (((amount == 1) && !inventoryLocator.inventory().hasAnyOf(Set.of(searchItem.getItem())))
|| (inventoryLocator.inventory().countItem(searchItem.getItem()) < amount)) || (inventoryLocator.inventory().countItem(searchItem.getItem()) < amount))
{ {
return Value.FALSE; return Value.FALSE;
@@ -170,7 +170,7 @@ public class Scoreboards
} }
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective); Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
Vanilla.Objective_setCriterion(objective, criterion); Vanilla.Objective_setCriterion(objective, criterion);
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList())).add(objective); Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList()).add(objective);
scoreboard.onObjectiveAdded(objective); scoreboard.onObjectiveAdded(objective);
return Value.FALSE; return Value.FALSE;
} }
@@ -215,7 +215,7 @@ public class Scoreboards
} }
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective); Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
Vanilla.Objective_setCriterion(objective, criterion); Vanilla.Objective_setCriterion(objective, criterion);
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList())).add(objective); Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList()).add(objective);
scoreboard.onObjectiveAdded(objective); scoreboard.onObjectiveAdded(objective);
return Value.TRUE; return Value.TRUE;
} }
@@ -585,7 +585,7 @@ public class Scoreboards
case "color" -> { case "color" -> {
if (propertyValue == null) if (propertyValue == null)
{ {
BossEvent.BossBarColor color = (bossBar).getColor(); BossEvent.BossBarColor color = bossBar.getColor();
return color == null ? Value.NULL : StringValue.of(color.getName()); return color == null ? Value.NULL : StringValue.of(color.getName());
} }
BossEvent.BossBarColor color = ((StringRepresentable.EnumCodec<BossEvent.BossBarColor>)BossEvent.BossBarColor.CODEC).byName(propertyValue.getString()); BossEvent.BossBarColor color = ((StringRepresentable.EnumCodec<BossEvent.BossBarColor>)BossEvent.BossBarColor.CODEC).byName(propertyValue.getString());
+67 -108
View File
@@ -31,7 +31,7 @@ import carpet.script.value.ValueConversions;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Util; import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
@@ -58,21 +58,20 @@ import net.minecraft.util.ProblemReporter;
import net.minecraft.util.random.WeightedList; import net.minecraft.util.random.WeightedList;
import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.level.ServerExplosion; import net.minecraft.world.level.ServerExplosion;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.levelgen.Aquifer; import net.minecraft.world.level.levelgen.Aquifer;
import net.minecraft.world.level.levelgen.NoiseRouterData;
import net.minecraft.world.level.levelgen.densityfunction.DensityFunction; import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
import net.minecraft.world.level.levelgen.densityfunction.DensityFunctions;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseRouter;
import net.minecraft.world.level.levelgen.RandomState; import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.levelgen.densityfunction.DensitySamplerSet;
import net.minecraft.world.level.levelgen.densityfunction.SamplerContext;
import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.StructureType; import net.minecraft.world.level.levelgen.structure.StructureType;
import net.minecraft.world.level.saveddata.WeatherData; import net.minecraft.world.level.saveddata.WeatherData;
import net.minecraft.world.level.storage.TagValueInput; import net.minecraft.world.level.storage.TagValueInput;
import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -96,7 +95,6 @@ import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.village.poi.PoiManager; import net.minecraft.world.entity.ai.village.poi.PoiManager;
import net.minecraft.world.entity.ai.village.poi.PoiRecord; import net.minecraft.world.entity.ai.village.poi.PoiRecord;
@@ -133,7 +131,6 @@ import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.StructureStart; import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.level.storage.ServerLevelData;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
@@ -351,7 +348,7 @@ public class WorldAccess
{ {
status = PoiManager.Occupancy.HAS_SPACE; status = PoiManager.Occupancy.HAS_SPACE;
} }
else if (!("any".equals(statusString))) else if (!"any".equals(statusString))
{ {
throw new InternalExpressionException( throw new InternalExpressionException(
"Incorrect POI occupation status " + status + " use `any`, " + "`occupied` or `available`" "Incorrect POI occupation status " + status + " use `any`, " + "`occupied` or `available`"
@@ -603,7 +600,7 @@ public class WorldAccess
}); });
expression.addContextFunction("loaded", -1, (c, t, lv) -> expression.addContextFunction("loaded", -1, (c, t, lv) ->
BooleanValue.of((((CarpetContext) c).level().hasChunkAt(BlockArgument.findIn((CarpetContext) c, lv, 0).block.getPos())))); BooleanValue.of(((CarpetContext) c).level().hasChunkAt(BlockArgument.findIn((CarpetContext) c, lv, 0).block.getPos())));
// Deprecated, use loaded_status as more indicative // Deprecated, use loaded_status as more indicative
expression.addContextFunction("loaded_ep", -1, (c, t, lv) -> expression.addContextFunction("loaded_ep", -1, (c, t, lv) ->
@@ -1088,9 +1085,7 @@ public class WorldAccess
ServerExplosion serverExplosion = new ServerExplosion(cc.level(), source, null, null, pos, powah, createFire, mode) ServerExplosion serverExplosion = new ServerExplosion(cc.level(), source, null, null, pos, powah, createFire, mode)
{ {
@Override @Override
@Nullable public @Nullable LivingEntity getIndirectSourceEntity()
public
LivingEntity getIndirectSourceEntity()
{ {
return theAttacker; return theAttacker;
} }
@@ -1484,7 +1479,7 @@ public class WorldAccess
} }
catch (NullPointerException npe) catch (NullPointerException npe)
{ {
CarpetScriptServer.LOG.error("Failed to detect structure: " + reg.getKey(str)); CarpetScriptServer.LOG.error("Failed to detect structure: {}", reg.getKey(str));
start = null; start = null;
} }
@@ -1494,7 +1489,7 @@ public class WorldAccess
} }
Value key = NBTSerializableValue.nameFromRegistryId(reg.getKey(str)); Value key = NBTSerializableValue.nameFromRegistryId(reg.getKey(str));
ret.put(key, (!needSize) ? Value.NULL : ValueConversions.of(start, cc.registryAccess())); ret.put(key, !needSize ? Value.NULL : ValueConversions.of(start, cc.registryAccess()));
} }
return MapValue.wrap(ret); return MapValue.wrap(ret);
}); });
@@ -1731,104 +1726,68 @@ public class WorldAccess
{ {
return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of)); return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of));
} }
RandomState router = level.getChunkSource().randomState();
return densityFunctionQueries.length == 1 return densityFunctionQueries.length == 1
? NumericValue.of(sampleNoise(router, level, densityFunctionQueries[0], pos)) ? NumericValue.of(sampleNoise(level, densityFunctionQueries[0], pos))
: ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(sampleNoise(router, level, s, pos)))); : ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(sampleNoise(level, s, pos))));
}); });
} }
public static double sampleNoise(RandomState router, ServerLevel level, String what, BlockPos pos)
private static @Nullable DensitySamplerSet samplersCache = null;
private static @Nullable ServerLevel samplerLevel = null;
public static double sampleNoise(ServerLevel level, String what, BlockPos pos)
{ {
DensityFunction densityFunction = switch (what) if (samplersCache == null || samplerLevel != level) {
{ final ServerChunkCache chunkSource = level.getChunkSource();
case "temperature" -> router.router().temperature(); final RandomState randomState = chunkSource.randomState();
case "vegetation" -> router.router().vegetation(); final SamplerContext samplerContext = SamplerContext.builder().enableCaches().build();
case "continents" -> router.router().continents(); samplersCache = randomState.samplersWithContext(samplerContext);
case "erosion" -> router.router().erosion(); samplerLevel = level;
case "depth" -> router.router().depth();
case "ridges" -> router.router().ridges();
case "preliminary_surface_level" -> router.router().preliminarySurfaceLevel();
case "final_density" -> router.router().finalDensity();
//case "vein_toggle" -> router. router(). veinToggle();
//case "vein_ridged" -> router.router().veinRidged();
//case "vein_gap" -> router.router().veinGap();
default -> {
Aquifer.Config aquifer = router.aquifers().orElse(null);
if (aquifer != null) {
yield switch (what) {
case "barrier_noise" -> aquifer.barrierNoise();
case "fluid_level_floodedness_noise" -> aquifer.fluidLevelFloodednessNoise();
case "fluid_level_spread_noise" -> aquifer.fluidLevelSpreadNoise();
case "lava_noise" -> aquifer.lavaNoise();
default -> stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, what));
};
}
yield stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, what));
}
};
return densityFunction.compute(new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ()));
}
// to be used with future seedable noise
public static final Function<Pair<ServerLevel, String>, DensityFunction> stupidWorldgenNoiseCacheGetter = Util.memoize(pair -> {
ServerLevel level = pair.getKey();
String densityFunctionQuery = pair.getValue();
ChunkGenerator generator = level.getChunkSource().getGenerator();
if (generator instanceof final NoiseBasedChunkGenerator noiseBasedChunkGenerator)
{
Registry<DensityFunction> densityFunctionRegistry = level.registryAccess().lookupOrThrow(Registries.DENSITY_FUNCTION);
NoiseRouter router = noiseBasedChunkGenerator.generatorSettings().value().noiseRouter();
DensityFunction densityFunction = switch (densityFunctionQuery)
{
case "temperature" -> router.temperature();
case "vegetation" -> router.vegetation();
case "continents" -> router.continents();
case "erosion" -> router.erosion();
case "depth" -> router.depth();
case "ridges" -> router.ridges();
case "preliminary_surface_level" -> router.preliminarySurfaceLevel();
case "final_density" -> router.finalDensity();
//case "vein_toggle" -> router.veinToggle();
//case "vein_ridged" -> router.veinRidged();
//case "vein_gap" -> router.veinGap();
default -> {
Aquifer.Config aquifers = noiseBasedChunkGenerator.generatorSettings().value().aquifers().orElse(null);
if (aquifers != null) {
yield switch (densityFunctionQuery) {
case "barrier_noise" -> aquifers.barrierNoise();
case "fluid_level_floodedness_noise" -> aquifers.fluidLevelFloodednessNoise();
case "fluid_level_spread_noise" -> aquifers.fluidLevelSpreadNoise();
case "lava_noise" -> aquifers.lavaNoise();
default -> {
DensityFunction result = densityFunctionRegistry.getValue(InputValidator.identifierOf(densityFunctionQuery));
if (result == null)
{
throw new InternalExpressionException("Density function '" + densityFunctionQuery + "' is not defined in the registies.");
}
yield result;
}
};
}
DensityFunction result = densityFunctionRegistry.getValue(InputValidator.identifierOf(densityFunctionQuery));
if (result == null)
{
throw new InternalExpressionException("Density function '" + densityFunctionQuery + "' is not defined in the registies.");
}
yield result;
}
};
RandomState randomState = RandomState.create(
level.registryAccess().lookupOrThrow(Registries.NOISE), level.getSeed(), noiseBasedChunkGenerator.generatorSettings().value()
);
DensityFunction.Visitor visitor = Vanilla.RandomState_getVisitor(randomState);
return densityFunction.mapAll(visitor);
} }
return DensityFunctions.zero();
}); ResourceKey<DensityFunction> key = switch (what) {
case "temperature" -> NoiseRouterData.OVERWORLD_FUNCTIONS.temperature();
case "vegetation" -> NoiseRouterData.OVERWORLD_FUNCTIONS.vegetation();
case "continents" -> NoiseRouterData.OVERWORLD_FUNCTIONS.continents();
case "erosion" -> NoiseRouterData.OVERWORLD_FUNCTIONS.erosion();
case "depth" -> NoiseRouterData.OVERWORLD_FUNCTIONS.depth();
case "ridges" -> NoiseRouterData.RIDGES;
case "preliminary_height" -> NoiseRouterData.OVERWORLD_FUNCTIONS.preliminarySurfaceLevel();
case "final_density" -> NoiseRouterData.OVERWORLD_FUNCTIONS.finalDensity();
default -> null;
};
final DensityFunction df;
if (key != null) {
df = level.registryAccess().lookupOrThrow(Registries.DENSITY_FUNCTION).get(key).get().value();
} else {
df = level.registryAccess().lookupOrThrow(Registries.DENSITY_FUNCTION).getValue(InputValidator.identifierOf(what));
}
if (df == null)
{
// last call, maybe its the aquifers
DensityFunction dfa;
if (level.getChunkSource().getGenerator() instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
Aquifer.Config aquifers = noiseBasedChunkGenerator.generatorSettings().value().aquifers().orElse(null);
if (aquifers != null) {
dfa = switch (what) {
case "barrier_noise" -> aquifers.barrierNoise();
case "fluid_level_floodedness_noise" -> aquifers.fluidLevelFloodednessNoise();
case "fluid_level_spread_noise" -> aquifers.fluidLevelSpreadNoise();
case "lava_noise" -> aquifers.lavaNoise();
default -> null;
};
if (dfa != null) {
return samplersCache.sampleValue(dfa, pos.getX(), pos.getY(), pos.getZ());
}
}
} else if (what.equalsIgnoreCase("barrier_noise") || what.equalsIgnoreCase("fluid_level_floodedness_noise") || what.equalsIgnoreCase("fluid_level_spread_noise") || what.equalsIgnoreCase("lava_noise")) {
// querying for aquifers outside of noise based level should not result in an invalid exception, but rather a 0 value, as the aquifers are not present in that world.
return 0;
}
throw new InternalExpressionException("Density function '" + what + "' is not defined in the registries.");
}
return samplersCache.sampleValue(df, pos.getX(), pos.getY(), pos.getZ());
}
} }
@@ -19,7 +19,7 @@ import org.jspecify.annotations.Nullable;
public class BlockArgument extends Argument public class BlockArgument extends Argument
{ {
public final BlockValue block; public final BlockValue block;
@Nullable public final String replacement; public final @Nullable String replacement;
private BlockArgument(BlockValue b, int o) private BlockArgument(BlockValue b, int o)
{ {
@@ -68,14 +68,14 @@ public class BlockArgument extends Argument
{ {
return new BlockArgument(BlockValue.fromString(v1.getString(), c.level()), 1 + offset); return new BlockArgument(BlockValue.fromString(v1.getString(), c.level()), 1 + offset);
} }
if (v1 instanceof BlockValue) if (v1 instanceof final BlockValue blockValue)
{ {
return new BlockArgument(((BlockValue) v1), 1 + offset); return new BlockArgument(blockValue, 1 + offset);
} }
BlockPos pos = c.origin(); BlockPos pos = c.origin();
if (v1 instanceof ListValue) if (v1 instanceof final ListValue listValue)
{ {
List<Value> args = ((ListValue) v1).getItems(); List<Value> args = listValue.getItems();
int xpos = (int) NumericValue.asNumber(args.get(0)).getLong(); int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
int ypos = (int) NumericValue.asNumber(args.get(1)).getLong(); int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
int zpos = (int) NumericValue.asNumber(args.get(2)).getLong(); int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
@@ -202,8 +202,7 @@ public class FileArgument
return host.resolveScriptFile(suffix); return host.resolveScriptFile(suffix);
} }
@Nullable private @Nullable Path toPath(@Nullable Module module)
private Path toPath(@Nullable Module module)
{ {
if (!isShared && module == null) if (!isShared && module == null)
{ {
@@ -245,8 +244,7 @@ public class FileArgument
} }
} }
@Nullable private @Nullable Path moduleRootPath(@Nullable Module module)
private Path moduleRootPath(@Nullable Module module)
{ {
return !isShared && module == null return !isShared && module == null
? null ? null
@@ -294,8 +292,7 @@ public class FileArgument
return true; return true;
} }
@Nullable public @Nullable Stream<Path> listFiles(Module module)
public Stream<Path> listFiles(Module module)
{ {
Path dir = toPath(module); Path dir = toPath(module);
if (dir == null || !Files.exists(dir)) if (dir == null || !Files.exists(dir))
@@ -316,8 +313,7 @@ public class FileArgument
} }
} }
@Nullable public @Nullable Stream<String> listFolder(Module module)
public Stream<String> listFolder(Module module)
{ {
Stream<String> strings; Stream<String> strings;
try (Stream<Path> result = listFiles(module)) try (Stream<Path> result = listFiles(module))
@@ -407,8 +403,7 @@ public class FileArgument
return true; return true;
} }
@Nullable public @Nullable Tag getNbtData(Module module) // aka getData
public Tag getNbtData(Module module) // aka getData
{ {
try try
{ {
@@ -430,8 +425,7 @@ public class FileArgument
//copied private method from net.minecraft.nbt.NbtIo.read() //copied private method from net.minecraft.nbt.NbtIo.read()
// to read non-compound tags - these won't be compressed // to read non-compound tags - these won't be compressed
@Nullable public static @Nullable Tag readTag(Path path)
public static Tag readTag(Path path)
{ {
try try
{ {
@@ -567,8 +561,7 @@ public class FileArgument
} }
} }
@Nullable public @Nullable List<String> listFile(Module module)
public List<String> listFile(Module module)
{ {
try try
{ {
@@ -615,8 +608,7 @@ public class FileArgument
} }
} }
@Nullable public @Nullable JsonElement readJsonFile(Module module)
public JsonElement readJsonFile(Module module)
{ {
try try
{ {
@@ -96,9 +96,9 @@ public class FunctionArgument extends Argument
throw CommandArgument.error("Function has empty spec"); throw CommandArgument.error("Function has empty spec");
} }
Value first = params.get(0); Value first = params.get(0);
if (first instanceof FunctionValue) if (first instanceof final FunctionValue functionValue)
{ {
function = (FunctionValue) first; function = functionValue;
} }
else else
{ {
@@ -22,8 +22,7 @@ public class Vector3Argument extends Argument
public final double yaw; public final double yaw;
public final double pitch; public final double pitch;
public boolean fromBlock = false; public boolean fromBlock = false;
@Nullable public @Nullable Entity entity = null;
public Entity entity = null;
private Vector3Argument(Vec3 v, int o) private Vector3Argument(Vec3 v, int o)
{ {
@@ -68,18 +67,18 @@ public class Vector3Argument extends Argument
try try
{ {
Value v1 = params.next(); Value v1 = params.next();
if (v1 instanceof BlockValue) if (v1 instanceof final BlockValue blockValue)
{ {
return (new Vector3Argument(Vec3.atCenterOf(((BlockValue) v1).getPos()), 1 + offset)).fromBlock(); return new Vector3Argument(Vec3.atCenterOf(blockValue.getPos()), 1 + offset).fromBlock();
} }
if (optionalEntity && v1 instanceof EntityValue) if (optionalEntity && v1 instanceof final EntityValue entityValue)
{ {
Entity e = ((EntityValue) v1).getEntity(); Entity e = entityValue.getEntity();
return new Vector3Argument(e.position(), 1 + offset).withEntity(e); return new Vector3Argument(e.position(), 1 + offset).withEntity(e);
} }
if (v1 instanceof ListValue) if (v1 instanceof final ListValue listValue)
{ {
List<Value> args = ((ListValue) v1).getItems(); List<Value> args = listValue.getItems();
Vec3 pos = new Vec3( Vec3 pos = new Vec3(
NumericValue.asNumber(args.get(0)).getDouble(), NumericValue.asNumber(args.get(0)).getDouble(),
NumericValue.asNumber(args.get(1)).getDouble(), NumericValue.asNumber(args.get(1)).getDouble(),
@@ -321,8 +321,7 @@ public abstract class CommandArgument
} }
protected String suffix; protected String suffix;
@Nullable protected @Nullable Collection<String> examples;
protected Collection<String> examples;
protected boolean needsMatching; protected boolean needsMatching;
protected boolean caseSensitive = true; protected boolean caseSensitive = true;
protected Function<String, SuggestionProvider<CommandSourceStack>> suggestionProvider; protected Function<String, SuggestionProvider<CommandSourceStack>> suggestionProvider;
@@ -385,11 +384,11 @@ public abstract class CommandArgument
throw error("Attempted to provide 'suggest' list while 'suggester' is present" + " for custom type " + suffix); throw error("Attempted to provide 'suggest' list while 'suggester' is present" + " for custom type " + suffix);
} }
Value suggestionValue = config.get("suggest"); Value suggestionValue = config.get("suggest");
if (!(suggestionValue instanceof ListValue)) if (!(suggestionValue instanceof final ListValue listValue))
{ {
throw error("Argument suggestions needs to be a list" + " for custom type " + suffix); throw error("Argument suggestions needs to be a list" + " for custom type " + suffix);
} }
examples = ((ListValue) suggestionValue).getItems().stream() examples = listValue.getItems().stream()
.map(Value::getString) .map(Value::getString)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
if (!examples.isEmpty()) if (!examples.isEmpty())
@@ -437,11 +436,11 @@ public abstract class CommandArgument
args.add(MapValue.wrap(params)); args.add(MapValue.wrap(params));
args.addAll(customSuggester.args); args.addAll(customSuggester.args);
Value response = host.handleCommand(context.getSource(), customSuggester.function, args); Value response = host.handleCommand(context.getSource(), customSuggester.function, args);
if (!(response instanceof ListValue)) if (!(response instanceof final ListValue listValue))
{ {
throw error("Custom suggester should return a list of options" + " for custom type " + suffix); throw error("Custom suggester should return a list of options" + " for custom type " + suffix);
} }
Collection<String> res = ((ListValue) response).getItems().stream().map(Value::getString).collect(Collectors.toList()); Collection<String> res = listValue.getItems().stream().map(Value::getString).collect(Collectors.toList());
currentSection.run(); currentSection.run();
return res; return res;
} }
@@ -504,12 +503,12 @@ public abstract class CommandArgument
if (config.containsKey("options")) if (config.containsKey("options"))
{ {
Value optionsValue = config.get("options"); Value optionsValue = config.get("options");
if (!(optionsValue instanceof ListValue)) if (!(optionsValue instanceof final ListValue listValue))
{ {
throw error("Custom string type requires options passed as a list" + " for custom type " + suffix); throw error("Custom string type requires options passed as a list" + " for custom type " + suffix);
} }
validOptions = ((ListValue) optionsValue).getItems().stream() validOptions = listValue.getItems().stream()
.map(v -> caseSensitive ? v.getString() : (v.getString().toLowerCase(Locale.ROOT))) .map(v -> caseSensitive ? v.getString() : v.getString().toLowerCase(Locale.ROOT))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
} }
@@ -879,11 +878,11 @@ public abstract class CommandArgument
if (config.containsKey("options")) if (config.containsKey("options"))
{ {
Value optionsValue = config.get("options"); Value optionsValue = config.get("options");
if (!(optionsValue instanceof ListValue)) if (!(optionsValue instanceof final ListValue listValue))
{ {
throw error("Custom sting type requires options passed as a list" + " for custom type " + suffix); throw error("Custom sting type requires options passed as a list" + " for custom type " + suffix);
} }
validOptions = ((ListValue) optionsValue).getItems().stream().map(v -> Identifier.parse(v.getString())).collect(Collectors.toSet()); validOptions = listValue.getItems().stream().map(v -> Identifier.parse(v.getString())).collect(Collectors.toSet());
} }
} }
} }
@@ -1005,6 +1004,7 @@ public abstract class CommandArgument
} }
private String restrict; private String restrict;
@SuppressWarnings("DoubleBraceInitialization")
private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<>() private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<>()
{{ {{
int i; int i;
@@ -1293,8 +1293,8 @@ public abstract class CommandArgument
protected Supplier<CommandArgument> factory(MinecraftServer server) protected Supplier<CommandArgument> factory(MinecraftServer server)
{ {
return argumentTypeSupplier != null return argumentTypeSupplier != null
? (() -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples)) ? () -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples)
: (() -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplierEx, valueExtractor, providesExamples, server)); : () -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplierEx, valueExtractor, providesExamples, server);
} }
} }
} }
@@ -22,8 +22,7 @@ public class CommandToken implements Comparable<CommandToken>
{ {
public final String surface; public final String surface;
public final boolean isArgument; public final boolean isArgument;
@Nullable public final @Nullable CommandArgument type;
public final CommandArgument type;
private CommandToken(String surface, @Nullable CommandArgument type) private CommandToken(String surface, @Nullable CommandArgument type)
{ {
@@ -32,8 +31,7 @@ public class CommandToken implements Comparable<CommandToken>
isArgument = type != null; isArgument = type != null;
} }
@Nullable public static @Nullable CommandToken getToken(String source, CarpetScriptHost host)
public static CommandToken getToken(String source, CarpetScriptHost host)
{ {
// todo add more type checking and return null // todo add more type checking and return null
if (!source.startsWith("<")) if (!source.startsWith("<"))
@@ -7,8 +7,7 @@ import org.jspecify.annotations.Nullable;
/* Exception thrown to terminate execution mid expression (aka return statement) */ /* Exception thrown to terminate execution mid expression (aka return statement) */
public class ExitStatement extends StacklessRuntimeException public class ExitStatement extends StacklessRuntimeException
{ {
@Nullable public final @Nullable Value retval;
public final Value retval;
public ExitStatement(@Nullable Value value) public ExitStatement(@Nullable Value value)
{ {
@@ -11,8 +11,7 @@ import java.util.Map;
public class Throwables public class Throwables
{ {
private final String id; private final String id;
@Nullable private final @Nullable Throwables parent;
private final Throwables parent;
private static final Map<String, Throwables> byId = new HashMap<>(); private static final Map<String, Throwables> byId = new HashMap<>();
+3 -38
View File
@@ -147,49 +147,14 @@ public class Carpet
return CarpetSettings.superSecretSetting; return CarpetSettings.superSecretSetting;
} }
@Nullable public static @Nullable Path fetchGlobalPath(MinecraftServer server) {
public static Module fetchGlobalModule(String name, boolean allowLibraries) throws IOException if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
{
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT)
{
Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts"); Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
if (!Files.exists(globalFolder)) return globalFolder;
{
Files.createDirectories(globalFolder);
}
try (Stream<Path> folderWalker = Files.walk(globalFolder))
{
Optional<Path> scriptPath = folderWalker
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
.findFirst();
if (scriptPath.isPresent())
{
return Module.fromPath(scriptPath.get());
}
}
} }
return null; return null;
} }
public static void addGlobalModules(final List<String> moduleNames, boolean includeBuiltIns) throws IOException
{
if (includeBuiltIns && (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT))
{
Path globalScripts = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
if (!Files.exists(globalScripts))
{
Files.createDirectories(globalScripts);
}
try (Stream<Path> folderWalker = Files.walk(globalScripts, FileVisitOption.FOLLOW_LINKS))
{
folderWalker
.filter(f -> f.toString().endsWith(".sc"))
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$", "").toLowerCase(Locale.ROOT)));
}
}
}
public static void assertRequirementMet(CarpetScriptHost host, String requiredModId, String stringPredicate) public static void assertRequirementMet(CarpetScriptHost host, String requiredModId, String stringPredicate)
{ {
VersionPredicate predicate; VersionPredicate predicate;
+9 -5
View File
@@ -17,7 +17,10 @@ import com.mojang.brigadier.CommandDispatcher;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.ModContainer;
import net.minecraft.commands.CommandResultCallback;
import net.minecraft.commands.CommandSigningContext;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.EntityAnchorArgument;
import net.minecraft.commands.arguments.blocks.BlockInput; import net.minecraft.commands.arguments.blocks.BlockInput;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@@ -31,6 +34,7 @@ import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.server.level.Ticket; import net.minecraft.server.level.Ticket;
import net.minecraft.server.permissions.PermissionSet; import net.minecraft.server.permissions.PermissionSet;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.util.TaskChainer;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
@@ -64,6 +68,7 @@ import net.minecraft.world.scores.criteria.ObjectiveCriteria;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.OptionalLong;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
import java.util.function.Predicate; import java.util.function.Predicate;
@@ -109,11 +114,6 @@ public class Vanilla
return ((TicketsFetcherInterface) ticketManager).getTicketsByPosition(); return ((TicketsFetcherInterface) ticketManager).getTicketsByPosition();
} }
public static DensityFunction.Visitor RandomState_getVisitor(RandomState randomState)
{
return ((RandomStateVisitorAccessor) (Object) randomState).getVisitor();
}
public static CompoundTag BlockInput_getTag(BlockInput blockInput) public static CompoundTag BlockInput_getTag(BlockInput blockInput)
{ {
return ((BlockStateArgumentInterface) blockInput).getCMTag(); return ((BlockStateArgumentInterface) blockInput).getCMTag();
@@ -144,6 +144,10 @@ public class Vanilla
return CarpetSettings.runPermissionLevel; return CarpetSettings.runPermissionLevel;
} }
public static void CommandSourceStack_setupPrivates(CommandSourceStack css, boolean bl, CommandResultCallback commandResultCallback, EntityAnchorArgument.Anchor anchor, CommandSigningContext commandSigningContext, TaskChainer taskChainer) {
((CommandSourceStackInterface) css).setupPrivates(bl, commandResultCallback, anchor, commandSigningContext, taskChainer);
};
public static int [] MinecraftServer_getReleaseTarget(MinecraftServer server) public static int [] MinecraftServer_getReleaseTarget(MinecraftServer server)
{ {
return CarpetSettings.releaseTarget; return CarpetSettings.releaseTarget;
@@ -58,8 +58,8 @@ public class Arithmetic
expression.addMathematicalUnaryFunction("cot", d -> 1.0 / Math.tan(Math.toRadians(d))); // Formula: cot(x) = cos(x) / sin(x) = 1 / tan(x) expression.addMathematicalUnaryFunction("cot", d -> 1.0 / Math.tan(Math.toRadians(d))); // Formula: cot(x) = cos(x) / sin(x) = 1 / tan(x)
expression.addMathematicalUnaryFunction("acot", d -> Math.toDegrees(Math.atan(1.0 / d)));// Formula: acot(x) = atan(1/x) expression.addMathematicalUnaryFunction("acot", d -> Math.toDegrees(Math.atan(1.0 / d)));// Formula: acot(x) = atan(1/x)
expression.addMathematicalUnaryFunction("coth", d -> 1.0 / Math.tanh(d)); // Formula: coth(x) = 1 / tanh(x) expression.addMathematicalUnaryFunction("coth", d -> 1.0 / Math.tanh(d)); // Formula: coth(x) = 1 / tanh(x)
expression.addMathematicalUnaryFunction("asinh", d -> Math.log(d + (Math.sqrt(Math.pow(d, 2) + 1)))); // Formula: asinh(x) = ln(x + sqrt(x^2 + 1)) expression.addMathematicalUnaryFunction("asinh", d -> Math.log(d + Math.sqrt(Math.pow(d, 2) + 1))); // Formula: asinh(x) = ln(x + sqrt(x^2 + 1))
expression.addMathematicalUnaryFunction("acosh", d -> Math.log(d + (Math.sqrt(Math.pow(d, 2) - 1)))); // Formula: acosh(x) = ln(x + sqrt(x^2 - 1)) expression.addMathematicalUnaryFunction("acosh", d -> Math.log(d + Math.sqrt(Math.pow(d, 2) - 1))); // Formula: acosh(x) = ln(x + sqrt(x^2 - 1))
expression.addMathematicalUnaryFunction("atanh", d -> // Formula: atanh(x) = 0.5*ln((1 + x)/(1 - x)) expression.addMathematicalUnaryFunction("atanh", d -> // Formula: atanh(x) = 0.5*ln((1 + x)/(1 - x))
{ {
if (Math.abs(d) > 1 || Math.abs(d) == 1) if (Math.abs(d) > 1 || Math.abs(d) == 1)
@@ -14,6 +14,7 @@ import carpet.script.value.ListValue;
import carpet.script.value.MapValue; import carpet.script.value.MapValue;
import carpet.script.value.NumericValue; import carpet.script.value.NumericValue;
import carpet.script.value.Value; import carpet.script.value.Value;
import com.google.common.collect.ImmutableMap;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
@@ -23,21 +24,19 @@ import java.util.Map;
public class Operators public class Operators
{ {
public static final Map<String, Integer> precedence = new HashMap<>() public static final Map<String, Integer> precedence = ImmutableMap.<String, Integer>builder()
{{ .put("attribute~:", 80)
put("attribute~:", 80); .put("unary+-!...", 60)
put("unary+-!...", 60); .put("exponent^", 40)
put("exponent^", 40); .put("multiplication*/%", 30)
put("multiplication*/%", 30); .put("addition+-", 20)
put("addition+-", 20); .put("compare>=><=<", 10)
put("compare>=><=<", 10); .put("equal==!=", 7)
put("equal==!=", 7); .put("and&&", 5)
put("and&&", 5); .put("or||", 4)
put("or||", 4); .put("assign=<>", 3)
put("assign=<>", 3); .put("def->", 2)
put("def->", 2); .put("nextop;", 1).build();
put("nextop;", 1);
}};
public static void apply(Expression expression) public static void apply(Expression expression)
{ {
@@ -149,7 +148,7 @@ public class Operators
expression.addLazyBinaryOperator("&&", "and", precedence.get("and&&"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) -> expression.addLazyBinaryOperator("&&", "and", precedence.get("and&&"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
{ // todo check how is optimizations going { // todo check how is optimizations going
Value v1 = lv1.evalValue(c, Context.BOOLEAN); Value v1 = lv1.evalValue(c, Context.BOOLEAN);
return v1.getBoolean() ? lv2 : ((cc, tt) -> v1); return v1.getBoolean() ? lv2 : (cc, tt) -> v1;
}, (c, t, lv) -> { }, (c, t, lv) -> {
int last = lv.size() - 1; int last = lv.size() - 1;
if (last == -1) if (last == -1)
@@ -184,7 +183,7 @@ public class Operators
expression.addLazyBinaryOperator("||", "or", precedence.get("or||"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) -> expression.addLazyBinaryOperator("||", "or", precedence.get("or||"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
{ {
Value v1 = lv1.evalValue(c, Context.BOOLEAN); Value v1 = lv1.evalValue(c, Context.BOOLEAN);
return v1.getBoolean() ? ((cc, tt) -> v1) : lv2; return v1.getBoolean() ? (cc, tt) -> v1 : lv2;
}, (c, t, lv) -> { }, (c, t, lv) -> {
int last = lv.size() - 1; int last = lv.size() - 1;
if (last == -1) if (last == -1)
@@ -379,7 +378,7 @@ public class Operators
return (cc, tt) -> Value.NULL; return (cc, tt) -> Value.NULL;
} }
Value address = lcv.address(); Value address = lcv.address();
if (!(container.put(address, v2))) if (!container.put(address, v2))
{ {
return (cc, tt) -> Value.NULL; return (cc, tt) -> Value.NULL;
} }
@@ -493,7 +493,7 @@ public class Sys
c.host.scriptServer().systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c)); c.host.scriptServer().systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c));
} }
Value res = c.host.scriptServer().systemGlobals.get(key); Value res = c.host.scriptServer().systemGlobals.get(key);
return res == null ? LazyValue.NULL : ((cc, tt) -> res); return res == null ? LazyValue.NULL : (cc, tt) -> res;
}); });
expression.addContextFunction("system_variable_set", 2, (c, t, lv) -> expression.addContextFunction("system_variable_set", 2, (c, t, lv) ->
@@ -41,7 +41,7 @@ public class Threading
expression.addContextFunction("task_count", -1, (c, t, lv) -> expression.addContextFunction("task_count", -1, (c, t, lv) ->
(!lv.isEmpty()) ? new NumericValue(c.host.taskCount(lv.get(0))) : new NumericValue(c.host.taskCount())); !lv.isEmpty() ? new NumericValue(c.host.taskCount(lv.get(0))) : new NumericValue(c.host.taskCount()));
expression.addUnaryFunction("task_value", v -> expression.addUnaryFunction("task_value", v ->
{ {
@@ -174,7 +174,7 @@ public class Threading
throw new InternalExpressionException("'task_await' requires a coroutine task value"); throw new InternalExpressionException("'task_await' requires a coroutine task value");
} }
Value ret = thread.next(); Value ret = thread.next();
return ret == Value.EOL ? ((cc, tt) -> Value.NULL) : ((cc, tt) -> ret); return ret == Value.EOL ? (cc, tt) -> Value.NULL : (cc, tt) -> ret;
}); });
expression.addLazyFunction("task_ready", 1, (c, t, lv) -> expression.addLazyFunction("task_ready", 1, (c, t, lv) ->
@@ -71,8 +71,7 @@ public class AppStoreManager
public static class StoreNode public static class StoreNode
{ {
public String name; public String name;
@Nullable public @Nullable StoreNode parent;
public StoreNode parent;
public Map<String, StoreNode> children; public Map<String, StoreNode> children;
public boolean sealed; public boolean sealed;
public String value; public String value;
@@ -406,7 +405,7 @@ public class AppStoreManager
{ {
throw new InternalExpressionException("Unable to write resource " + target); throw new InternalExpressionException("Unable to write resource " + target);
} }
CarpetScriptServer.LOG.info("Downloaded resource " + target + " from " + contentUrl); CarpetScriptServer.LOG.info("Downloaded resource {} from {}", target, contentUrl);
} }
/** /**
@@ -417,8 +416,7 @@ public class AppStoreManager
* @param contentUrl The full content URL, from {@link #getFullContentUrl(String, StoreNode, CommandSourceStack)} * @param contentUrl The full content URL, from {@link #getFullContentUrl(String, StoreNode, CommandSourceStack)}
* @return A {@link StoreNode} that can be used in an app that came from the provided source * @return A {@link StoreNode} that can be used in an app that came from the provided source
*/ */
@Nullable private static @Nullable StoreNode getNewStoreNode(CommandSourceStack commandSource, StoreNode originalSource, String sourceString, String contentUrl)
private static StoreNode getNewStoreNode(CommandSourceStack commandSource, StoreNode originalSource, String sourceString, String contentUrl)
{ {
StoreNode next = originalSource; StoreNode next = originalSource;
if (sourceString == contentUrl) // External URL (check getFullUrlContent) if (sourceString == contentUrl) // External URL (check getFullUrlContent)
@@ -471,7 +469,7 @@ public class AppStoreManager
{ {
throw new InternalExpressionException("Error when installing app dependencies: " + e); throw new InternalExpressionException("Error when installing app dependencies: " + e);
} }
CarpetScriptServer.LOG.info("Downloaded app " + target + " from " + contentUrl); CarpetScriptServer.LOG.info("Downloaded app {} from {}", target, contentUrl);
} }
public static class CommandRuntimeException extends RuntimeException { public static class CommandRuntimeException extends RuntimeException {
@@ -20,9 +20,11 @@ import net.minecraft.world.attribute.EnvironmentAttribute;
import net.minecraft.world.attribute.EnvironmentAttributes; import net.minecraft.world.attribute.EnvironmentAttributes;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import org.joml.Vector3fc;
public class BiomeInfo public class BiomeInfo
{ {
@SuppressWarnings("DoubleBraceInitialization")
public static final Map<String, BiFunction<ServerLevel, Biome, Value>> biomeFeatures = new HashMap<>() public static final Map<String, BiFunction<ServerLevel, Biome, Value>> biomeFeatures = new HashMap<>()
{{ {{
put("tags", (w, b) -> ListValue.wrap(w.registryAccess().lookupOrThrow(Registries.BIOME).getTags().filter(p -> p.stream().anyMatch(h -> h.value() == b)).map(ValueConversions::of))); put("tags", (w, b) -> ListValue.wrap(w.registryAccess().lookupOrThrow(Registries.BIOME).getTags().filter(p -> p.stream().anyMatch(h -> h.value() == b)).map(ValueConversions::of)));
@@ -47,7 +49,7 @@ public class BiomeInfo
}); });
}}; }};
private static Value fromEnvironmentalAttribute(ServerLevel w, Biome b, EnvironmentAttribute<Integer> fogColor) { private static Value fromEnvironmentalAttribute(ServerLevel w, Biome b, EnvironmentAttribute<Vector3fc> fogColor) {
return ValueConversions.ofRGB(b.getAttributes().applyModifier(fogColor, w.dimensionType().attributes().applyModifier(fogColor, fogColor.defaultValue()))); return ValueConversions.ofRGB(b.getAttributes().applyModifier(fogColor, w.dimensionType().attributes().applyModifier(fogColor, fogColor.defaultValue())));
} }
} }
@@ -47,6 +47,7 @@ import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.RandomState; import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.levelgen.VerticalAnchor; import net.minecraft.world.level.levelgen.VerticalAnchor;
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate; import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
import net.minecraft.world.level.levelgen.densityfunction.SamplerContext;
import net.minecraft.world.level.levelgen.feature.CoralClawFeature; import net.minecraft.world.level.levelgen.feature.CoralClawFeature;
import net.minecraft.world.level.levelgen.feature.CoralTreeFeature; import net.minecraft.world.level.levelgen.feature.CoralTreeFeature;
import net.minecraft.world.level.levelgen.feature.CuboidPlacement; import net.minecraft.world.level.levelgen.feature.CuboidPlacement;
@@ -85,12 +86,9 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProc
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
import static net.minecraft.world.level.levelgen.feature.TreeFeature.CAN_PLACE_BELOW_TREE_TRUNKS;
public class FeatureGenerator public class FeatureGenerator
{ {
@Nullable public static synchronized @Nullable Boolean plop(String featureName, ServerLevel world, BlockPos pos)
public static synchronized Boolean plop(String featureName, ServerLevel world, BlockPos pos)
{ {
Function<ServerLevel, Thing> custom = featureMap.get(featureName); Function<ServerLevel, Thing> custom = featureMap.get(featureName);
if (custom != null) if (custom != null)
@@ -148,8 +146,7 @@ public class FeatureGenerator
return null; return null;
} }
@Nullable public static @Nullable Structure resolveConfiguredStructure(String name, ServerLevel world, BlockPos pos)
public static Structure resolveConfiguredStructure(String name, ServerLevel world, BlockPos pos)
{ {
Identifier id = Identifier.parse(name); Identifier id = Identifier.parse(name);
Structure configuredStructureFeature = world.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValue(id); Structure configuredStructureFeature = world.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValue(id);
@@ -269,8 +266,8 @@ public class FeatureGenerator
{ {
//Holder<Biome> genBiome = generator.getBiomeSource().getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ()), seed.sampler()); //Holder<Biome> genBiome = generator.getBiomeSource().getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ()), seed.sampler());
if (structure.findValidGenerationPoint(new Structure.GenerationContext( if (structure.findValidGenerationPoint(new Structure.GenerationContext(
world.registryAccess(), generator, world.uncachedBiomeResolver(), world.registryAccess(), generator, generator.getBiomeSource(), seed.createClimateSampler(SamplerContext.EMPTY_UNCACHED),
seed, world.getStructureManager(), world.getSeed(), chunkPos, world, structureBiomes::contains seed, world.getStructureTemplateManager(), world.getSeed(), chunkPos, world, structureBiomes::contains
)).isPresent()) )).isPresent())
{ {
return StructureStart.INVALID_START; return StructureStart.INVALID_START;
@@ -279,7 +276,7 @@ public class FeatureGenerator
else else
{ {
StructureStart filledStructure = structure.generate(Holder.direct(structure), world.dimension(), StructureStart filledStructure = structure.generate(Holder.direct(structure), world.dimension(),
world.registryAccess(), generator, world.uncachedBiomeResolver(), seed, world.getStructureManager(), world.registryAccess(), generator, generator.getBiomeSource(), seed.createClimateSampler(SamplerContext.EMPTY_UNCACHED), seed, world.getStructureTemplateManager(),
world.getSeed(), chunkPos, 0, world, structureBiomes::contains); world.getSeed(), chunkPos, 0, world, structureBiomes::contains);
if (filledStructure != null && filledStructure.isValid()) if (filledStructure != null && filledStructure.isValid())
{ {
@@ -289,17 +286,17 @@ public class FeatureGenerator
return null; return null;
} }
private static RuleBasedStateProvider belowTrees = RuleBasedStateProvider.ifTrueThenProvide(CAN_PLACE_BELOW_TREE_TRUNKS, Blocks.DIRT); private static RuleBasedStateProvider belowTrees = RuleBasedStateProvider.ifTrueThenProvide(BlockPredicate.not(BlockPredicate.matchesTag(BlockTags.CANNOT_REPLACE_BELOW_TREE_TRUNK)), Blocks.DIRT);
private static TreeFeature.Builder createTree(Block block, Block block2, int i, int j, int k, int l) private static TreeFeature.Builder createTree(Block block, Block block2, int i, int j, int k, int l)
{ {
return new TreeFeature.Builder(BlockStateProvider.simple(block), new StraightTrunkPlacer(i, j, k), BlockStateProvider.simple(block2), new BlobFoliagePlacer(ConstantInt.of(l), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), belowTrees); return new TreeFeature.Builder(BlockStateProvider.of(block), new StraightTrunkPlacer(i, j, k), BlockStateProvider.of(block2), new BlobFoliagePlacer(ConstantInt.of(l), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), Holder.direct( belowTrees));
} }
// from AquaticFeatures // from AquaticFeatures
private static Holder<PlacedFeature> wallCoral(final HolderGetter<Block> blocks, final Direction direction) { private static Holder<PlacedFeature> wallCoral(final HolderGetter<Block> blocks, final Direction direction) {
return PlacementUtils.inlinePlaced( return PlacementUtils.inlinePlaced(
new SimpleBlockFeature(new RotatedBlockProvider(new RandomBlockProvider(blocks.getOrThrow(BlockTags.WALL_CORALS)), Optional.of(direction))), new SimpleBlockFeature(new RotatedBlockProvider(Holder.direct(new RandomBlockProvider(blocks.getOrThrow(BlockTags.WALL_CORALS))), Optional.of(direction))),
new RandomChancePlacement(0.2f), new RandomChancePlacement(0.2f),
OffsetPlacement.of(direction), OffsetPlacement.of(direction),
BlockPredicateFilter.forPredicate(BlockPredicate.matchesBlocks(Blocks.WATER)) BlockPredicateFilter.forPredicate(BlockPredicate.matchesBlocks(Blocks.WATER))
@@ -308,7 +305,7 @@ public class FeatureGenerator
public static Feature coral(final HolderGetter<Feature> features, final HolderGetter<Block> blocks, final Block block) { public static Feature coral(final HolderGetter<Feature> features, final HolderGetter<Block> blocks, final Block block) {
return new OverlayFeature(HolderSet.direct( return new OverlayFeature(HolderSet.direct(
PlacementUtils.inlinePlaced(new SimpleBlockFeature(BlockStateProvider.simple(block))), PlacementUtils.inlinePlaced(new SimpleBlockFeature(BlockStateProvider.of(block))),
PlacementUtils.inlinePlaced( PlacementUtils.inlinePlaced(
new WeightedRandomSelectorFeature(WeightedList.of( new WeightedRandomSelectorFeature(WeightedList.of(
new Weighted<>(PlacementUtils.inlinePlaced(new SimpleBlockFeature(new RandomBlockProvider(blocks.getOrThrow(BlockTags.CORALS)))), 20), new Weighted<>(PlacementUtils.inlinePlaced(new SimpleBlockFeature(new RandomBlockProvider(blocks.getOrThrow(BlockTags.CORALS)))), 20),
@@ -366,14 +363,13 @@ public class FeatureGenerator
); );
} }
@SuppressWarnings("DoubleBraceInitialization")
public static final Map<String, Function<ServerLevel, Thing>> featureMap = new HashMap<>() public static final Map<String, Function<ServerLevel, Thing>> featureMap = new HashMap<>()
{{ {{
// TODO remove this using what place feature is using // TODO remove this using what place feature is using
put("oak_bees", l -> simpleTree(createTree(Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))))); put("oak_bees", l -> simpleTree(createTree(Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
put("fancy_oak_bees", l -> simpleTree(new TreeFeature.Builder(BlockStateProvider.simple(Blocks.OAK_LOG), new FancyTrunkPlacer(3, 11, 0), BlockStateProvider.simple(Blocks.OAK_LEAVES), new FancyFoliagePlacer(ConstantInt.of(2), ConstantInt.of(4), 4), new TwoLayersFeatureSize(0, 0, 0, OptionalInt.of(4)), belowTrees).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))))); put("fancy_oak_bees", l -> simpleTree(new TreeFeature.Builder(BlockStateProvider.of(Blocks.OAK_LOG), new FancyTrunkPlacer(3, 11, 0), BlockStateProvider.of(Blocks.OAK_LEAVES), new FancyFoliagePlacer(ConstantInt.of(2), ConstantInt.of(4), 4), new TwoLayersFeatureSize(0, 0, 0, OptionalInt.of(4)), Holder.direct(belowTrees)).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
put("birch_bees", l -> simpleTree(createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))))); put("birch_bees", l -> simpleTree(createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
put("coral_tree", l -> simplePlop(coral(l, 0))); put("coral_tree", l -> simplePlop(coral(l, 0)));
@@ -508,7 +504,7 @@ public class FeatureGenerator
checks.set(true); checks.set(true);
try try
{ {
StructureStart start = structure.generate(Holder.direct(structure), world.dimension(), world.registryAccess(), generator, world.uncachedBiomeResolver(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), ChunkPos.containing(pos), 0, world, b -> true); StructureStart start = structure.generate(Holder.direct(structure), world.dimension(), world.registryAccess(), generator, generator.getBiomeSource(), world.getChunkSource().randomState().createClimateSampler(SamplerContext.EMPTY_UNCACHED), world.getChunkSource().randomState(), world.getStructureTemplateManager(), world.getSeed(), ChunkPos.containing(pos), 0, world, b -> true);
if (start == StructureStart.INVALID_START) if (start == StructureStart.INVALID_START)
{ {
return false; return false;
@@ -552,7 +548,7 @@ public class FeatureGenerator
} }
catch (Exception booboo) catch (Exception booboo)
{ {
CarpetScriptServer.LOG.error("Unknown Exception while plopping structure: " + booboo, booboo); CarpetScriptServer.LOG.error("Unknown Exception while plopping structure: {}", booboo, booboo);
return false; return false;
} }
finally finally
@@ -50,8 +50,7 @@ public class GlocalFlag extends ThreadLocal<Boolean>
return result; return result;
} }
@Nullable public <T> @Nullable T runIfEnabled(Supplier<T> action)
public <T> T runIfEnabled(Supplier<T> action)
{ {
synchronized (this) synchronized (this)
{ {
@@ -26,8 +26,7 @@ public class ParticleParser
} }
} }
@Nullable public static @Nullable ParticleOptions getEffect(@Nullable String name, RegistryAccess lookup)
public static ParticleOptions getEffect(@Nullable String name, RegistryAccess lookup)
{ {
if (name == null) if (name == null)
{ {
@@ -21,6 +21,7 @@ import carpet.script.value.StringValue;
import carpet.script.value.Value; import carpet.script.value.Value;
import carpet.script.value.ValueConversions; import carpet.script.value.ValueConversions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@@ -236,8 +237,7 @@ public class ShapeDispatcher
} }
// client // client
@Nullable public static @Nullable ExpiringShape fromTag(CompoundTag tag, Level level)
public static ExpiringShape fromTag(CompoundTag tag, Level level)
{ {
Map<String, Value> options = new HashMap<>(); Map<String, Value> options = new HashMap<>();
for (String key : tag.keySet()) for (String key : tag.keySet())
@@ -245,7 +245,7 @@ public class ShapeDispatcher
Param decoder = Param.of.get(key); Param decoder = Param.of.get(key);
if (decoder == null) if (decoder == null)
{ {
CarpetScriptServer.LOG.info("Unknown parameter for shape: " + key); CarpetScriptServer.LOG.info("Unknown parameter for shape: {}", key);
return null; return null;
} }
Value decodedValue = decoder.decode(tag.get(key), level); Value decodedValue = decoder.decode(tag.get(key), level);
@@ -254,13 +254,13 @@ public class ShapeDispatcher
Value shapeValue = options.get("shape"); Value shapeValue = options.get("shape");
if (shapeValue == null) if (shapeValue == null)
{ {
CarpetScriptServer.LOG.info("Shape id missing in " + String.join(", ", tag.keySet())); CarpetScriptServer.LOG.info("Shape id missing in {}", String.join(", ", tag.keySet()));
return null; return null;
} }
BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeValue.getString()); BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeValue.getString());
if (factory == null) if (factory == null)
{ {
CarpetScriptServer.LOG.info("Unknown shape: " + shapeValue.getString()); CarpetScriptServer.LOG.info("Unknown shape: {}", shapeValue.getString());
return null; return null;
} }
try try
@@ -269,24 +269,23 @@ public class ShapeDispatcher
} }
catch (InternalExpressionException exc) catch (InternalExpressionException exc)
{ {
CarpetScriptServer.LOG.info(exc.getMessage()); CarpetScriptServer.LOG.info("", exc);
} }
return null; return null;
} }
public abstract static class ExpiringShape public abstract static class ExpiringShape
{ {
public static final Map<String, BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape>> shapeProviders = new HashMap<>() public static final ImmutableMap<String, BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape>> shapeProviders = ImmutableMap.<String, BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape>>builder().
{{ put("line", creator(Line::new)).
put("line", creator(Line::new)); put("box", creator(Box::new)).
put("box", creator(Box::new)); put("sphere", creator(Sphere::new)).
put("sphere", creator(Sphere::new)); put("cylinder", creator(Cylinder::new)).
put("cylinder", creator(Cylinder::new)); put("label", creator(DisplayedText::new)).
put("label", creator(DisplayedText::new)); put("polygon", creator(Polyface::new)).
put("polygon", creator(Polyface::new)); put("block", creator(() -> new DisplayedSprite(false))).
put("block", creator(() -> new DisplayedSprite(false))); put("item", creator(() -> new DisplayedSprite(true))).
put("item", creator(() -> new DisplayedSprite(true))); build();
}};
private static BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> creator(Supplier<ExpiringShape> shapeFactory) private static BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> creator(Supplier<ExpiringShape> shapeFactory)
{ {
@@ -978,78 +977,65 @@ public class ShapeDispatcher
return alterPoint; return alterPoint;
} }
alterPoint = new ArrayList<>(); alterPoint = new ArrayList<>();
switch (mode) switch (mode) {
{ case 4 -> {
case 4: for (int i = 0; i < vertexList.size(); i++) {
for (int i = 0; i < vertexList.size(); i++)
{
Vec3 vecA = vertexList.get(i); Vec3 vecA = vertexList.get(i);
if (relative.get(i)) if (relative.get(i)) {
{
vecA = relativiseRender(p.level(), vecA, 0); vecA = relativiseRender(p.level(), vecA, 0);
} }
i++; i++;
Vec3 vecB = vertexList.get(i); Vec3 vecB = vertexList.get(i);
if (relative.get(i)) if (relative.get(i)) {
{
vecB = relativiseRender(p.level(), vecB, 0); vecB = relativiseRender(p.level(), vecB, 0);
} }
i++; i++;
Vec3 vecC = vertexList.get(i); Vec3 vecC = vertexList.get(i);
if (relative.get(i)) if (relative.get(i)) {
{
vecC = relativiseRender(p.level(), vecC, 0); vecC = relativiseRender(p.level(), vecC, 0);
} }
alterDrawTriangles(vecA, vecB, vecC); alterDrawTriangles(vecA, vecB, vecC);
} }
break; }
case 6: case 6 -> {
Vec3 vec0 = vertexList.get(0); Vec3 vec0 = vertexList.get(0);
if (relative.get(0)) if (relative.get(0)) {
{
vec0 = relativiseRender(p.level(), vec0, 0); vec0 = relativiseRender(p.level(), vec0, 0);
} }
Vec3 vec1 = vertexList.get(1); Vec3 vec1 = vertexList.get(1);
if (relative.get(1)) if (relative.get(1)) {
{
vec1 = relativiseRender(p.level(), vec1, 0); vec1 = relativiseRender(p.level(), vec1, 0);
} }
for (int i = 2; i < vertexList.size(); i++) for (int i = 2; i < vertexList.size(); i++) {
{
Vec3 vec = vertexList.get(i); Vec3 vec = vertexList.get(i);
if (relative.get(i)) if (relative.get(i)) {
{
vec = relativiseRender(p.level(), vec, 0); vec = relativiseRender(p.level(), vec, 0);
} }
alterDrawTriangles(vec0, vec1, vec); alterDrawTriangles(vec0, vec1, vec);
vec1 = vec; vec1 = vec;
} }
break; }
case 5: case 5 -> {
Vec3 vecA = vertexList.get(0); Vec3 vecA = vertexList.get(0);
if (relative.get(0)) if (relative.get(0)) {
{
vecA = relativiseRender(p.level(), vecA, 0); vecA = relativiseRender(p.level(), vecA, 0);
} }
Vec3 vecB = vertexList.get(1); Vec3 vecB = vertexList.get(1);
if (relative.get(1)) if (relative.get(1)) {
{
vecB = relativiseRender(p.level(), vecB, 0); vecB = relativiseRender(p.level(), vecB, 0);
} }
for (int i = 2; i < vertexList.size(); i++) for (int i = 2; i < vertexList.size(); i++) {
{
Vec3 vec = vertexList.get(i); Vec3 vec = vertexList.get(i);
if (relative.get(i)) if (relative.get(i)) {
{
vec = relativiseRender(p.level(), vec, 0); vec = relativiseRender(p.level(), vec, 0);
} }
alterDrawTriangles(vecA, vecB, vec); alterDrawTriangles(vecA, vecB, vec);
vecA = vecB; vecA = vecB;
vecB = vec; vecB = vec;
} }
break; }
default: default -> {
break; }
} }
return alterPoint; return alterPoint;
@@ -1466,85 +1452,81 @@ public class ShapeDispatcher
public abstract static class Param public abstract static class Param
{ {
public static final Map<String, Param> of = new HashMap<>() public static final ImmutableMap<String, Param> of = ImmutableMap.<String, Param>builder()
{{ .put("mode", new StringChoiceParam("mode", "polygon", "strip", "triangles"))
put("mode", new StringChoiceParam("mode", "polygon", "strip", "triangles")); .put("relative", new OptionalBoolListParam("relative"))
put("relative", new OptionalBoolListParam("relative")); .put("inner", new BoolParam("inner"))
put("inner", new BoolParam("inner")); .put("shape", new ShapeParam())
put("shape", new ShapeParam()); .put("dim", new DimensionParam())
put("dim", new DimensionParam()); .put("duration", new NonNegativeIntParam("duration"))
put("duration", new NonNegativeIntParam("duration")); .put("color", new ColorParam("color"))
put("color", new ColorParam("color")); .put("follow", new EntityParam("follow"))
put("follow", new EntityParam("follow")); .put("variant", new StringChoiceParam("variant",
put("variant", new StringChoiceParam("variant", "NONE",
"NONE", "THIRD_PERSON_LEFT_HAND",
"THIRD_PERSON_LEFT_HAND", "THIRD_PERSON_RIGHT_HAND",
"THIRD_PERSON_RIGHT_HAND", "FIRST_PERSON_LEFT_HAND",
"FIRST_PERSON_LEFT_HAND", "FIRST_PERSON_RIGHT_HAND",
"FIRST_PERSON_RIGHT_HAND", "HEAD",
"HEAD", "GUI",
"GUI", "GROUND",
"GROUND", "FIXED",
"FIXED", "ON_SHELF")
"ON_SHELF")
{
@Override
public Value validate(Map<String, Value> o, MinecraftServer s, Value v)
{ {
return super.validate(o, s, new StringValue(v.getString().toUpperCase(Locale.ROOT))); @Override
} public Value validate(Map<String, Value> o, MinecraftServer s, Value v)
});
put("snap", new StringChoiceParam("snap",
"xyz", "xz", "yz", "xy", "x", "y", "z",
"dxdydz", "dxdz", "dydz", "dxdy", "dx", "dy", "dz",
"xdz", "dxz", "ydz", "dyz", "xdy", "dxy",
"xydz", "xdyz", "xdydz", "dxyz", "dxydz", "dxdyz"
));
put("line", new PositiveFloatParam("line"));
put("fill", new ColorParam("fill"));
put("from", new Vec3Param("from", false));
put("to", new Vec3Param("to", true));
put("center", new Vec3Param("center", false));
put("pos", new Vec3Param("pos", false));
put("radius", new PositiveFloatParam("radius"));
put("level", new PositiveIntParam("level"));
put("height", new FloatParam("height"));
put("width", new FloatParam("width"));
put("scale", new Vec3Param("scale", false)
{
@Override
public Value validate(java.util.Map<String, Value> options, MinecraftServer server, Value value)
{
if (value instanceof final NumericValue vn)
{ {
value = ListValue.of(vn, vn, vn); return super.validate(o, s, new StringValue(v.getString().toUpperCase(Locale.ROOT)));
} }
return super.validate(options, server, value); })
} .put("snap", new StringChoiceParam("snap",
"xyz", "xz", "yz", "xy", "x", "y", "z",
"dxdydz", "dxdz", "dydz", "dxdy", "dx", "dy", "dz",
"xdz", "dxz", "ydz", "dyz", "xdy", "dxy",
"xydz", "xdyz", "xdydz", "dxyz", "dxydz", "dxdyz"
))
.put("line", new PositiveFloatParam("line"))
.put("fill", new ColorParam("fill"))
.put("from", new Vec3Param("from", false))
.put("to", new Vec3Param("to", true))
.put("center", new Vec3Param("center", false))
.put("pos", new Vec3Param("pos", false))
.put("radius", new PositiveFloatParam("radius"))
.put("level", new PositiveIntParam("level"))
.put("height", new FloatParam("height"))
.put("width", new FloatParam("width"))
.put("scale", new Vec3Param("scale", false)
{
@Override
public Value validate(java.util.Map<String, Value> options, MinecraftServer server, Value value)
{
if (value instanceof final NumericValue vn)
{
value = ListValue.of(vn, vn, vn);
}
return super.validate(options, server, value);
}
})
.put("axis", new StringChoiceParam("axis", "x", "y", "z"))
.put("points", new PointsParam("points"))
.put("text", new FormattedTextParam("text"))
.put("value", new FormattedTextParam("value"))
.put("size", new PositiveIntParam("size"))
.put("align", new StringChoiceParam("align", "center", "left", "right"))
.put("block", new BlockParam("block"))
.put("item", new ItemParam("item"))
.put("blocklight", new NonNegativeIntParam("blocklight"))
.put("skylight", new NonNegativeIntParam("skylight"))
.put("indent", new FloatParam("indent"))
.put("raise", new FloatParam("raise"))
.put("tilt", new FloatParam("tilt"))
.put("lean", new FloatParam("lean"))
.put("turn", new FloatParam("turn"))
.put("facing", new StringChoiceParam("facing", "player", "camera", "north", "south", "east", "west", "up", "down"))
.put("doublesided", new BoolParam("doublesided"))
.put("debug", new BoolParam("debug"))
.build();
});
put("axis", new StringChoiceParam("axis", "x", "y", "z"));
put("points", new PointsParam("points"));
put("text", new FormattedTextParam("text"));
put("value", new FormattedTextParam("value"));
put("size", new PositiveIntParam("size"));
put("align", new StringChoiceParam("align", "center", "left", "right"));
put("block", new BlockParam("block"));
put("item", new ItemParam("item"));
put("blocklight", new NonNegativeIntParam("blocklight"));
put("skylight", new NonNegativeIntParam("skylight"));
put("indent", new FloatParam("indent"));
put("raise", new FloatParam("raise"));
put("tilt", new FloatParam("tilt"));
put("lean", new FloatParam("lean"));
put("turn", new FloatParam("turn"));
put("facing", new StringChoiceParam("facing", "player", "camera", "north", "south", "east", "west", "up", "down"));
put("doublesided", new BoolParam("doublesided"));
put("debug", new BoolParam("debug"));
}};
protected String id; protected String id;
protected Param(String id) protected Param(String id)
@@ -1552,8 +1534,7 @@ public class ShapeDispatcher
this.id = id; this.id = id;
} }
@Nullable public abstract @Nullable Tag toTag(Value value, final RegistryAccess regs); //validates value, returning null if not necessary to keep it and serialize
public abstract Tag toTag(Value value, final RegistryAccess regs); //validates value, returning null if not necessary to keep it and serialize
public abstract Value validate(Map<String, Value> options, MinecraftServer server, Value value); // makes sure the value is proper public abstract Value validate(Map<String, Value> options, MinecraftServer server, Value value); // makes sure the value is proper
@@ -1640,9 +1621,8 @@ public class ShapeDispatcher
return BlockValue.fromString(value.getString(), server.overworld()); return BlockValue.fromString(value.getString(), server.overworld());
} }
@Nullable
@Override @Override
public Tag toTag(Value value, final RegistryAccess regs) public @Nullable Tag toTag(Value value, final RegistryAccess regs)
{ {
if (value instanceof final BlockValue blv) if (value instanceof final BlockValue blv)
{ {
@@ -1758,9 +1738,8 @@ public class ShapeDispatcher
this.options = Sets.newHashSet(options); this.options = Sets.newHashSet(options);
} }
@Nullable
@Override @Override
public Value validate(Map<String, Value> options, MinecraftServer server, Value value) public @Nullable Value validate(Map<String, Value> options, MinecraftServer server, Value value)
{ {
if (this.options.contains(value.getString())) if (this.options.contains(value.getString()))
{ {
@@ -2046,7 +2025,7 @@ public class ShapeDispatcher
new NumericValue(e.getZ()) new NumericValue(e.getZ())
); );
} }
CarpetScriptServer.LOG.error("Value: " + value.getString()); CarpetScriptServer.LOG.error("Value: {}", value.getString());
throw new InternalExpressionException("'" + p.id + "' requires a triple, block or entity to indicate position"); throw new InternalExpressionException("'" + p.id + "' requires a triple, block or entity to indicate position");
} }
@@ -2206,7 +2185,7 @@ public class ShapeDispatcher
{ {
ServerLevel world = player.level(); ServerLevel world = player.level();
world.sendParticles(player, particle, true, true, world.sendParticles(player, particle, true, true,
(towards.x) / 2 + from.x, (towards.y) / 2 + from.y, (towards.z) / 2 + from.z, particles / 3, towards.x / 2 + from.x, towards.y / 2 + from.y, towards.z / 2 + from.z, particles / 3,
towards.x / 6, towards.y / 6, towards.z / 6, 0.0); towards.x / 6, towards.y / 6, towards.z / 6, 0.0);
world.sendParticles(player, particle, true, true, world.sendParticles(player, particle, true, true,
from.x, from.y, from.z, 1, 0.0, 0.0, 0.0, 0.0); from.x, from.y, from.z, 1, 0.0, 0.0, 0.0, 0.0);
@@ -2223,10 +2202,10 @@ public class ShapeDispatcher
{ {
ServerLevel world = player.level(); ServerLevel world = player.level();
world.sendParticles(player, particle, true, true, world.sendParticles(player, particle, true, true,
(towards.x) / center + from.x, (towards.y) / center + from.y, (towards.z) / center + from.z, particles / divider, towards.x / center + from.x, towards.y / center + from.y, towards.z / center + from.z, particles / divider,
towards.x / dev, towards.y / dev, towards.z / dev, 0.0); towards.x / dev, towards.y / dev, towards.z / dev, 0.0);
world.sendParticles(player, particle, true, true, world.sendParticles(player, particle, true, true,
(towards.x) * (1.0 - 1.0 / center) + from.x, (towards.y) * (1.0 - 1.0 / center) + from.y, (towards.z) * (1.0 - 1.0 / center) + from.z, particles / divider, towards.x * (1.0 - 1.0 / center) + from.x, towards.y * (1.0 - 1.0 / center) + from.y, towards.z * (1.0 - 1.0 / center) + from.z, particles / divider,
towards.x / dev, towards.y / dev, towards.z / dev, 0.0); towards.x / dev, towards.y / dev, towards.z / dev, 0.0);
} }
parts += 2 * particles / divider; parts += 2 * particles / divider;
@@ -4,6 +4,7 @@ import carpet.script.CarpetScriptServer;
import carpet.script.external.Carpet; import carpet.script.external.Carpet;
import carpet.script.utils.shapes.ShapeDirection; import carpet.script.utils.shapes.ShapeDirection;
import com.google.common.collect.ImmutableMap;
import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
@@ -63,44 +64,42 @@ public class ShapesRenderer
private final Map<ResourceKey<Level>, Long2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> labels; private final Map<ResourceKey<Level>, Long2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> labels;
private final Minecraft client; private final Minecraft client;
private final Map<String, BiFunction<Minecraft, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> renderedShapes private final Map<String, BiFunction<Minecraft, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> renderedShapes = ImmutableMap.<String, BiFunction<Minecraft, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>>>builder()
= new HashMap<>() .put("line", RenderedLine::new)
{{ .put("box", RenderedBox::new)
put("line", RenderedLine::new); .put("sphere", RenderedSphere::new)
put("box", RenderedBox::new); .put("cylinder", RenderedCylinder::new)
put("sphere", RenderedSphere::new); .put("label", RenderedText::new)
put("cylinder", RenderedCylinder::new); .put("polygon", RenderedPolyface::new)
put("label", RenderedText::new); .put("block", (c, s) -> new RenderedSprite(c, s, false))
put("polygon", RenderedPolyface::new); .put("item", (c, s) -> new RenderedSprite(c, s, true))
put("block", (c, s) -> new RenderedSprite(c, s, false)); .build();
put("item", (c, s) -> new RenderedSprite(c, s, true));
}};
public static void rotatePoseStackByShapeDirection(PoseStack poseStack, ShapeDirection shapeDirection, Camera camera, Vec3 objectPos) public static void rotatePoseStackByShapeDirection(PoseStack poseStack, ShapeDirection shapeDirection, Camera camera, Vec3 objectPos)
{ {
switch (shapeDirection) switch (shapeDirection)
{ {
case NORTH -> {} case NORTH -> {}
case SOUTH -> poseStack.mulPose(Axis.YP.rotationDegrees(180)); case SOUTH -> poseStack.rotate(Axis.YP.rotationDegrees(180));
case EAST -> poseStack.mulPose(Axis.YP.rotationDegrees(270)); case EAST -> poseStack.rotate(Axis.YP.rotationDegrees(270));
case WEST -> poseStack.mulPose(Axis.YP.rotationDegrees(90)); case WEST -> poseStack.rotate(Axis.YP.rotationDegrees(90));
case UP -> poseStack.mulPose(Axis.XP.rotationDegrees(90)); case UP -> poseStack.rotate(Axis.XP.rotationDegrees(90));
case DOWN -> poseStack.mulPose(Axis.XP.rotationDegrees(-90)); case DOWN -> poseStack.rotate(Axis.XP.rotationDegrees(-90));
case CAMERA -> poseStack.mulPose(camera.rotation()); case CAMERA -> poseStack.rotate(camera.rotation());
case PLAYER -> { case PLAYER -> {
Vec3 vector = objectPos.subtract(camera.position()); Vec3 vector = objectPos.subtract(camera.position());
double x = vector.x; double x = vector.x;
double y = vector.y; double y = vector.y;
double z = vector.z; double z = vector.z;
double d = Math.sqrt(x * x + z * z); double d = Math.sqrt(x * x + z * z);
float rotX = (float) (Math.atan2(x, z)); float rotX = (float) Math.atan2(x, z);
float rotY = (float) (Math.atan2(y, d)); float rotY = (float) Math.atan2(y, d);
// that should work somehow but it doesn't for some reason // that should work somehow but it doesn't for some reason
//matrices.mulPose(new Quaternion( -rotY, rotX, 0, false)); //matrices.mulPose(new Quaternion( -rotY, rotX, 0, false));
poseStack.mulPose(Axis.YP.rotation(rotX)); poseStack.rotate(Axis.YP.rotation(rotX));
poseStack.mulPose(Axis.XP.rotation(-rotY)); poseStack.rotate(Axis.XP.rotation(-rotY));
} }
} }
} }
@@ -239,7 +238,7 @@ public class ShapesRenderer
shapeFactory = renderedShapes.get(tag.getString("shape").orElseThrow()); shapeFactory = renderedShapes.get(tag.getString("shape").orElseThrow());
if (shapeFactory == null) if (shapeFactory == null)
{ {
CarpetScriptServer.LOG.info("Unrecognized shape: " + tag.getString("shape")); CarpetScriptServer.LOG.info("Unrecognized shape: {}", tag.getString("shape"));
} }
else else
{ {
@@ -373,21 +372,21 @@ public class ShapesRenderer
matrices.translate(0.5, 0.5, 0.5); matrices.translate(0.5, 0.5, 0.5);
} }
matrices.mulPose(camera1.rotation().conjugate(new Quaternionf())); matrices.rotate(camera1.rotation().conjugate(new Quaternionf()));
matrices.translate(v1.x - cx, v1.y - cy, v1.z - cz); matrices.translate(v1.x - cx, v1.y - cy, v1.z - cz);
rotatePoseStackByShapeDirection(matrices, shape.facing, camera1, isitem ? v1 : v1.add(0.5, 0.5, 0.5)); rotatePoseStackByShapeDirection(matrices, shape.facing, camera1, isitem ? v1 : v1.add(0.5, 0.5, 0.5));
if (shape.tilt != 0.0f) if (shape.tilt != 0.0f)
{ {
matrices.mulPose(Axis.ZP.rotationDegrees(-shape.tilt)); matrices.rotate(Axis.ZP.rotationDegrees(-shape.tilt));
} }
if (shape.lean != 0.0f) if (shape.lean != 0.0f)
{ {
matrices.mulPose(Axis.XP.rotationDegrees(-shape.lean)); matrices.rotate(Axis.XP.rotationDegrees(-shape.lean));
} }
if (shape.turn != 0.0f) if (shape.turn != 0.0f)
{ {
matrices.mulPose(Axis.YP.rotationDegrees(shape.turn)); matrices.rotate(Axis.YP.rotationDegrees(shape.turn));
} }
matrices.scale(shape.scaleX, shape.scaleY, shape.scaleZ); matrices.scale(shape.scaleX, shape.scaleY, shape.scaleZ);
@@ -399,7 +398,7 @@ public class ShapesRenderer
else else
{ {
// items seems to be flipped by default // items seems to be flipped by default
matrices.mulPose(Axis.YP.rotationDegrees(180)); matrices.rotate(Axis.YP.rotationDegrees(180));
} }
blockPos = BlockPos.containing(v1); blockPos = BlockPos.containing(v1);
@@ -546,15 +545,15 @@ public class ShapesRenderer
//RenderSystem.scalef(shape.size* 0.0025f, -shape.size*0.0025f, shape.size*0.0025f); //RenderSystem.scalef(shape.size* 0.0025f, -shape.size*0.0025f, shape.size*0.0025f);
if (shape.tilt != 0.0f) if (shape.tilt != 0.0f)
{ {
matrices.mulPose(Axis.ZP.rotationDegrees(shape.tilt)); matrices.rotate(Axis.ZP.rotationDegrees(shape.tilt));
} }
if (shape.lean != 0.0f) if (shape.lean != 0.0f)
{ {
matrices.mulPose(Axis.XP.rotationDegrees(shape.lean)); matrices.rotate(Axis.XP.rotationDegrees(shape.lean));
} }
if (shape.turn != 0.0f) if (shape.turn != 0.0f)
{ {
matrices.mulPose(Axis.YP.rotationDegrees(shape.turn)); matrices.rotate(Axis.YP.rotationDegrees(shape.turn));
} }
matrices.translate(-10 * shape.indent, -10 * shape.height - 9, (-10 * renderEpsilon) - 10 * shape.raise); matrices.translate(-10 * shape.indent, -10 * shape.height - 9, (-10 * renderEpsilon) - 10 * shape.raise);
//if (visibleThroughWalls) RenderSystem.disableDepthTest(); //if (visibleThroughWalls) RenderSystem.disableDepthTest();
@@ -564,11 +563,11 @@ public class ShapesRenderer
float text_x = 0; float text_x = 0;
if (shape.align == 0) if (shape.align == 0)
{ {
text_x = (float) (-textRenderer.width(shape.value.getString())) / 2.0F; text_x = (float) -textRenderer.width(shape.value.getString()) / 2.0F;
} }
else if (shape.align == 1) else if (shape.align == 1)
{ {
text_x = (float) (-textRenderer.width(shape.value.getString())); text_x = (float) -textRenderer.width(shape.value.getString());
} }
//try (ByteBufferBuilder bbb = new ByteBufferBuilder(RenderType.TRANSIENT_BUFFER_SIZE)) //try (ByteBufferBuilder bbb = new ByteBufferBuilder(RenderType.TRANSIENT_BUFFER_SIZE))
//{ //{
@@ -620,7 +619,7 @@ public class ShapesRenderer
} }
catch (ClassCastException ignored) catch (ClassCastException ignored)
{ {
CarpetScriptServer.LOG.error("shape " + rshape.shape.getClass() + " cannot cast to a Label"); CarpetScriptServer.LOG.error("shape {} cannot cast to a Label", rshape.shape.getClass());
} }
} }
} }
@@ -893,7 +892,7 @@ public class ShapesRenderer
} }
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick); Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
drawSphereWireframe(primitives, drawSphereWireframe(primitives,
(float) (vc.x), (float) (vc.y), (float) (vc.z), (float) vc.x, (float) vc.y, (float) vc.z,
(float) (shape.radius + renderEpsilon), shape.subdivisions, (float) (shape.radius + renderEpsilon), shape.subdivisions,
shape.argb, shape.lineWidth); shape.argb, shape.lineWidth);
} }
@@ -907,7 +906,7 @@ public class ShapesRenderer
} }
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick); Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
drawSphereFaces(primitives, drawSphereFaces(primitives,
(float) (vc.x ), (float) (vc.y ), (float) (vc.z ), (float) vc.x, (float) vc.y, (float) vc.z,
(float) (shape.radius + renderEpsilon), shape.subdivisions, (float) (shape.radius + renderEpsilon), shape.subdivisions,
shape.fargb); shape.fargb);
} }
@@ -1358,8 +1357,8 @@ public class ShapesRenderer
private static int shuffleColor(int argb) { private static int shuffleColor(int argb) {
int a = 0xff000000 & argb; int a = 0xff000000 & argb;
argb = (new Random(argb)).nextInt(); argb = new Random(argb).nextInt();
argb = (a) | (0x00ffffff & argb); argb = a | (0x00ffffff & argb);
return argb; return argb;
} }
@@ -1,6 +1,5 @@
package carpet.script.utils; package carpet.script.utils;
import carpet.fakes.CommandSourceStackInterface;
import carpet.script.external.Vanilla; import carpet.script.external.Vanilla;
import net.minecraft.commands.CommandResultCallback; import net.minecraft.commands.CommandResultCallback;
import net.minecraft.commands.CommandSigningContext; import net.minecraft.commands.CommandSigningContext;
@@ -31,8 +30,7 @@ public class SnoopyCommandSource extends CommandSourceStack
private final Vec3 position; private final Vec3 position;
private final ServerLevel world; private final ServerLevel world;
private final PermissionSet level; private final PermissionSet level;
private final String simpleName; private final CommandSourceStack.NamesProvider namesProvider;
private final Component name;
private final MinecraftServer server; private final MinecraftServer server;
// skipping silent since snooper is never silent // skipping silent since snooper is never silent
private final Entity entity; private final Entity entity;
@@ -49,15 +47,14 @@ public class SnoopyCommandSource extends CommandSourceStack
public SnoopyCommandSource(CommandSourceStack original, Component[] error, List<Component> chatOutput, OptionalLong[] returnValue) public SnoopyCommandSource(CommandSourceStack original, Component[] error, List<Component> chatOutput, OptionalLong[] returnValue)
{ {
super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()), super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()),
original.getTextName(), original.getDisplayName(), original.getServer(), original.getEntity() original.getServer(), original.getEntity()
//,false ,(b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer()) //,false ,(b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer())
); );
this.output = CommandSource.NULL; this.output = CommandSource.NULL;
this.position = original.getPosition(); this.position = original.getPosition();
this.world = original.getLevel(); this.world = original.getLevel();
this.level = Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()); this.level = Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer());
this.simpleName = original.getTextName(); this.namesProvider = original.namesProvider;
this.name = original.getDisplayName();
this.server = original.getServer(); this.server = original.getServer();
this.entity = original.getEntity(); this.entity = original.getEntity();
this.resultConsumer = (b, i) -> returnValue[0] = OptionalLong.of(i); this.resultConsumer = (b, i) -> returnValue[0] = OptionalLong.of(i);
@@ -67,21 +64,20 @@ public class SnoopyCommandSource extends CommandSourceStack
this.chatOutput = chatOutput; this.chatOutput = chatOutput;
this.signingContext = original.getSigningContext(); this.signingContext = original.getSigningContext();
this.taskChainer = TaskChainer.immediate(original.getServer()); this.taskChainer = TaskChainer.immediate(original.getServer());
((CommandSourceStackInterface) this).setupPrivates(false, (b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer())); Vanilla.CommandSourceStack_setupPrivates(this, false, (b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer()));
} }
public SnoopyCommandSource(ServerPlayer player, Component[] error, List<Component> output, int [] result) public SnoopyCommandSource(ServerPlayer player, Component[] error, List<Component> output, int [] result)
{ {
super(player.commandSource(), player.position(), player.getRotationVector(), super(player.commandSource(), player.position(), player.getRotationVector(),
player.level() instanceof final ServerLevel serverLevel ? serverLevel : null, player.level(),
player.level().getServer().getProfilePermissions(player.nameAndId()), player.getName().getString(), player.getDisplayName(), player.level().getServer().getProfilePermissions(player.nameAndId()),
player.level().getServer(), player); player.level().getServer(), player);
this.output = player.commandSource(); this.output = player.commandSource();
this.position = player.position(); this.position = player.position();
this.world = player.level() instanceof final ServerLevel serverLevel ? serverLevel : null; this.world = player.level();
this.level = player.level().getServer().getProfilePermissions(player.nameAndId()); this.level = player.level().getServer().getProfilePermissions(player.nameAndId());
this.simpleName = player.getName().getString(); this.namesProvider = NamesProvider.FOR_ENTITY;
this.name = player.getDisplayName();
this.server = player.level().getServer(); this.server = player.level().getServer();
this.entity = player; this.entity = player;
this.resultConsumer = (b, i) -> result[0] = i; this.resultConsumer = (b, i) -> result[0] = i;
@@ -91,15 +87,15 @@ public class SnoopyCommandSource extends CommandSourceStack
this.chatOutput = output; this.chatOutput = output;
this.signingContext = CommandSigningContext.ANONYMOUS; this.signingContext = CommandSigningContext.ANONYMOUS;
this.taskChainer = TaskChainer.immediate(player.level().getServer()); this.taskChainer = TaskChainer.immediate(player.level().getServer());
((CommandSourceStackInterface) this).setupPrivates(false, (b, i) -> result[0] = i, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(player.level().getServer())); Vanilla.CommandSourceStack_setupPrivates(this, false, (b, i) -> result[0] = i, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(player.level().getServer()));
} }
private SnoopyCommandSource(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, PermissionSet level, String simpleName, Component name, MinecraftServer server, @Nullable Entity entity, CommandResultCallback consumer, EntityAnchorArgument.Anchor entityAnchor, CommandSigningContext context, TaskChainer chainer, private SnoopyCommandSource(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, PermissionSet level, CommandSourceStack.NamesProvider namesProvider, MinecraftServer server, @Nullable Entity entity, CommandResultCallback consumer, EntityAnchorArgument.Anchor entityAnchor, CommandSigningContext context, TaskChainer chainer,
Component[] error, List<Component> chatOutput Component[] error, List<Component> chatOutput
) )
{ {
super(output, pos, rot, world, level, super(output, pos, rot, world, level,
simpleName, name, server, entity server, entity
// , false, consumer, entityAnchor, context, chainer // , false, consumer, entityAnchor, context, chainer
); );
this.output = output; this.output = output;
@@ -107,8 +103,7 @@ public class SnoopyCommandSource extends CommandSourceStack
this.rotation = rot; this.rotation = rot;
this.world = world; this.world = world;
this.level = level; this.level = level;
this.simpleName = simpleName; this.namesProvider = namesProvider;
this.name = name;
this.server = server; this.server = server;
this.entity = entity; this.entity = entity;
this.resultConsumer = consumer; this.resultConsumer = consumer;
@@ -117,31 +112,31 @@ public class SnoopyCommandSource extends CommandSourceStack
this.chatOutput = chatOutput; this.chatOutput = chatOutput;
this.signingContext = context; this.signingContext = context;
this.taskChainer = chainer; this.taskChainer = chainer;
((CommandSourceStackInterface) this).setupPrivates(false, consumer, entityAnchor, context, chainer); Vanilla.CommandSourceStack_setupPrivates(this, false, consumer, entityAnchor, context, chainer);
} }
@Override @Override
public CommandSourceStack withEntity(Entity entity) public CommandSourceStack withEntity(Entity entity)
{ {
return new SnoopyCommandSource(output, position, rotation, world, level, entity.getName().getString(), entity.getDisplayName(), server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput); return new SnoopyCommandSource(output, position, rotation, world, level, NamesProvider.FOR_ENTITY, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
} }
@Override @Override
public CommandSourceStack withPosition(Vec3 position) public CommandSourceStack withPosition(Vec3 position)
{ {
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput); return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
} }
@Override @Override
public CommandSourceStack withRotation(Vec2 rotation) public CommandSourceStack withRotation(Vec2 rotation)
{ {
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput); return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
} }
@Override @Override
public CommandSourceStack withCallback(CommandResultCallback consumer) public CommandSourceStack withCallback(CommandResultCallback consumer)
{ {
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, consumer, entityAnchor, signingContext, taskChainer, error, chatOutput); return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, consumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
} }
@Override @Override
@@ -170,13 +165,13 @@ public class SnoopyCommandSource extends CommandSourceStack
@Override @Override
public CommandSourceStack withAnchor(EntityAnchorArgument.Anchor anchor) public CommandSourceStack withAnchor(EntityAnchorArgument.Anchor anchor)
{ {
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, anchor, signingContext, taskChainer, error, chatOutput); return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, anchor, signingContext, taskChainer, error, chatOutput);
} }
@Override @Override
public CommandSourceStack withSigningContext(CommandSigningContext commandSigningContext, TaskChainer taskChainer) public CommandSourceStack withSigningContext(CommandSigningContext commandSigningContext, TaskChainer taskChainer)
{ {
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, commandSigningContext, taskChainer, error, chatOutput); return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, entityAnchor, commandSigningContext, taskChainer, error, chatOutput);
} }
@Override @Override
@@ -184,7 +179,7 @@ public class SnoopyCommandSource extends CommandSourceStack
{ {
double d = DimensionType.getTeleportationScale(this.world.dimensionType(), world.dimensionType()); double d = DimensionType.getTeleportationScale(this.world.dimensionType(), world.dimensionType());
Vec3 position = new Vec3(this.position.x * d, this.position.y, this.position.z * d); Vec3 position = new Vec3(this.position.x * d, this.position.y, this.position.z * d);
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput); return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
} }
@Override @Override
@@ -195,7 +190,7 @@ public class SnoopyCommandSource extends CommandSourceStack
double e = position.y - vec3d.y; double e = position.y - vec3d.y;
double f = position.z - vec3d.z; double f = position.z - vec3d.z;
double g = Math.sqrt(d * d + f * f); double g = Math.sqrt(d * d + f * f);
float h = Mth.wrapDegrees((float) (-(Mth.atan2(e, g) * 57.2957763671875D))); float h = Mth.wrapDegrees((float) -(Mth.atan2(e, g) * 57.2957763671875D));
float i = Mth.wrapDegrees((float) (Mth.atan2(f, d) * 57.2957763671875D) - 90.0F); float i = Mth.wrapDegrees((float) (Mth.atan2(f, d) * 57.2957763671875D) - 90.0F);
return this.withRotation(new Vec2(h, i)); return this.withRotation(new Vec2(h, i));
} }
@@ -35,6 +35,7 @@ import java.util.function.Function;
public class SystemInfo public class SystemInfo
{ {
@SuppressWarnings("DoubleBraceInitialization")
private static final Map<String, Function<CarpetContext, Value>> options = new HashMap<>() private static final Map<String, Function<CarpetContext, Value>> options = new HashMap<>()
{{ {{
put("app_name", c -> put("app_name", c ->
@@ -43,7 +44,7 @@ public class SystemInfo
return name == null ? Value.NULL : new StringValue(name); return name == null ? Value.NULL : new StringValue(name);
}); });
put("app_list", c -> ListValue.wrap(((CarpetScriptHost) c.host).scriptServer().modules.keySet().stream().filter(Objects::nonNull).map(StringValue::new))); put("app_list", c -> ListValue.wrap(((CarpetScriptHost) c.host).scriptServer().modules.keySet().stream().filter(Objects::nonNull).map(StringValue::new)));
put("app_scope", c -> StringValue.of((c.host).isPerUser() ? "player" : "global")); put("app_scope", c -> StringValue.of(c.host.isPerUser() ? "player" : "global"));
put("app_players", c -> ListValue.wrap(c.host.getUserList().stream().map(StringValue::new))); put("app_players", c -> ListValue.wrap(c.host.getUserList().stream().map(StringValue::new)));
put("world_name", c -> new StringValue(c.server().getWorldData().getLevelName())); put("world_name", c -> new StringValue(c.server().getWorldData().getLevelName()));
@@ -133,7 +134,7 @@ public class SystemInfo
long[] tickArray = c.server().getTickTimesNanos(); long[] tickArray = c.server().getTickTimesNanos();
for (int i = currentReportedTick + 100; i > currentReportedTick; i--) for (int i = currentReportedTick + 100; i > currentReportedTick; i--)
{ {
ticks.add(new NumericValue((tickArray[i % 100]) / 1000000.0)); ticks.add(new NumericValue(tickArray[i % 100] / 1000000.0));
} }
return ListValue.wrap(ticks); return ListValue.wrap(ticks);
}); });
@@ -14,8 +14,7 @@ public enum ShapeDirection
CAMERA, CAMERA,
PLAYER; PLAYER;
@Nullable public static @Nullable ShapeDirection fromString(String direction)
public static ShapeDirection fromString(String direction)
{ {
return switch (direction.toLowerCase(Locale.ROOT)) return switch (direction.toLowerCase(Locale.ROOT))
{ {
@@ -298,6 +298,7 @@ public class EntityValue extends Value
return ListValue.wrap(types.stream().map(et -> nameFromRegistryId(entityRegs.getKey(et)))); return ListValue.wrap(types.stream().map(et -> nameFromRegistryId(entityRegs.getKey(et))));
} }
@SuppressWarnings("DoubleBraceInitialization")
public static final Map<String, EntityClassDescriptor> byName = new HashMap<>() public static final Map<String, EntityClassDescriptor> byName = new HashMap<>()
{{ {{
List<EntityType<?>> allTypes = BuiltInRegistries.ENTITY_TYPE.stream().toList(); List<EntityType<?>> allTypes = BuiltInRegistries.ENTITY_TYPE.stream().toList();
@@ -409,7 +410,7 @@ public class EntityValue extends Value
public Value get(String what, @Nullable Value arg) public Value get(String what, @Nullable Value arg)
{ {
if (!(featureAccessors.containsKey(what))) if (!featureAccessors.containsKey(what))
{ {
throw new InternalExpressionException("Unknown entity feature: " + what); throw new InternalExpressionException("Unknown entity feature: " + what);
} }
@@ -432,6 +433,7 @@ public class EntityValue extends Value
"feet", EquipmentSlot.FEET "feet", EquipmentSlot.FEET
); );
@SuppressWarnings("DoubleBraceInitialization")
private static final Map<String, BiFunction<Entity, Value, Value>> featureAccessors = new HashMap<String, BiFunction<Entity, Value, Value>>() private static final Map<String, BiFunction<Entity, Value, Value>> featureAccessors = new HashMap<String, BiFunction<Entity, Value, Value>>()
{{ {{
//put("test", (e, a) -> a == null ? Value.NULL : new StringValue(a.getString())); //put("test", (e, a) -> a == null ? Value.NULL : new StringValue(a.getString()));
@@ -834,16 +836,11 @@ public class EntityValue extends Value
{ {
return ValueConversions.of(hitres.getLocation()); return ValueConversions.of(hitres.getLocation());
} }
switch (hitres.getType()) return switch (hitres.getType()) {
{ case MISS -> Value.NULL;
case MISS: case BLOCK -> new BlockValue((ServerLevel) e.level(), ((BlockHitResult) hitres).getBlockPos());
return Value.NULL; case ENTITY -> new EntityValue(((EntityHitResult) hitres).getEntity());
case BLOCK: };
return new BlockValue((ServerLevel) e.level(), ((BlockHitResult) hitres).getBlockPos());
case ENTITY:
return new EntityValue(((EntityHitResult) hitres).getEntity());
}
return Value.NULL;
}); });
put("attribute", (e, a) -> { put("attribute", (e, a) -> {
@@ -888,7 +885,7 @@ public class EntityValue extends Value
public void set(String what, @Nullable Value toWhat) public void set(String what, @Nullable Value toWhat)
{ {
if (!(featureModifiers.containsKey(what))) if (!featureModifiers.containsKey(what))
{ {
throw new InternalExpressionException("Unknown entity action: " + what); throw new InternalExpressionException("Unknown entity action: " + what);
} }
@@ -947,10 +944,11 @@ public class EntityValue extends Value
e.syncVelocity = true; e.syncVelocity = true;
if (Math.abs(scale) > 10000) if (Math.abs(scale) > 10000)
{ {
CarpetScriptServer.LOG.warn("Moved entity " + e.getScoreboardName() + " " + e.getName() + " at " + e.position() + " extremely fast: " + e.getDeltaMovement()); CarpetScriptServer.LOG.warn("Moved entity {} {} at {} extremely fast: {}", e.getScoreboardName(), e.getName(), e.position(), e.getDeltaMovement());
} }
} }
@SuppressWarnings("DoubleBraceInitialization")
private static final Map<String, BiConsumer<Entity, Value>> featureModifiers = new HashMap<String, BiConsumer<Entity, Value>>() private static final Map<String, BiConsumer<Entity, Value>> featureModifiers = new HashMap<String, BiConsumer<Entity, Value>>()
{{ {{
put("remove", (entity, value) -> entity.discard()); // using discard here - will see other options if valid put("remove", (entity, value) -> entity.discard()); // using discard here - will see other options if valid
@@ -1547,8 +1545,8 @@ public class EntityValue extends Value
{ {
return; return;
} }
GameType toSet = v instanceof NumericValue ? GameType toSet = v instanceof final NumericValue numericValue ?
GameType.byId(((NumericValue) v).getInt()) : GameType.byId(numericValue.getInt()) :
GameType.byName(v.getString().toLowerCase(Locale.ROOT), null); GameType.byName(v.getString().toLowerCase(Locale.ROOT), null);
if (toSet != null) if (toSet != null)
{ {
@@ -434,9 +434,9 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
{ {
if (ind.isNull()) if (ind.isNull())
{ {
if (extend && value instanceof AbstractListValue) if (extend && value instanceof final AbstractListValue abstractListValue)
{ {
((AbstractListValue) value).iterator().forEachRemaining(items::add); abstractListValue.iterator().forEachRemaining(items::add);
} }
else else
{ {
@@ -446,11 +446,11 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
else else
{ {
int numitems = items.size(); int numitems = items.size();
if (!(ind instanceof NumericValue)) if (!(ind instanceof final NumericValue numericValue))
{ {
return false; return false;
} }
int index = (int) ((NumericValue) ind).getLong(); int index = (int) numericValue.getLong();
if (index < 0) if (index < 0)
{// only for values < 0 {// only for values < 0
index = normalizeIndex(index, numitems); index = normalizeIndex(index, numitems);
@@ -469,9 +469,9 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
items.add(Value.NULL); items.add(Value.NULL);
} }
if (extend && value instanceof AbstractListValue) if (extend && value instanceof final AbstractListValue abstractListValue)
{ {
Iterable<Value> iterable = ((AbstractListValue) value)::iterator; Iterable<Value> iterable = abstractListValue::iterator;
List<Value> appendix = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList()); List<Value> appendix = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
items.addAll(index, appendix); items.addAll(index, appendix);
return true; return true;
@@ -498,11 +498,11 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
@Override @Override
public boolean delete(Value where) public boolean delete(Value where)
{ {
if (!(where instanceof NumericValue) || items.isEmpty()) if (!(where instanceof final NumericValue numericValue) || items.isEmpty())
{ {
return false; return false;
} }
long index = ((NumericValue) where).getLong(); long index = numericValue.getLong();
items.remove(normalizeIndex(index, items.size())); items.remove(normalizeIndex(index, items.size()));
return true; return true;
} }
@@ -592,8 +592,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
} }
// only numbers / mixed types // only numbers / mixed types
tags.forEach(cases.contains(TagTypeCompat.DBL) tags.forEach(cases.contains(TagTypeCompat.DBL)
? (t -> tag.add(DoubleTag.valueOf(((NumericTag) t).doubleValue()))) ? t -> tag.add(DoubleTag.valueOf(((NumericTag) t).doubleValue()))
: (t -> tag.add(LongTag.valueOf(((NumericTag) t).longValue())))); : t -> tag.add(LongTag.valueOf(((NumericTag) t).longValue())));
return tag; return tag;
} }
@@ -118,14 +118,12 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
return StringValue.of(nameFromResource(id)); return StringValue.of(nameFromResource(id));
} }
@Nullable public static @Nullable String nameFromResource(@Nullable Identifier id)
public static String nameFromResource(@Nullable Identifier id)
{ {
return id == null ? null : id.getNamespace().equals("minecraft") ? id.getPath() : id.toString(); return id == null ? null : id.getNamespace().equals("minecraft") ? id.getPath() : id.toString();
} }
@Nullable public static @Nullable NBTSerializableValue parseString(String nbtString)
public static NBTSerializableValue parseString(String nbtString)
{ {
try try
{ {
@@ -356,7 +354,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
{ {
return res.createItemStack(1); return res.createItemStack(1);
} }
ItemInput parser = (new ItemParser(regs)).parse(new StringReader(itemString)); ItemInput parser = new ItemParser(regs).parse(new StringReader(itemString));
res = new ItemInput(parser.item(), parser.components()); res = new ItemInput(parser.item(), parser.components());
itemCache.put(itemString, res); itemCache.put(itemString, res);
@@ -477,11 +475,11 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
Tag tag = getTag(); Tag tag = getTag();
if (tag instanceof final CompoundTag ctag) if (tag instanceof final CompoundTag ctag)
{ {
return !(ctag).isEmpty(); return !ctag.isEmpty();
} }
if (tag instanceof final CollectionTag ltag) if (tag instanceof final CollectionTag ltag)
{ {
return !(ltag).isEmpty(); return !ltag.isEmpty();
} }
if (tag instanceof final NumericTag number) if (tag instanceof final NumericTag number)
{ {
@@ -88,13 +88,13 @@ public class ScreenValue extends Value
screenHandlerFactories.put("crafting", CraftingMenu::new); screenHandlerFactories.put("crafting", CraftingMenu::new);
screenHandlerFactories.put("enchantment", EnchantmentMenu::new); screenHandlerFactories.put("enchantment", EnchantmentMenu::new);
screenHandlerFactories.put("furnace", FurnaceMenu::new); screenHandlerFactories.put("furnace", FurnaceMenu::new);
screenHandlerFactories.put("generic_3x3", ((syncId, playerInventory) -> new ChestMenu(GENERIC_3x3, syncId, playerInventory, new SimpleContainer(9), 1))); screenHandlerFactories.put("generic_3x3", (syncId, playerInventory) -> new ChestMenu(GENERIC_3x3, syncId, playerInventory, new SimpleContainer(9), 1));
screenHandlerFactories.put("generic_9x1", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x1, syncId, playerInventory, new SimpleContainer(9), 1))); screenHandlerFactories.put("generic_9x1", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x1, syncId, playerInventory, new SimpleContainer(9), 1));
screenHandlerFactories.put("generic_9x2", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x2, syncId, playerInventory, new SimpleContainer(9 * 2), 2))); screenHandlerFactories.put("generic_9x2", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x2, syncId, playerInventory, new SimpleContainer(9 * 2), 2));
screenHandlerFactories.put("generic_9x3", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x3, syncId, playerInventory, new SimpleContainer(9 * 3), 3))); screenHandlerFactories.put("generic_9x3", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x3, syncId, playerInventory, new SimpleContainer(9 * 3), 3));
screenHandlerFactories.put("generic_9x4", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x4, syncId, playerInventory, new SimpleContainer(9 * 4), 4))); screenHandlerFactories.put("generic_9x4", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x4, syncId, playerInventory, new SimpleContainer(9 * 4), 4));
screenHandlerFactories.put("generic_9x5", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x5, syncId, playerInventory, new SimpleContainer(9 * 5), 5))); screenHandlerFactories.put("generic_9x5", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x5, syncId, playerInventory, new SimpleContainer(9 * 5), 5));
screenHandlerFactories.put("generic_9x6", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x6, syncId, playerInventory, new SimpleContainer(9 * 6), 6))); screenHandlerFactories.put("generic_9x6", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x6, syncId, playerInventory, new SimpleContainer(9 * 6), 6));
screenHandlerFactories.put("grindstone", GrindstoneMenu::new); screenHandlerFactories.put("grindstone", GrindstoneMenu::new);
screenHandlerFactories.put("hopper", HopperMenu::new); screenHandlerFactories.put("hopper", HopperMenu::new);
screenHandlerFactories.put("lectern", (syncId, playerInventory) -> new LecternMenu(syncId, new SimpleContainer(1), new SimpleContainerData(1))); screenHandlerFactories.put("lectern", (syncId, playerInventory) -> new LecternMenu(syncId, new SimpleContainer(1), new SimpleContainerData(1)));
@@ -25,6 +25,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ColumnPos; import net.minecraft.server.level.ColumnPos;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.util.ARGB;
import net.minecraft.util.StringRepresentable; import net.minecraft.util.StringRepresentable;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@@ -60,6 +61,7 @@ import java.util.UUID;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import org.joml.Vector3fc;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
public class ValueConversions public class ValueConversions
@@ -140,11 +142,16 @@ public class ValueConversions
return new NumericValue(value * 256 + 255); return new NumericValue(value * 256 + 255);
} }
public static Value ofRGB(Vector3fc value)
{
return new NumericValue(ARGB.colorFromVector3f(value));
}
public static Level dimFromValue(Value dimensionValue, MinecraftServer server) public static Level dimFromValue(Value dimensionValue, MinecraftServer server)
{ {
if (dimensionValue instanceof EntityValue) if (dimensionValue instanceof final EntityValue entityValue)
{ {
return ((EntityValue) dimensionValue).getEntity().level(); return entityValue.getEntity().level();
} }
else if (dimensionValue instanceof BlockValue bv) else if (dimensionValue instanceof BlockValue bv)
{ {
@@ -168,7 +175,7 @@ public class ValueConversions
ResourceKey<Level> dim = null; ResourceKey<Level> dim = null;
Identifier id = Identifier.parse(dimString); Identifier id = Identifier.parse(dimString);
// not using RegistryKey.of since that one creates on check // not using RegistryKey.of since that one creates on check
for (ResourceKey<Level> world : (server.levelKeys())) for (ResourceKey<Level> world : server.levelKeys())
{ {
if (id.equals(world.identifier())) if (id.equals(world.identifier()))
{ {
@@ -412,6 +419,7 @@ public class ValueConversions
} }
} }
@SuppressWarnings("DoubleBraceInitialization")
private static final Int2ObjectMap<SlotParam> slotIdsToSlotParams = new Int2ObjectOpenHashMap<>() private static final Int2ObjectMap<SlotParam> slotIdsToSlotParams = new Int2ObjectOpenHashMap<>()
{{ {{
int n; int n;
+5 -5
View File
@@ -257,10 +257,10 @@ public class Messenger
MutableComponent previousComponent = null; MutableComponent previousComponent = null;
for (Object o: fields) for (Object o: fields)
{ {
if (o instanceof MutableComponent) if (o instanceof final MutableComponent mutableComponent)
{ {
message.append((MutableComponent)o); message.append(mutableComponent);
previousComponent = (MutableComponent)o; previousComponent = mutableComponent;
continue; continue;
} }
String txt = o.toString(); String txt = o.toString();
@@ -300,7 +300,7 @@ public class Messenger
public static void print_server_message(MinecraftServer server, String message) public static void print_server_message(MinecraftServer server, String message)
{ {
if (server == null) if (server == null)
LOG.error("Message not delivered: "+message); LOG.error("Message not delivered: {}", message);
server.sendSystemMessage(Component.literal(message)); server.sendSystemMessage(Component.literal(message));
Component txt = c("gi "+message); Component txt = c("gi "+message);
for (ServerPlayer entityplayer : server.getPlayerList().getPlayers()) for (ServerPlayer entityplayer : server.getPlayerList().getPlayers())
@@ -311,7 +311,7 @@ public class Messenger
public static void print_server_message(MinecraftServer server, Component message) public static void print_server_message(MinecraftServer server, Component message)
{ {
if (server == null) if (server == null)
LOG.error("Message not delivered: "+message.getString()); LOG.error("Message not delivered: {}", message.getString());
server.sendSystemMessage(message); server.sendSystemMessage(message);
for (ServerPlayer entityplayer : server.getPlayerList().getPlayers()) for (ServerPlayer entityplayer : server.getPlayerList().getPlayers())
{ {
+1
View File
@@ -14,3 +14,4 @@ accessible method net/minecraft/world/level/border/WorldBorder getListeners ()Lj
accessible method net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator calculateTargetStrength (Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)I accessible method net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator calculateTargetStrength (Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)I
accessible field net/minecraft/world/level/block/state/BlockBehaviour UPDATE_SHAPE_ORDER [Lnet/minecraft/core/Direction; accessible field net/minecraft/world/level/block/state/BlockBehaviour UPDATE_SHAPE_ORDER [Lnet/minecraft/core/Direction;
accessible field net/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher blockModelResolver Lnet/minecraft/client/renderer/block/BlockModelResolver; accessible field net/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher blockModelResolver Lnet/minecraft/client/renderer/block/BlockModelResolver;
accessible field net/minecraft/commands/CommandSourceStack namesProvider Lnet/minecraft/commands/CommandSourceStack$NamesProvider;
-1
View File
@@ -153,7 +153,6 @@
"BlockPredicate_scarpetMixin", "BlockPredicate_scarpetMixin",
"TagPredicate_scarpetMixin", "TagPredicate_scarpetMixin",
"HorseBaseEntity_scarpetMixin", "HorseBaseEntity_scarpetMixin",
"RandomState_ScarpetMixin",
"Biome_scarpetMixin", "Biome_scarpetMixin",
"PortalProcessor_scarpetMixin", "PortalProcessor_scarpetMixin",
+2 -2
View File
@@ -33,8 +33,8 @@
"accessWidener" : "carpet.accesswidener", "accessWidener" : "carpet.accesswidener",
"depends": { "depends": {
"minecraft": ">26.2", "minecraft": ">=26.3",
"fabricloader": ">=0.19.3", "fabricloader": ">=0.19.5",
"java": ">=25" "java": ">=25"
} }
} }