cleanup of scarpet dependencies

This commit is contained in:
gnembon committed 2023-02-08 21:13:14 +01:00
1 parent fd93785fec
commit 75d94b0570
71 files changed
+1623 -1014

No files matched your search

+13 -4
View File
@@ -14,19 +14,19 @@ import carpet.commands.MobAICommand;
import carpet.commands.PerimeterInfoCommand;
import carpet.commands.PlayerCommand;
import carpet.commands.ProfileCommand;
import carpet.commands.ScriptCommand;
import carpet.script.ScriptCommand;
import carpet.commands.SpawnCommand;
import carpet.commands.TestCommand;
import carpet.commands.TickCommand;
import carpet.network.ServerNetworkHandler;
import carpet.helpers.HopperCounter;
import carpet.helpers.ParticleDisplay;
import carpet.helpers.TickSpeed;
import carpet.logging.LoggerRegistry;
import carpet.script.CarpetScriptServer;
import carpet.api.settings.SettingsManager;
import carpet.logging.HUDController;
import carpet.utils.FabricAPIHooks;
import carpet.script.external.Carpet;
import carpet.script.utils.ParticleParser;
import carpet.utils.MobAI;
import carpet.utils.SpawnReporter;
import com.mojang.brigadier.CommandDispatcher;
@@ -90,6 +90,7 @@ public class CarpetServer // static for now - easier to handle all around the co
e.onServerLoaded(server);
});
scriptServer = new CarpetScriptServer(server);
Carpet.MinecraftServer_addScriptServer(server, scriptServer);
MobAI.resetTrackers();
LoggerRegistry.initLoggers();
//TickSpeed.reset();
@@ -99,6 +100,14 @@ public class CarpetServer // static for now - easier to handle all around the co
{
HopperCounter.resetAll(minecraftServer, true);
extensions.forEach(e -> e.onServerLoadedWorlds(minecraftServer));
// initialize scarpet rules after all extensions are loaded
settingsManager.initializeScarpetRules();
extensions.forEach(e -> {
if (e.extensionSettingsManager() != null)
{
e.extensionSettingsManager().initializeScarpetRules();
}
});
scriptServer.initializeForWorld();
}
@@ -185,7 +194,7 @@ public class CarpetServer // static for now - easier to handle all around the co
LoggerRegistry.stopLoggers();
HUDController.resetScarpetHUDs();
ParticleDisplay.resetCache();
ParticleParser.resetCache();
extensions.forEach(e -> e.onServerClosed(server));
minecraft_server = null;
}
+2 -2
View File
@@ -4,7 +4,7 @@ import carpet.api.settings.CarpetRule;
import carpet.api.settings.RuleCategory;
import carpet.api.settings.Validators;
import carpet.api.settings.Validator;
import carpet.script.utils.AppStoreManager;
import carpet.script.external.Carpet;
import carpet.settings.Rule;
import carpet.utils.Translations;
import carpet.utils.CommandHelper;
@@ -562,7 +562,7 @@ public class CarpetSettings
},
category = SCARPET,
strict = false,
validate= AppStoreManager.ScarpetAppStoreValidator.class
validate= Carpet.ScarpetAppStoreValidator.class
)
public static String scriptsAppStore = "gnembon/scarpet/contents/programs";
@@ -25,6 +25,8 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import carpet.script.CarpetEventServer;
import carpet.script.value.StringValue;
import com.google.common.collect.Sets;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
@@ -54,7 +56,6 @@ import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.storage.LevelResource;
import static carpet.script.CarpetEventServer.Event.CARPET_RULE_CHANGES;
import static carpet.utils.Translations.tr;
import static java.util.Comparator.comparing;
import static net.minecraft.commands.Commands.argument;
@@ -258,13 +259,39 @@ public class SettingsManager {
rules.put(rule.name(), rule);
}
public static final CarpetEventServer.Event CARPET_RULE_CHANGES = new CarpetEventServer.Event("carpet_rule_changes", 2, true)
{
@Override
public void handleAny(final Object ... args)
{
final CarpetRule<?> rule = (CarpetRule<?>) args[0];
final CommandSourceStack source = (CommandSourceStack) args[1];
final String id = rule.settingsManager().identifier();
final String namespace;
if (!id.equals("carpet"))
{
namespace = id + ":";
}
else
{
namespace = "";
}
handler.call(
() -> Arrays.asList(
new StringValue(namespace + rule.name()),
new StringValue(RuleHelper.toRuleString(rule.value()))
), () -> source
);
}
};
public void notifyRuleChanged(CommandSourceStack source, CarpetRule<?> rule, String userInput)
{
observers.forEach(observer -> observer.ruleChanged(source, rule, userInput));
staticObservers.forEach(observer -> observer.ruleChanged(source, rule, userInput));
ServerNetworkHandler.updateRuleWithConnectedClients(rule);
switchScarpetRuleIfNeeded(source, rule); //TODO move into rule
if (CARPET_RULE_CHANGES.isNeeded()) CARPET_RULE_CHANGES.onCarpetRuleChanges(rule, source);
if (CARPET_RULE_CHANGES.isNeeded()) CARPET_RULE_CHANGES.handleAny(rule, source);
}
/**
@@ -27,7 +27,7 @@ public class MobAICommand
suggests( (c, b) -> suggest(MobAI.availbleTypes(c.getSource()), b)).
then(literal("clear").executes( (c) ->
{
MobAI.clearTracking(getSummonableEntityType(c, "entity type").value());
MobAI.clearTracking(c.getSource().getServer(), getSummonableEntityType(c, "entity type").value());
return 1;
}
)).
@@ -2,7 +2,7 @@ package carpet.commands;
import carpet.helpers.EntityPlayerActionPack;
import carpet.CarpetSettings;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInterface;
import carpet.patches.EntityPlayerMPFake;
import carpet.utils.CommandHelper;
import carpet.utils.Messenger;
@@ -14,7 +14,6 @@ import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.util.UUIDTypeAdapter;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.DimensionArgument;
@@ -336,7 +335,7 @@ public class PlayerCommand
{
if (cantManipulate(context)) return 0;
ServerPlayer player = getPlayer(context);
((ServerPlayerEntityInterface) player).getActionPack().stopAll();
((ServerPlayerInterface) player).getActionPack().stopAll();
return 1;
}
@@ -344,7 +343,7 @@ public class PlayerCommand
{
if (cantManipulate(context)) return 0;
ServerPlayer player = getPlayer(context);
action.accept(((ServerPlayerEntityInterface) player).getActionPack());
action.accept(((ServerPlayerInterface) player).getActionPack());
return 1;
}
@@ -5,8 +5,9 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.DataSlot;
import net.minecraft.world.item.crafting.Recipe;
public interface ScreenHandlerInterface {
DataSlot getProperty(int index);
public interface AbstractContainerMenuInterface
{
DataSlot getDataSlot(int index);
boolean callButtonClickListener(int button, Player player);
boolean callSelectRecipeListener(ServerPlayer player, Recipe<?> recipe, boolean craftAll);
}
@@ -1,13 +0,0 @@
package carpet.fakes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement;
import java.util.List;
public interface ChunkGeneratorInterface
{
void initStrongholds(final ServerLevel level);
List<StructurePlacement> getPlacementsForFeatureCM(final ServerLevel level, final Structure structure);
}
@@ -3,6 +3,7 @@ package carpet.fakes;
import java.util.Map;
import java.util.function.BooleanSupplier;
import carpet.script.CarpetScriptServer;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceKey;
//import net.minecraft.server.ServerResources;
@@ -19,4 +20,7 @@ public interface MinecraftServerInterface
void reloadAfterReload(RegistryAccess newRegs);
MinecraftServer.ReloadableResources getResourceManager();
void addScriptServer(CarpetScriptServer scriptServer);
CarpetScriptServer getScriptServer();
}
@@ -2,7 +2,7 @@ package carpet.fakes;
import carpet.helpers.EntityPlayerActionPack;
public interface ServerPlayerEntityInterface
public interface ServerPlayerInterface
{
EntityPlayerActionPack getActionPack();
void invalidateEntityObjectReference();
@@ -1,10 +1,12 @@
package carpet.helpers;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInterface;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import carpet.script.utils.Tracer;
import net.minecraft.commands.arguments.EntityAnchorArgument;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -289,7 +291,7 @@ public class EntityPlayerActionPack
@Override
boolean execute(ServerPlayer player, Action action)
{
EntityPlayerActionPack ap = ((ServerPlayerEntityInterface) player).getActionPack();
EntityPlayerActionPack ap = ((ServerPlayerInterface) player).getActionPack();
if (ap.itemUseCooldown > 0)
{
ap.itemUseCooldown--;
@@ -358,7 +360,7 @@ public class EntityPlayerActionPack
@Override
void inactiveTick(ServerPlayer player, Action action)
{
EntityPlayerActionPack ap = ((ServerPlayerEntityInterface) player).getActionPack();
EntityPlayerActionPack ap = ((ServerPlayerInterface) player).getActionPack();
ap.itemUseCooldown = 0;
player.releaseUsingItem();
}
@@ -380,7 +382,7 @@ public class EntityPlayerActionPack
return true;
}
case BLOCK: {
EntityPlayerActionPack ap = ((ServerPlayerEntityInterface) player).getActionPack();
EntityPlayerActionPack ap = ((ServerPlayerInterface) player).getActionPack();
if (ap.blockHitDelay > 0)
{
ap.blockHitDelay--;
@@ -451,7 +453,7 @@ public class EntityPlayerActionPack
@Override
void inactiveTick(ServerPlayer player, Action action)
{
EntityPlayerActionPack ap = ((ServerPlayerEntityInterface) player).getActionPack();
EntityPlayerActionPack ap = ((ServerPlayerInterface) player).getActionPack();
if (ap.currentBlock == null) return;
player.level.destroyBlockProgress(-1, ap.currentBlock, -1);
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.getLevel().getMaxBuildHeight(), -1);
@@ -1,10 +1,6 @@
package carpet.helpers;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.commands.arguments.ParticleArgument;
import carpet.script.utils.ParticleParser;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
@@ -14,34 +10,11 @@ import net.minecraft.world.phys.Vec3;
public class ParticleDisplay
{
private static final Map<String, ParticleOptions> particleCache = new HashMap<>(); // we reset this on reloads, but probably need something better
private static ParticleOptions parseParticle(String name, HolderLookup<ParticleType<?>> lookup)
{
try
{
return ParticleArgument.readParticle(new StringReader(name), lookup);
}
catch (CommandSyntaxException e)
{
throw new IllegalArgumentException("No such particle: " + name);
}
}
public static ParticleOptions getEffect(String name, HolderLookup<ParticleType<?>> lookup)
{
if (name == null) return null;
return particleCache.computeIfAbsent(name, particle -> parseParticle(particle, lookup));
}
public static void resetCache() {
particleCache.clear();
}
public static void drawParticleLine(ServerPlayer player, Vec3 from, Vec3 to, String main, String accent, int count, double spread)
{
HolderLookup<ParticleType<?>> lookup = player.getLevel().holderLookup(Registries.PARTICLE_TYPE);
ParticleOptions accentParticle = getEffect(accent, lookup);
ParticleOptions mainParticle = getEffect(main, lookup);
ParticleOptions accentParticle = ParticleParser.getEffect(accent, lookup);
ParticleOptions mainParticle = ParticleParser.getEffect(main, lookup);
if (accentParticle != null) player.getLevel().sendParticles(
player,
@@ -1,6 +1,6 @@
package carpet.mixins;
import carpet.fakes.ScreenHandlerInterface;
import carpet.fakes.AbstractContainerMenuInterface;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.EnchantmentMenu;
@@ -23,7 +23,7 @@ public abstract class AbstractContainerMenuSubclasses_scarpetMixin extends Abstr
@Inject(method = "clickMenuButton", at = @At("HEAD"), cancellable = true)
private void buttonClickCallback(Player player, int id, CallbackInfoReturnable<Boolean> cir) {
if(((ScreenHandlerInterface) this).callButtonClickListener(id,player))
if(((AbstractContainerMenuInterface) this).callButtonClickListener(id,player))
cir.cancel();
}
}
@@ -1,7 +1,6 @@
package carpet.mixins;
import carpet.fakes.ScreenHandlerInterface;
import carpet.fakes.AbstractContainerMenuInterface;
import carpet.script.value.ScreenValue;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -20,7 +19,7 @@ import net.minecraft.world.inventory.DataSlot;
import net.minecraft.world.item.crafting.Recipe;
@Mixin(AbstractContainerMenu.class)
public abstract class AbstractContainerMenu_scarpetMixin implements ScreenHandlerInterface
public abstract class AbstractContainerMenu_scarpetMixin implements AbstractContainerMenuInterface
{
@Shadow @Final private List<ContainerListener> containerListeners;
@Shadow public abstract void sendAllDataToRemote();
@@ -73,7 +72,7 @@ public abstract class AbstractContainerMenu_scarpetMixin implements ScreenHandle
}
@Override
public DataSlot getProperty(int index) {
public DataSlot getDataSlot(int index) {
return this.dataSlots.get(index);
}
}
@@ -1,26 +0,0 @@
package carpet.mixins;
import carpet.fakes.ChunkGeneratorInterface;
import net.minecraft.core.Holder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement;
import org.spongepowered.asm.mixin.Mixin;
import java.util.List;
@Mixin(ChunkGenerator.class)
public abstract class ChunkGenerator_scarpetMixin implements ChunkGeneratorInterface
{
@Override
public void initStrongholds(final ServerLevel level)
{
level.getChunkSource().getGeneratorState().ensureStructuresGenerated();
}
@Override
public List<StructurePlacement> getPlacementsForFeatureCM(final ServerLevel level, Structure structure) {
return level.getChunkSource().getGeneratorState().getPlacementsForStructure(Holder.direct(structure));
}
}
@@ -25,6 +25,7 @@ public abstract class EntityMixin implements EntityInterface
@Shadow public Level level;
@Override
public float getMainYaw(float partialTicks)
{
return partialTicks == 1.0F ? this.yRot : Mth.lerp(partialTicks, this.yRotO, this.yRot);
@@ -8,7 +8,6 @@ import org.spongepowered.asm.mixin.Shadow;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
@@ -20,7 +19,6 @@ public class Ingredient_scarpetMixin implements IngredientInterface
@Override
public List<Collection<ItemStack>> getRecipeStacks()
{
List<Collection<ItemStack>> res = Arrays.stream(values).map(Ingredient.Value::getItems).collect(Collectors.toList());
return res;
return Arrays.stream(values).map(Ingredient.Value::getItems).toList();
}
}
@@ -2,6 +2,7 @@ package carpet.mixins;
import carpet.fakes.MinecraftServerInterface;
import carpet.helpers.TickSpeed;
import carpet.script.CarpetScriptServer;
import net.minecraft.Util;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceKey;
@@ -31,6 +32,8 @@ import static carpet.script.CarpetEventServer.Event.TICK;
@Mixin(MinecraftServer.class)
public abstract class MinecraftServer_scarpetMixin extends ReentrantBlockableEventLoop<TickTask> implements MinecraftServerInterface
{
private CarpetScriptServer scriptServer;
public MinecraftServer_scarpetMixin(String string_1)
{
super(string_1);
@@ -74,11 +77,6 @@ public abstract class MinecraftServer_scarpetMixin extends ReentrantBlockableEve
return storageSource;
}
//@Override
//public ServerResources getResourceManager() {
// return resources;
//}
@Override
public Map<ResourceKey<Level>, ServerLevel> getCMWorlds()
{
@@ -93,9 +91,9 @@ public abstract class MinecraftServer_scarpetMixin extends ReentrantBlockableEve
{
if (!TickSpeed.process_entities)
return;
TICK.onTick();
NETHER_TICK.onTick();
ENDER_TICK.onTick();
TICK.onTick((MinecraftServer) (Object) this);
NETHER_TICK.onTick((MinecraftServer) (Object) this);
ENDER_TICK.onTick((MinecraftServer) (Object) this);
}
@Override
@@ -113,4 +111,16 @@ public abstract class MinecraftServer_scarpetMixin extends ReentrantBlockableEve
{
return resources;
}
@Override
public void addScriptServer(final CarpetScriptServer scriptServer)
{
this.scriptServer = scriptServer;
}
@Override
public CarpetScriptServer getScriptServer()
{
return scriptServer;
}
}
@@ -1,7 +1,7 @@
package carpet.mixins;
import carpet.CarpetServer;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInterface;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.PlayerList;
import org.spongepowered.asm.mixin.Mixin;
@@ -27,7 +27,7 @@ public class PlayerList_scarpetEventsMixin
))
private void invalidatePreviousInstance(ServerPlayer player, boolean alive, CallbackInfoReturnable<ServerPlayer> cir)
{
((ServerPlayerEntityInterface)player).invalidateEntityObjectReference();
((ServerPlayerInterface)player).invalidateEntityObjectReference();
}
@Inject(method = "reloadResources", at = @At("HEAD"))
@@ -1,6 +1,6 @@
package carpet.mixins;
import carpet.fakes.ScreenHandlerInterface;
import carpet.fakes.AbstractContainerMenuInterface;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.RecipeBookMenu;
import net.minecraft.world.item.crafting.Recipe;
@@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public class RecipeBookMenu_scarpetMixin {
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
private void selectRecipeCallback(boolean craftAll, Recipe<?> recipe, ServerPlayer player, CallbackInfo ci) {
if(((ScreenHandlerInterface) this).callSelectRecipeListener(player,recipe,craftAll))
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener(player,recipe,craftAll))
ci.cancel();
}
}
@@ -92,6 +92,7 @@ public abstract class ServerLevel_scarpetMixin extends Level implements ServerWo
private ServerLevelData serverLevelData;
@Shadow @Final private PersistentEntitySectionManager<Entity> entityManager;
@Override
public ServerLevelData getWorldPropertiesCM(){
return serverLevelData;
}
@@ -1,9 +1,8 @@
package carpet.mixins;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInterface;
import carpet.helpers.EntityPlayerActionPack;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.chat.RemoteChatSession;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@@ -14,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerPlayer.class)
public abstract class ServerPlayer_actionPackMixin implements ServerPlayerEntityInterface
public abstract class ServerPlayer_actionPackMixin implements ServerPlayerInterface
{
@Unique
public EntityPlayerActionPack actionPack;
@@ -1,7 +1,7 @@
package carpet.mixins;
import carpet.fakes.EntityInterface;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInterface;
import carpet.script.EntityEventsGroup;
import com.mojang.authlib.GameProfile;
import net.minecraft.core.BlockPos;
@@ -31,7 +31,7 @@ import static carpet.script.CarpetEventServer.Event.PLAYER_FINISHED_USING_ITEM;
import static carpet.script.CarpetEventServer.Event.STATISTICS;
@Mixin(ServerPlayer.class)
public abstract class ServerPlayer_scarpetEventMixin extends Player implements ServerPlayerEntityInterface
public abstract class ServerPlayer_scarpetEventMixin extends Player implements ServerPlayerInterface
{
// to denote if the player reference is valid
@@ -23,7 +23,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.SkullBlockEntity;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInterface;
import carpet.utils.Messenger;
import java.util.concurrent.atomic.AtomicReference;
@@ -90,7 +90,7 @@ public class EntityPlayerMPFake extends ServerPlayer
playerShadow.setHealth(player.getHealth());
playerShadow.connection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
playerShadow.gameMode.changeGameModeForPlayer(player.gameMode.getGameModeForPlayer());
((ServerPlayerEntityInterface) playerShadow).getActionPack().copyFrom(((ServerPlayerEntityInterface) player).getActionPack());
((ServerPlayerInterface) playerShadow).getActionPack().copyFrom(((ServerPlayerInterface) player).getActionPack());
playerShadow.maxUpStep = 0.6F;
playerShadow.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, player.getEntityData().get(DATA_PLAYER_MODE_CUSTOMISATION));
+111 -134
View File
@@ -1,13 +1,10 @@
package carpet.script;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.api.settings.CarpetRule;
import carpet.api.settings.RuleHelper;
import carpet.helpers.TickSpeed;
import carpet.script.exception.IntegrityException;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.InvalidCallbackException;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.utils.GlocalFlag;
import carpet.script.value.BlockValue;
import carpet.script.value.BooleanValue;
@@ -19,8 +16,6 @@ import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.utils.CarpetProfiler;
import carpet.utils.Messenger;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.ArrayList;
@@ -51,6 +46,7 @@ import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stat;
@@ -93,13 +89,15 @@ public class CarpetEventServer
public final String optionalTarget;
public final FunctionValue function;
public final List<Value> parametrizedArgs;
public final CarpetScriptServer scriptServer;
public Callback(final String host, final String target, final FunctionValue function, final List<Value> parametrizedArgs)
public Callback(final String host, final String target, final FunctionValue function, final List<Value> parametrizedArgs, final CarpetScriptServer scriptServer)
{
this.host = host;
this.function = function;
this.optionalTarget = target;
this.parametrizedArgs = parametrizedArgs == null ? NOARGS : parametrizedArgs;
this.scriptServer = scriptServer;
}
/**
@@ -115,12 +113,12 @@ public class CarpetEventServer
runtimeArgs = new ArrayList<>(runtimeArgs);
runtimeArgs.addAll(this.parametrizedArgs);
}
if (CarpetServer.scriptServer == null)
if (scriptServer.stopAll)
{
return CallbackResult.FAIL; // already stopped
}
return CarpetServer.scriptServer.events.runEventCall(
sender.withPermission(CarpetSettings.runPermissionLevel),
return scriptServer.events.runEventCall(
sender.withPermission(Vanilla.MinecraftServer_getRunPermissionLevel(sender.getServer())),
host, optionalTarget, function, runtimeArgs);
}
@@ -169,7 +167,7 @@ public class CarpetEventServer
public ScheduledCall(final CarpetContext context, final FunctionValue function, final List<Value> args, final long dueTime)
{
// ignoring target as we will be always calling self
super(context.host.getName(), null, function, args);
super(context.host.getName(), null, function, args, (CarpetScriptServer) context.scriptServer());
this.ctx = context.duplicate();
this.dueTime = dueTime;
}
@@ -179,7 +177,7 @@ public class CarpetEventServer
*/
public void execute()
{
CarpetServer.scriptServer.events.runScheduledCall(ctx.origin(), ctx.source(), host, (CarpetScriptHost) ctx.host, function, parametrizedArgs);
scriptServer.events.runScheduledCall(ctx.origin(), ctx.source(), host, (CarpetScriptHost) ctx.host, function, parametrizedArgs);
}
}
@@ -237,64 +235,69 @@ public class CarpetEventServer
*/
public boolean call(final Supplier<List<Value>> argumentSupplier, final Supplier<CommandSourceStack> cmdSourceSupplier)
{
if (!callList.isEmpty() && CarpetServer.scriptServer != null)
if (callList.isEmpty())
{
final Boolean isCancelled = CarpetServer.scriptServer.events.handleEvents.runIfEnabled(() -> {
final CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet events", CarpetProfiler.TYPE.GENERAL);
final List<Value> argv = argumentSupplier.get(); // empty for onTickDone
final CommandSourceStack source;
try
return false;
}
final CommandSourceStack source;
try
{
source = cmdSourceSupplier.get();
}
catch (final NullPointerException noReference) // todo figure out what happens when closing.
{
return false;
}
final CarpetScriptServer scriptServer = Vanilla.MinecraftServer_getScriptServer(source.getServer());
if (scriptServer.stopAll)
{
return false;
}
final Boolean isCancelled = scriptServer.events.handleEvents.runIfEnabled(() -> {
final Runnable profilerToken = Carpet.startProfilerSection("Scarpet events");
final List<Value> argv = argumentSupplier.get(); // empty for onTickDone
final String nameCheck = perPlayerDistribution ? source.getTextName() : null;
assert argv.size() == reqArgs;
boolean cancelled = false;
try
{
// we are ok with list growing in the meantime
// which might happen during inCall or inSignal
inCall = true;
for (int i = 0; i < callList.size(); i++)
{
source = cmdSourceSupplier.get();
}
catch (final NullPointerException noReference) // todo figure out what happens when closing.
{
return false;
}
final String nameCheck = perPlayerDistribution ? source.getTextName() : null;
assert argv.size() == reqArgs;
boolean cancelled = false;
try
{
// we are ok with list growing in the meantime
// which might happen during inCall or inSignal
inCall = true;
for (int i = 0; i < callList.size(); i++)
final Callback call = callList.get(i);
// supressing calls where target player hosts simply don't match
// handling global hosts with player targets is left to when the host is resolved (few calls deeper).
if (nameCheck != null && call.optionalTarget != null && !nameCheck.equals(call.optionalTarget))
{
final Callback call = callList.get(i);
// supressing calls where target player hosts simply don't match
// handling global hosts with player targets is left to when the host is resolved (few calls deeper).
if (nameCheck != null && call.optionalTarget != null && !nameCheck.equals(call.optionalTarget))
{
continue;
}
final CallbackResult result = call.execute(source, argv);
if (result == CallbackResult.CANCEL)
{
cancelled = true;
break;
}
if (result == CallbackResult.FAIL)
{
removedCalls.add(call);
}
continue;
}
final CallbackResult result = call.execute(source, argv);
if (result == CallbackResult.CANCEL)
{
cancelled = true;
break;
}
if (result == CallbackResult.FAIL)
{
removedCalls.add(call);
}
}
finally
{
inCall = false;
}
for (final Callback call : removedCalls)
{
callList.remove(call);
}
removedCalls.clear();
CarpetProfiler.end_current_section(currentSection);
return cancelled;
});
return isCancelled != null && isCancelled;
}
return false;
}
finally
{
inCall = false;
}
for (final Callback call : removedCalls)
{
callList.remove(call);
}
removedCalls.clear();
profilerToken.run();
return cancelled;
});
return isCancelled != null && isCancelled;
}
public int signal(final CommandSourceStack sender, final ServerPlayer optinoalReceipient, final List<Value> callArg)
@@ -323,13 +326,13 @@ public class CarpetEventServer
return successes;
}
public boolean addFromExternal(final CommandSourceStack source, final String hostName, final String funName, final Consumer<ScriptHost> hostOnEventHandler)
public boolean addFromExternal(final CommandSourceStack source, final String hostName, final String funName, final Consumer<ScriptHost> hostOnEventHandler, final CarpetScriptServer scriptServer)
{
final ScriptHost host = CarpetServer.scriptServer.getAppHostByName(hostName);
final ScriptHost host = scriptServer.getAppHostByName(hostName);
if (host == null)
{
// impossible call to add
Messenger.m(source, "r Unknown app " + hostName);
Carpet.Messenger_message(source, "r Unknown app " + hostName);
return false;
}
hostOnEventHandler.accept(host);
@@ -337,7 +340,7 @@ public class CarpetEventServer
if (udf == null || udf.getArguments().size() != reqArgs)
{
// call won't match arguments
Messenger.m(source, "r Callback doesn't expect required number of arguments: " + reqArgs);
Carpet.Messenger_message(source, "r Callback doesn't expect required number of arguments: " + reqArgs);
return false;
}
String target = null;
@@ -349,7 +352,7 @@ public class CarpetEventServer
}
catch (final CommandSyntaxException e)
{
Messenger.m(source, "r Cannot add event to a player scoped app from a command without a player context");
Carpet.Messenger_message(source, "r Cannot add event to a player scoped app from a command without a player context");
return false;
}
}
@@ -357,7 +360,7 @@ public class CarpetEventServer
//remove duplicates
removeEventCall(hostName, target, udf.getString());
callList.add(new Callback(hostName, target, udf, null));
callList.add(new Callback(hostName, target, udf, null, scriptServer));
return true;
}
@@ -369,7 +372,7 @@ public class CarpetEventServer
}
//removing duplicates
removeEventCall(host.getName(), host.user, function.getString());
callList.add(new Callback(host.getName(), host.user, function, args));
callList.add(new Callback(host.getName(), host.user, function, args, (CarpetScriptServer) host.scriptServer()));
return true;
}
@@ -392,10 +395,10 @@ public class CarpetEventServer
final List<Callback> copyCalls = new ArrayList<>();
callList.forEach((c) ->
{
if ((Objects.equals(c.host, host.getName()))
if ((Objects.equals(c.host, host.getName())) // TODO fix me
&& c.optionalTarget == null)
{
copyCalls.add(new Callback(c.host, host.user, c.function, c.parametrizedArgs));
copyCalls.add(new Callback(c.host, host.user, c.function, c.parametrizedArgs, host.scriptServer()));
}
});
callList.addAll(copyCalls);
@@ -434,11 +437,10 @@ public class CarpetEventServer
public static final Event START = new Event("server_starts", 0, true)
{
@Override
public void onTick()
public void onTick(final MinecraftServer server)
{
handler.call(Collections::emptyList, () ->
CarpetServer.minecraft_server.createCommandSourceStack().
withLevel(CarpetServer.minecraft_server.getLevel(Level.OVERWORLD))
server.createCommandSourceStack().withLevel(server.getLevel(Level.OVERWORLD))
);
}
};
@@ -446,11 +448,10 @@ public class CarpetEventServer
public static final Event SHUTDOWN = new Event("server_shuts_down", 0, true)
{
@Override
public void onTick()
public void onTick(final MinecraftServer server)
{
handler.call(Collections::emptyList, () ->
CarpetServer.minecraft_server.createCommandSourceStack().
withLevel(CarpetServer.minecraft_server.getLevel(Level.OVERWORLD))
server.createCommandSourceStack().withLevel(server.getLevel(Level.OVERWORLD))
);
}
};
@@ -458,11 +459,10 @@ public class CarpetEventServer
public static final Event TICK = new Event("tick", 0, true)
{
@Override
public void onTick()
public void onTick(final MinecraftServer server)
{
handler.call(Collections::emptyList, () ->
CarpetServer.minecraft_server.createCommandSourceStack().
withLevel(CarpetServer.minecraft_server.getLevel(Level.OVERWORLD))
server.createCommandSourceStack().withLevel(server.getLevel(Level.OVERWORLD))
);
}
};
@@ -475,11 +475,11 @@ public class CarpetEventServer
}
@Override
public void onTick()
public void onTick(final MinecraftServer server)
{
handler.call(Collections::emptyList, () ->
CarpetServer.minecraft_server.createCommandSourceStack().
withLevel(CarpetServer.minecraft_server.getLevel(Level.NETHER))
server.createCommandSourceStack().
withLevel(server.getLevel(Level.NETHER))
);
}
};
@@ -492,11 +492,11 @@ public class CarpetEventServer
}
@Override
public void onTick()
public void onTick(final MinecraftServer server)
{
handler.call(Collections::emptyList, () ->
CarpetServer.minecraft_server.createCommandSourceStack().
withLevel(CarpetServer.minecraft_server.getLevel(Level.END))
server.createCommandSourceStack().
withLevel(server.getLevel(Level.END))
);
}
};
@@ -507,7 +507,7 @@ public class CarpetEventServer
{
handler.call(
() -> Arrays.asList(new NumericValue(chPos.x << 4), new NumericValue(chPos.z << 4)),
() -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel(world)
() -> world.getServer().createCommandSourceStack().withLevel(world)
);
}
};
@@ -518,7 +518,7 @@ public class CarpetEventServer
{
handler.call(
() -> Arrays.asList(new NumericValue(chPos.x << 4), new NumericValue(chPos.z << 4)),
() -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel(world)
() -> world.getServer().createCommandSourceStack().withLevel(world)
);
}
};
@@ -530,7 +530,7 @@ public class CarpetEventServer
{
handler.call(
() -> Arrays.asList(new NumericValue(chPos.x << 4), new NumericValue(chPos.z << 4)),
() -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel(world)
() -> world.getServer().createCommandSourceStack().withLevel(world)
);
}
};
@@ -714,7 +714,7 @@ public class CarpetEventServer
final RegistryAccess regs = player.getLevel().registryAccess();
handler.call(() -> Arrays.asList(
new EntityValue(player),
merchant instanceof final AbstractVillager villager? new EntityValue(villager) : Value.NULL,
merchant instanceof final AbstractVillager villager ? new EntityValue(villager) : Value.NULL,
ValueConversions.of(tradeOffer.getBaseCostA(), regs),
ValueConversions.of(tradeOffer.getCostB(), regs),
ValueConversions.of(tradeOffer.getResult(), regs)
@@ -1015,30 +1015,7 @@ public class CarpetEventServer
() -> Arrays.asList(
new BlockValue(null, world, pos),
flag > 0 ? Value.TRUE : Value.FALSE
), () -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel(world)
);
}
};
public static final Event CARPET_RULE_CHANGES = new Event("carpet_rule_changes", 2, true)
{
@Override
public void onCarpetRuleChanges(final CarpetRule<?> rule, final CommandSourceStack source)
{
final String identifier = rule.settingsManager().identifier();
final String namespace;
if (!identifier.equals("carpet"))
{
namespace = identifier + ":";
}
else
{
namespace = "";
}
handler.call(
() -> Arrays.asList(
new StringValue(namespace + rule.name()),
new StringValue(RuleHelper.toRuleString(rule.value()))
), () -> source
), () -> world.getServer().createCommandSourceStack().withLevel(world)
);
}
};
@@ -1086,7 +1063,7 @@ public class CarpetEventServer
b -> new BlockValue(world.getBlockState(b), world, b)
)),
ListValue.wrap(affectedEntities.stream().map(EntityValue::of))
), () -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel(world)
), () -> world.getServer().createCommandSourceStack().withLevel(world)
);
}
};
@@ -1105,7 +1082,7 @@ public class CarpetEventServer
EntityValue.of(attacker != null ? attacker.get() : Event.getExplosionCausingEntity(e)),
StringValue.of(type.name().toLowerCase(Locale.ROOT)),
BooleanValue.of(createFire)
), () -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel(world)
), () -> world.getServer().createCommandSourceStack().withLevel(world)
);
}
};
@@ -1126,7 +1103,7 @@ public class CarpetEventServer
{
handler.call(
() -> Collections.singletonList(new EntityValue(entity)),
() -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel((ServerLevel) entity.level).withPermission(CarpetSettings.runPermissionLevel)
() -> entity.getServer().createCommandSourceStack().withLevel((ServerLevel) entity.level).withPermission(Vanilla.MinecraftServer_getRunPermissionLevel(entity.getServer()))
);
}
})).collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));
@@ -1145,7 +1122,7 @@ public class CarpetEventServer
{
handler.call(
() -> Arrays.asList(new EntityValue(entity), BooleanValue.of(created)),
() -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel((ServerLevel) entity.level).withPermission(CarpetSettings.runPermissionLevel)
() -> entity.getServer().createCommandSourceStack().withLevel((ServerLevel) entity.level).withPermission(Vanilla.MinecraftServer_getRunPermissionLevel(entity.getServer()))
);
}
}))
@@ -1241,7 +1218,7 @@ public class CarpetEventServer
}
//stubs for calls just to ease calls in vanilla code so they don't need to deal with scarpet value types
public void onTick()
public void onTick(final MinecraftServer server)
{
}
@@ -1339,7 +1316,7 @@ public class CarpetEventServer
{
}
public void onCarpetRuleChanges(final CarpetRule<?> rule, final CommandSourceStack source)
public void handleAny(final Object... args)
{
}
@@ -1376,7 +1353,7 @@ public class CarpetEventServer
valArgs.add(ValueConversions.guess(world, o));
}
return valArgs;
}, () -> CarpetServer.minecraft_server.createCommandSourceStack().withLevel(world)
}, () -> world.getServer().createCommandSourceStack().withLevel(world)
);
}
}
@@ -1390,7 +1367,7 @@ public class CarpetEventServer
public void tick()
{
if (!TickSpeed.process_entities)
if (Carpet.isTickProcessingPaused())
{
return;
}
@@ -1455,7 +1432,7 @@ public class CarpetEventServer
return CallbackResult.FAIL;
}
}
final CommandSourceStack source = sender.withPermission(CarpetSettings.runPermissionLevel);
final CommandSourceStack source = sender.withPermission(Vanilla.MinecraftServer_getRunPermissionLevel(sender.getServer()));
final CarpetScriptHost executingHost = appHost.retrieveForExecution(sender, target);
if (executingHost == null)
{
@@ -1463,7 +1440,7 @@ public class CarpetEventServer
}
try
{
final Value returnValue = executingHost.callUDF(source.withPermission(CarpetSettings.runPermissionLevel), udf, argv);
final Value returnValue = executingHost.callUDF(source, udf, argv);
return returnValue instanceof StringValue && returnValue.getString().equals("cancel") ? CallbackResult.CANCEL : CallbackResult.SUCCESS;
}
catch (final NullPointerException | InvalidCallbackException | IntegrityException error)
@@ -1475,15 +1452,15 @@ public class CarpetEventServer
public boolean addEventFromCommand(final CommandSourceStack source, final String event, final String host, final String funName)
{
final Event ev = Event.getEvent(event, CarpetServer.scriptServer);
final Event ev = Event.getEvent(event, scriptServer);
if (ev == null)
{
return false;
}
final boolean added = ev.handler.addFromExternal(source, host, funName, h -> onEventAddedToHost(ev, h));
final boolean added = ev.handler.addFromExternal(source, host, funName, h -> onEventAddedToHost(ev, h), scriptServer);
if (added)
{
Messenger.m(source, "gi Added " + funName + " to " + event);
Carpet.Messenger_message(source, "gi Added " + funName + " to " + event);
}
return added;
}
@@ -1524,16 +1501,16 @@ public class CarpetEventServer
public boolean removeEventFromCommand(final CommandSourceStack source, final String event, final String funName)
{
final Event ev = Event.getEvent(event, CarpetServer.scriptServer);
final Event ev = Event.getEvent(event, scriptServer);
if (ev == null)
{
Messenger.m(source, "r Unknown event: " + event);
Carpet.Messenger_message(source, "r Unknown event: " + event);
return false;
}
final Callback.Signature call = Callback.fromString(funName);
ev.handler.removeEventCall(call.host, call.target, call.function);
// could verified if actually removed
Messenger.m(source, "gi Removed event: " + funName + " from " + event);
Carpet.Messenger_message(source, "gi Removed event: " + funName + " from " + event);
return true;
}
@@ -1,6 +1,5 @@
package carpet.script;
import carpet.CarpetServer;
import carpet.script.annotation.AnnotationParser;
import carpet.script.api.Auxiliary;
import carpet.script.api.BlockIterators;
@@ -12,6 +11,7 @@ import carpet.script.api.Threading;
import carpet.script.api.WorldAccess;
import carpet.script.exception.CarpetExpressionException;
import carpet.script.exception.ExpressionException;
import carpet.script.external.Carpet;
import carpet.script.value.BlockValue;
import carpet.script.value.EntityValue;
import carpet.script.value.NumericValue;
@@ -58,12 +58,13 @@ public class CarpetExpression
Scoreboards.apply(this.expr);
Monitoring.apply(this.expr);
AnnotationParser.apply(this.expr);
CarpetServer.extensions.forEach(e -> e.scarpetApi(this));
Carpet.handleExtensionsAPI(this);
}
public boolean fillAndScanCommand(final ScriptHost host, final int x, final int y, final int z)
{
if (CarpetServer.scriptServer.stopAll)
CarpetScriptServer scriptServer = (CarpetScriptServer) host.scriptServer();
if (scriptServer.stopAll)
{
return false;
}
@@ -85,7 +86,7 @@ public class CarpetExpression
final Value playerValue = new EntityValue(e).bindTo("p");
context.with("p", (cc, tt) -> playerValue);
}
return CarpetServer.scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context).getBoolean());
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context).getBoolean());
}
catch (final ExpressionException e)
{
@@ -103,7 +104,8 @@ public class CarpetExpression
public Value scriptRunCommand(final ScriptHost host, final BlockPos pos)
{
if (CarpetServer.scriptServer.stopAll)
CarpetScriptServer scriptServer = (CarpetScriptServer) host.scriptServer();
if (scriptServer.stopAll)
{
throw new CarpetExpressionException("SCRIPTING PAUSED (unpause with /script resume)", null);
}
@@ -124,7 +126,7 @@ public class CarpetExpression
final Value playerValue = new EntityValue(e).bindTo("p");
context.with("p", (cc, tt) -> playerValue);
}
return CarpetServer.scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context));
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context));
}
catch (final ExpressionException e)
{
@@ -1,7 +1,5 @@
package carpet.script;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.script.api.Auxiliary;
import carpet.script.argument.FileArgument;
import carpet.script.argument.FunctionArgument;
@@ -13,6 +11,8 @@ import carpet.script.exception.IntegrityException;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.InvalidCallbackException;
import carpet.script.exception.LoadException;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.utils.AppStoreManager;
import carpet.script.value.EntityValue;
import carpet.script.value.FunctionValue;
@@ -21,8 +21,6 @@ import carpet.script.value.MapValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.utils.CarpetProfiler;
import carpet.utils.Messenger;
import com.google.gson.JsonElement;
import com.mojang.brigadier.arguments.StringArgumentType;
@@ -144,8 +142,9 @@ public class CarpetScriptHost extends ScriptHost
private static int execute(final CommandContext<CommandSourceStack> ctx, final String hostName, final FunctionArgument funcSpec, final List<String> paramNames) throws CommandSyntaxException
{
final CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet command", CarpetProfiler.TYPE.GENERAL);
final CarpetScriptHost cHost = CarpetServer.scriptServer.modules.get(hostName).retrieveOwnForExecution(ctx.getSource());
final Runnable token = Carpet.startProfilerSection("Scarpet command");
final CarpetScriptServer scriptServer = Vanilla.MinecraftServer_getScriptServer(ctx.getSource().getServer());
final CarpetScriptHost cHost = scriptServer.modules.get(hostName).retrieveOwnForExecution(ctx.getSource());
final List<String> argNames = funcSpec.function.getArguments();
if ((argNames.size() - funcSpec.args.size()) != paramNames.size())
{
@@ -159,7 +158,7 @@ public class CarpetScriptHost extends ScriptHost
args.addAll(funcSpec.args);
final Value response = cHost.handleCommand(ctx.getSource(), funcSpec.function, args);
final int intres = (int) response.readInteger();
CarpetProfiler.end_current_section(currentSection);
token.run();
return intres;
}
@@ -239,18 +238,18 @@ public class CarpetScriptHost extends ScriptHost
return s -> {
try
{
final CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet command", CarpetProfiler.TYPE.GENERAL);
final CarpetScriptHost cHost = CarpetServer.scriptServer.modules.get(hostName).retrieveOwnForExecution(s);
final Runnable token = Carpet.startProfilerSection("Scarpet command");
final CarpetScriptHost cHost = scriptServer().modules.get(hostName).retrieveOwnForExecution(s);
final Value response = cHost.handleCommand(s, fun, Collections.singletonList(
(s.getEntity() instanceof ServerPlayer) ? new EntityValue(s.getEntity()) : Value.NULL)
);
final boolean res = response.getBoolean();
CarpetProfiler.end_current_section(currentSection);
token.run();
return res;
}
catch (final CommandSyntaxException e)
{
Messenger.m(s, "rb Unable to run app command: " + e.getMessage());
Carpet.Messenger_message(s, "rb Unable to run app command: " + e.getMessage());
return false;
}
};
@@ -434,14 +433,14 @@ public class CarpetScriptHost extends ScriptHost
}
catch (final CommandSyntaxException e)
{
notifier.accept(Messenger.c("r Error when handling of setting up custom argument types: " + e.getMessage()));
notifier.accept(Carpet.Messenger_compose("r Error when handling of setting up custom argument types: " + e.getMessage()));
return false;
}
if (appConfig.get(StringValue.of("commands")) != null)
{
if (scriptServer().isInvalidCommandRoot(getName()))
{
notifier.accept(Messenger.c("g A command with the app's name already exists in vanilla or an installed mod."));
notifier.accept(Carpet.Messenger_compose("g A command with the app's name already exists in vanilla or an installed mod."));
return null;
}
try
@@ -457,7 +456,7 @@ public class CarpetScriptHost extends ScriptHost
catch (final CommandSyntaxException cse)
{
// failed
notifier.accept(Messenger.c("r Failed to build command system: ", cse.getRawMessage()));
notifier.accept(Carpet.Messenger_compose("r Failed to build command system: ", cse.getRawMessage()));
return null;
}
@@ -512,7 +511,7 @@ public class CarpetScriptHost extends ScriptHost
if (scriptServer().isInvalidCommandRoot(getName()))
{
notifier.accept(Messenger.c("g A command with the app's name already exists in vanilla or an installed mod."));
notifier.accept(Carpet.Messenger_compose("g A command with the app's name already exists in vanilla or an installed mod."));
return null;
}
@@ -523,7 +522,7 @@ public class CarpetScriptHost extends ScriptHost
}
catch (final CommandSyntaxException e)
{
notifier.accept(Messenger.c("rb " + e.getMessage()));
notifier.accept(Carpet.Messenger_compose("rb " + e.getMessage()));
return null;
}
final String hostName = getName();
@@ -535,7 +534,7 @@ public class CarpetScriptHost extends ScriptHost
final Value response = targetHost.handleCommandLegacy(c.getSource(), "__command", null, "");
if (!response.isNull())
{
Messenger.m(c.getSource(), "gi " + response.getString());
Carpet.Messenger_message(c.getSource(), "gi " + response.getString());
}
return (int) response.readInteger();
});
@@ -570,7 +569,7 @@ public class CarpetScriptHost extends ScriptHost
final Value response = targetHost.handleCommandLegacy(c.getSource(), function, null, "");
if (!response.isNull())
{
Messenger.m(c.getSource(), "gi " + response.getString());
Carpet.Messenger_message(c.getSource(), "gi " + response.getString());
}
return (int) response.readInteger();
}).
@@ -580,7 +579,7 @@ public class CarpetScriptHost extends ScriptHost
final Value response = targetHost.handleCommandLegacy(c.getSource(), function, null, StringArgumentType.getString(c, "args..."));
if (!response.isNull())
{
Messenger.m(c.getSource(), "gi " + response.getString());
Carpet.Messenger_message(c.getSource(), "gi " + response.getString());
}
return (int) response.readInteger();
})));
@@ -721,9 +720,9 @@ public class CarpetScriptHost extends ScriptHost
{
try
{
final CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet command", CarpetProfiler.TYPE.GENERAL);
final Runnable token = Carpet.startProfilerSection("Scarpet command");
final Value res = callLegacy(source, call, coords, arg);
CarpetProfiler.end_current_section(currentSection);
token.run();
return res;
}
catch (final CarpetExpressionException exc)
@@ -764,7 +763,7 @@ public class CarpetScriptHost extends ScriptHost
public Value callLegacy(final CommandSourceStack source, final String call, final List<Integer> coords, final String arg)
{
if (CarpetServer.scriptServer.stopAll)
if (scriptServer().stopAll)
{
throw new CarpetExpressionException("SCARPET PAUSED (unpause with /script resume)", null);
}
@@ -871,7 +870,7 @@ public class CarpetScriptHost extends ScriptHost
public Value call(final CommandSourceStack source, final FunctionValue function, final List<Value> argv)
{
if (CarpetServer.scriptServer.stopAll)
if (scriptServer().stopAll)
{
throw new CarpetExpressionException("SCARPET PAUSED (unpause with /script resume)", null);
}
@@ -909,7 +908,7 @@ public class CarpetScriptHost extends ScriptHost
public Value callUDF(final BlockPos origin, final CommandSourceStack source, final FunctionValue fun, final List<Value> argv) throws InvalidCallbackException, IntegrityException
{
if (CarpetServer.scriptServer.stopAll)
if (scriptServer().stopAll)
{
return Value.NULL;
}
@@ -987,12 +986,12 @@ public class CarpetScriptHost extends ScriptHost
private void dumpState()
{
Module.saveData(main, globalState);
Module.saveData(main, globalState, this.scriptServer());
}
private Tag loadState()
{
return Module.getData(main);
return Module.getData(main, this.scriptServer());
}
public Tag readFileTag(final FileArgument fdesc)
@@ -1061,7 +1060,7 @@ public class CarpetScriptHost extends ScriptHost
public boolean applyActionForResource(final String path, final boolean shared, final Consumer<Path> action)
{
final FileArgument fdesc = FileArgument.resourceFromPath(path, FileArgument.Reason.CREATE, shared);
final FileArgument fdesc = FileArgument.resourceFromPath(this, path, FileArgument.Reason.CREATE, shared);
return fdesc.findPathAndApply(main, action);
}
@@ -1104,21 +1103,21 @@ public class CarpetScriptHost extends ScriptHost
{
shebang += " at pos " + (token.pos + 1);
}
Messenger.m(source, "r " + shebang);
Carpet.Messenger_message(source, "r " + shebang);
if (lines.length > 1 && token.lineno > 0)
{
Messenger.m(source, withLocals("l", lines[token.lineno - 1], ctx));
Carpet.Messenger_message(source, withLocals("l", lines[token.lineno - 1], ctx));
}
Messenger.m(source, withLocals("l", lines[token.lineno].substring(0, token.linepos), ctx), "r HERE>> ",
Carpet.Messenger_message(source, withLocals("l", lines[token.lineno].substring(0, token.linepos), ctx), "r HERE>> ",
withLocals("l", lines[token.lineno].substring(token.linepos), ctx));
if (lines.length > 1 && token.lineno < lines.length - 1)
{
Messenger.m(source, withLocals("l", lines[token.lineno + 1], ctx));
Carpet.Messenger_message(source, withLocals("l", lines[token.lineno + 1], ctx));
}
}
else
{
Messenger.m(source, "r " + shebang);
Carpet.Messenger_message(source, "r " + shebang);
}
return new ArrayList<>();
};
@@ -1182,7 +1181,7 @@ public class CarpetScriptHost extends ScriptHost
{
stringsToFormat.add(format + line.substring(lastPos));
}
return Messenger.c(stringsToFormat.toArray());
return Carpet.Messenger_compose(stringsToFormat.toArray());
}
@Override
@@ -1201,11 +1200,11 @@ public class CarpetScriptHost extends ScriptHost
cee.printStack(responsibleSource);
}
final String message = exception.getMessage();
Messenger.m(responsibleSource, "r " + intro + ((message == null || message.isEmpty()) ? "" : ": " + message));
Carpet.Messenger_message(responsibleSource, "r " + intro + ((message == null || message.isEmpty()) ? "" : ": " + message));
}
else
{
CarpetSettings.LOG.error(intro + ": " + exception.getMessage());
CarpetScriptServer.LOG.error(intro + ": " + exception.getMessage());
}
}
@@ -1235,7 +1234,7 @@ public class CarpetScriptHost extends ScriptHost
{
if (super.issueDeprecation(feature))
{
Messenger.m(responsibleSource, "rb '" + feature + "' is deprecated and soon will be removed. Please consult the docs for their replacement");
Carpet.Messenger_message(responsibleSource, "rb '" + feature + "' is deprecated and soon will be removed. Please consult the docs for their replacement");
return true;
}
return false;
@@ -1,7 +1,5 @@
package carpet.script;
import carpet.CarpetSettings;
import carpet.fakes.CommandDispatcherInterface;
import carpet.script.annotation.AnnotationParser;
import carpet.script.api.Auxiliary;
import carpet.script.api.BlockIterators;
@@ -9,9 +7,10 @@ import carpet.script.api.Entities;
import carpet.script.api.Inventories;
import carpet.script.api.Scoreboards;
import carpet.script.api.WorldAccess;
import carpet.CarpetServer;
import carpet.script.exception.ExpressionException;
import carpet.script.exception.LoadException;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.language.Arithmetic;
import carpet.script.language.ControlFlow;
import carpet.script.language.DataStructures;
@@ -21,9 +20,6 @@ import carpet.script.language.Sys;
import carpet.script.language.Threading;
import carpet.script.utils.AppStoreManager;
import carpet.script.value.FunctionValue;
import carpet.utils.CarpetProfiler;
import carpet.utils.CommandHelper;
import carpet.utils.Messenger;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.tree.CommandNode;
@@ -127,21 +123,14 @@ public class CarpetScriptServer extends ScriptServer
public void initializeForWorld()
{
CarpetServer.settingsManager.initializeScarpetRules();
CarpetServer.extensions.forEach(e -> {
if (e.extensionSettingsManager() != null)
{
e.extensionSettingsManager().initializeScarpetRules();
}
});
if (CarpetSettings.scriptsAutoload)
if (Vanilla.MinecraftServer_doScriptsAutoload(server))
{
for (final String moduleName : listAvailableModules(false))
{
addScriptHost(server.createCommandSourceStack(), moduleName, null, true, true, false, null);
}
}
CarpetEventServer.Event.START.onTick();
CarpetEventServer.Event.START.onTick(server);
}
public Module getModule(final String name, final boolean allowLibraries)
@@ -188,7 +177,7 @@ public class CarpetScriptServer extends ScriptServer
}
catch (final IOException e)
{
CarpetSettings.LOG.error("Exception while loading the app: ", e);
LOG.error("Exception while loading the app: ", e);
}
for (final Module moduleData : bundledModuleData)
{
@@ -256,7 +245,7 @@ public class CarpetScriptServer extends ScriptServer
}
catch (final IOException e)
{
CarpetSettings.LOG.error("Exception while searching for apps: ", e);
LOG.error("Exception while searching for apps: ", e);
}
return moduleNames;
}
@@ -269,7 +258,7 @@ public class CarpetScriptServer extends ScriptServer
public boolean addScriptHost(final CommandSourceStack source, String name, Predicate<CommandSourceStack> commandValidator,
final boolean perPlayer, final boolean autoload, final boolean isRuleApp, final AppStoreManager.StoreNode installer)
{
final CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet load", CarpetProfiler.TYPE.GENERAL);
final Runnable token = Carpet.startProfilerSection("Scarpet load");
if (commandValidator == null)
{
commandValidator = p -> true;
@@ -289,7 +278,7 @@ public class CarpetScriptServer extends ScriptServer
final Module module = isRuleApp ? getRuleModule(name) : getModule(name, false);
if (module == null)
{
Messenger.m(source, "r Failed to add " + name + " app: App not found");
Carpet.Messenger_message(source, "r Failed to add " + name + " app: App not found");
return false;
}
final CarpetScriptHost newHost;
@@ -299,7 +288,7 @@ public class CarpetScriptServer extends ScriptServer
}
catch (final LoadException e)
{
Messenger.m(source, "r Failed to add " + name + " app" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
Carpet.Messenger_message(source, "r Failed to add " + name + " app" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
return false;
}
@@ -320,7 +309,7 @@ public class CarpetScriptServer extends ScriptServer
final Boolean isCommandAdded = newHost.addAppCommands(s -> {
if (!isRuleApp)
{
Messenger.m(source, Messenger.c("r Failed to add app '" + finalName + "': ", s));
Carpet.Messenger_message(source, "r Failed to add app '" + finalName + "': ", s);
}
});
if (isCommandAdded == null) // error should be dispatched
@@ -330,17 +319,17 @@ public class CarpetScriptServer extends ScriptServer
}
else if (isCommandAdded)
{
CommandHelper.notifyPlayersCommandsChanged(server);
Vanilla.MinecraftServer_notifyPlayersCommandsChanged(server);
if (!isRuleApp)
{
Messenger.m(source, "gi " + name + " app " + action + " with /" + name + " command");
Carpet.Messenger_message(source, "gi " + name + " app " + action + " with /" + name + " command");
}
}
else
{
if (!isRuleApp)
{
Messenger.m(source, "gi " + name + " app " + action);
Carpet.Messenger_message(source, "gi " + name + " app " + action);
}
}
@@ -361,9 +350,9 @@ public class CarpetScriptServer extends ScriptServer
newHost.callNow(onStart, Collections.emptyList());
}
}
CarpetProfiler.end_current_section(currentSection);
token.run();
final long end = System.nanoTime();
CarpetSettings.LOG.info("App " + name + " loaded in " + (end - start) / 1000000 + " ms");
LOG.info("App " + name + " loaded in " + (end - start) / 1000000 + " ms");
return true;
}
@@ -380,7 +369,7 @@ public class CarpetScriptServer extends ScriptServer
{
if (notifySource)
{
Messenger.m(source, "r No such app found: ", "wb " + name);
Carpet.Messenger_message(source, "r No such app found: ", "wb " + name);
}
return false;
}
@@ -390,16 +379,16 @@ public class CarpetScriptServer extends ScriptServer
host.onClose();
if (host.hasCommand)
{
((CommandDispatcherInterface) server.getCommands().getDispatcher()).carpet$unregister(name);
Vanilla.CommandDispatcher_unregisterCommand(server.getCommands().getDispatcher(), name);
}
if (!isRuleApp)
{
unloadableModules.remove(name);
}
CommandHelper.notifyPlayersCommandsChanged(server);
Vanilla.MinecraftServer_notifyPlayersCommandsChanged(server);
if (notifySource)
{
Messenger.m(source, "gi Removed " + name + " app");
Carpet.Messenger_message(source, "gi Removed " + name + " app");
}
return true;
}
@@ -416,46 +405,47 @@ public class CarpetScriptServer extends ScriptServer
}
if (!Files.exists(folder.getParent().resolve(name + ".sc")))
{
Messenger.m(source, "App doesn't exist in the world scripts folder, so can only be unloaded");
Carpet.Messenger_message(source, "App doesn't exist in the world scripts folder, so can only be unloaded");
return false;
}
removeScriptHost(source, name, false, false);
Files.move(folder.getParent().resolve(name + ".sc"), folder.resolve(name + ".sc"), StandardCopyOption.REPLACE_EXISTING);
Messenger.m(source, "gi Removed " + name + " app");
Carpet.Messenger_message(source, "gi Removed " + name + " app");
return true;
}
catch (final IOException exc)
{
Messenger.m(source, "rb Failed to uninstall the app");
Carpet.Messenger_message(source, "rb Failed to uninstall the app");
}
return false;
}
public void tick()
{
CarpetProfiler.ProfilerToken token;
token = CarpetProfiler.start_section(null, "Scarpet schedule", CarpetProfiler.TYPE.GENERAL);
Runnable token;
token = Carpet.startProfilerSection("Scarpet schedule");
events.handleEvents.getWhileDisabled(() -> {
events.tick();
return null;
});
CarpetProfiler.end_current_section(token);
token = CarpetProfiler.start_section(null, "Scarpet app data", CarpetProfiler.TYPE.GENERAL);
token.run();
token = Carpet.startProfilerSection("Scarpet app data");
for (final CarpetScriptHost host : modules.values())
{
host.tick();
}
CarpetProfiler.end_current_section(token);
token.run();
}
public void onClose()
{
CarpetEventServer.Event.SHUTDOWN.onTick();
CarpetEventServer.Event.SHUTDOWN.onTick(server);
for (final CarpetScriptHost host : modules.values())
{
host.onClose();
events.removeAllHostEvents(host);
}
stopAll = true;
}
public void onPlayerJoin(final ServerPlayer player)
@@ -475,6 +465,12 @@ public class CarpetScriptServer extends ScriptServer
});
}
@Override
public Path resolveResource(final String suffix)
{
return server.getWorldPath(LevelResource.ROOT).resolve("scripts/" + suffix);
}
private record TransferData(boolean perUser, Predicate<CommandSourceStack> commandValidator,
boolean isRuleApp)
{
+5
View File
@@ -91,6 +91,11 @@ public class Context
return host.errorSnooper;
}
public ScriptServer scriptServer()
{
return host.scriptServer();
}
/**
* immutable context only for reason on reporting access violations in evaluating expressions in optimizization
* mode detecting any potential violations that may happen on the way
@@ -1,7 +1,7 @@
package carpet.script;
import carpet.CarpetServer;
import carpet.script.exception.InternalExpressionException;
import carpet.script.external.Vanilla;
import carpet.script.value.EntityValue;
import carpet.script.value.FunctionValue;
import carpet.script.value.NumericValue;
@@ -46,7 +46,8 @@ public class EntityEventsGroup
{
return;
}
if (CarpetServer.scriptServer == null)
final CarpetScriptServer scriptServer = Vanilla.MinecraftServer_getScriptServer(entity.getServer());
if (scriptServer.stopAll)
{
return; // executed after world is closin down
}
@@ -54,7 +55,7 @@ public class EntityEventsGroup
{
final Map.Entry<EventKey, CarpetEventServer.Callback> action = iterator.next();
final EventKey key = action.getKey();
final ScriptHost host = CarpetServer.scriptServer.getAppHostByName(key.host());
final ScriptHost host = scriptServer.getAppHostByName(key.host());
if (host == null)
{
iterator.remove();
@@ -81,7 +82,7 @@ public class EntityEventsGroup
final EventKey key = new EventKey(host.getName(), host.user);
if (fun != null)
{
final CarpetEventServer.Callback call = type.create(key, fun, extraargs);
final CarpetEventServer.Callback call = type.create(key, fun, extraargs, (CarpetScriptServer) host.scriptServer());
if (call == null)
{
throw new InternalExpressionException("wrong number of arguments for callback, required " + type.argcount);
@@ -154,13 +155,13 @@ public class EntityEventsGroup
byName.put(identifier, this);
}
public CarpetEventServer.Callback create(final EventKey key, final FunctionValue function, final List<Value> extraArgs)
public CarpetEventServer.Callback create(final EventKey key, final FunctionValue function, final List<Value> extraArgs, final CarpetScriptServer scriptServer)
{
if ((function.getArguments().size() - (extraArgs == null ? 0 : extraArgs.size())) != argcount)
{
return null;
}
return new CarpetEventServer.Callback(key.host(), key.user(), function, extraArgs);
return new CarpetEventServer.Callback(key.host(), key.user(), function, extraArgs, scriptServer);
}
public CarpetEventServer.CallbackResult call(final CarpetEventServer.Callback tickCall, final Entity entity, final Object... args)
+27 -24
View File
@@ -1,6 +1,5 @@
package carpet.script;
import carpet.CarpetSettings;
import carpet.script.Fluff.AbstractFunction;
import carpet.script.Fluff.AbstractLazyFunction;
import carpet.script.Fluff.AbstractLazyOperator;
@@ -20,6 +19,7 @@ import carpet.script.exception.IntegrityException;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ResolvedException;
import carpet.script.exception.ReturnStatement;
import carpet.script.external.Vanilla;
import carpet.script.language.Arithmetic;
import carpet.script.language.ControlFlow;
import carpet.script.language.DataStructures;
@@ -44,12 +44,14 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.*;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.DoubleToLongFunction;
import java.util.function.DoubleUnaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static java.lang.Math.max;
import static java.lang.Math.min;
public class Expression
{
/**
@@ -164,8 +166,8 @@ public class Expression
}
else
{
output.add(expr.substring(max(0, token.pos - 40), token.pos));
output.add(expr.substring(token.pos, min(token.pos + 1 + 40, expr.length())));
output.add(expr.substring(Math.max(0, token.pos - 40), token.pos));
output.add(expr.substring(token.pos, Math.min(token.pos + 1 + 40, expr.length())));
}
return output;
}
@@ -424,7 +426,7 @@ public class Expression
return exc;
}
// unexpected really - should be caught earlier and converted to InternalExpressionException
CarpetSettings.LOG.error("Unexpected exception while running Scarpet code", exc);
CarpetScriptServer.LOG.error("Unexpected exception while running Scarpet code", exc);
return new ExpressionException(c, e, token, "Internal error (please report this issue to Carpet) while evaluating: " + exc);
}
@@ -1188,13 +1190,14 @@ public class Expression
final List<Tokenizer.Token> rpn = shuntingYard(context);
validate(context, rpn);
final ExpressionNode root = RPNToParseTree(rpn, context);
if (!CarpetSettings.scriptsOptimization)
if (!Vanilla.ScriptServer_scriptOptimizations(((CarpetScriptServer)context.scriptServer()).server))
{
return root.op;
}
final Context optimizeOnlyContext = new Context.ContextForErrorReporting(context);
if (CarpetSettings.scriptsDebugging)
final boolean scriptsDebugging = Vanilla.ScriptServer_scriptDebugging(((CarpetScriptServer)context.scriptServer()).server);
if (scriptsDebugging)
{
CarpetScriptServer.LOG.info("Input code size for " + getModuleName() + ": " + treeSize(root) + " nodes, " + treeDepth(root) + " deep");
}
@@ -1209,36 +1212,36 @@ public class Expression
changed = false;
while (true)
{
if (CarpetSettings.scriptsDebugging)
if (scriptsDebugging)
{
prevTreeSize = treeSize(root);
prevTreeDepth = treeDepth(root);
}
final boolean optimized = compactTree(root, Context.Type.NONE, 0);
final boolean optimized = compactTree(root, Context.Type.NONE, 0, scriptsDebugging);
if (!optimized)
{
break;
}
changed = true;
if (CarpetSettings.scriptsDebugging)
if (scriptsDebugging)
{
CarpetScriptServer.LOG.info("Compacted from " + prevTreeSize + " nodes, " + prevTreeDepth + " code depth to " + treeSize(root) + " nodes, " + treeDepth(root) + " code depth");
}
}
while (true)
{
if (CarpetSettings.scriptsDebugging)
if (scriptsDebugging)
{
prevTreeSize = treeSize(root);
prevTreeDepth = treeDepth(root);
}
final boolean optimized = optimizeTree(optimizeOnlyContext, root, Context.Type.NONE, 0);
final boolean optimized = optimizeTree(optimizeOnlyContext, root, Context.Type.NONE, 0, scriptsDebugging);
if (!optimized)
{
break;
}
changed = true;
if (CarpetSettings.scriptsDebugging)
if (scriptsDebugging)
{
CarpetScriptServer.LOG.info("Optimized from " + prevTreeSize + " nodes, " + prevTreeDepth + " code depth to " + treeSize(root) + " nodes, " + treeDepth(root) + " code depth");
}
@@ -1258,7 +1261,7 @@ public class Expression
}
private boolean compactTree(final ExpressionNode node, final Context.Type expectedType, final int indent)
private boolean compactTree(final ExpressionNode node, final Context.Type expectedType, final int indent, final boolean scriptsDebugging)
{
// ctx is just to report errors, not values evaluation
boolean optimized = false;
@@ -1278,7 +1281,7 @@ public class Expression
final Context.Type requestedType = operation.staticType(expectedType);
for (final ExpressionNode arg : node.args)
{
if (compactTree(arg, requestedType, indent + 1))
if (compactTree(arg, requestedType, indent + 1, scriptsDebugging))
{
optimized = true;
}
@@ -1308,7 +1311,7 @@ public class Expression
returnNode.token = returnNode.args.get(0).token;
returnNode.range = returnNode.args.get(0).range;
returnNode.args = returnNode.args.get(0).args;
if (CarpetSettings.scriptsDebugging)
if (scriptsDebugging)
{
CarpetScriptServer.LOG.info(" - Removed unnecessary tail return of " + returnNode.token.surface + " from function body at line " + (returnNode.token.lineno + 1) + ", node depth " + indent);
}
@@ -1318,7 +1321,7 @@ public class Expression
returnNode.op = LazyValue.ofConstant(Value.NULL);
returnNode.token.morph(Tokenizer.Token.TokenType.CONSTANT, "");
returnNode.args = Collections.emptyList();
if (CarpetSettings.scriptsDebugging)
if (scriptsDebugging)
{
CarpetScriptServer.LOG.info(" - Removed unnecessary tail return from function body at line " + (returnNode.token.lineno + 1) + ", node depth " + indent);
}
@@ -1356,7 +1359,7 @@ public class Expression
newargs.addAll(optimizedChild.args);
}
if (CarpetSettings.scriptsDebugging)
if (scriptsDebugging)
{
CarpetScriptServer.LOG.info(" - " + symbol + "(" + node.args.size() + ") => " + function + "(" + newargs.size() + ") at line " + (node.token.lineno + 1) + ", node depth " + indent);
}
@@ -1368,7 +1371,7 @@ public class Expression
return optimized;
}
private boolean optimizeTree(final Context ctx, final ExpressionNode node, Context.Type expectedType, final int indent)
private boolean optimizeTree(final Context ctx, final ExpressionNode node, Context.Type expectedType, final int indent, final boolean scriptsDebugging)
{
// ctx is just to report errors, not values evaluation
boolean optimized = false;
@@ -1390,7 +1393,7 @@ public class Expression
final Context.Type requestedType = operation.staticType(expectedType);
for (final ExpressionNode arg : node.args)
{
if (optimizeTree(ctx, arg, requestedType, indent + 1))
if (optimizeTree(ctx, arg, requestedType, indent + 1, scriptsDebugging))
{
optimized = true;
}
@@ -1457,7 +1460,7 @@ public class Expression
result = ((ILazyOperator) operation).lazyEval(ctx, expectedType, this, node.token, args.get(0), args.get(1)).evalValue(null, expectedType);
}
node.op = LazyValue.ofConstant(result);
if (CarpetSettings.scriptsDebugging)
if (scriptsDebugging)
{
CarpetScriptServer.LOG.info(" - " + symbol + "(" + args.stream().map(a -> a.evalValue(null, requestedType).getString()).collect(Collectors.joining(", ")) + ") => " + result.getString() + " at line " + (node.token.lineno + 1) + ", node depth " + indent);
}
+1 -2
View File
@@ -1,6 +1,5 @@
package carpet.script;
import carpet.CarpetSettings;
import carpet.script.exception.ExpressionException;
import carpet.script.exception.InternalExpressionException;
import carpet.script.value.FunctionUnpackedArgumentsValue;
@@ -218,7 +217,7 @@ public abstract class Fluff
}
else
{
CarpetSettings.LOG.error("How did we get here 1");
CarpetScriptServer.LOG.error("How did we get here 1");
}
return params;
}
+6 -9
View File
@@ -9,10 +9,8 @@ import java.util.Objects;
import org.apache.commons.io.IOUtils;
import carpet.CarpetServer;
import carpet.script.argument.FileArgument;
import net.minecraft.nbt.Tag;
import net.minecraft.world.level.storage.LevelResource;
public record Module(String name, String code, boolean library)
{
@@ -89,9 +87,9 @@ public record Module(String name, String code, boolean library)
}
}
public static Tag getData(final Module module)
public static Tag getData(final Module module, final ScriptServer scriptServer)
{
final Path dataFile = resolveResource(module);
final Path dataFile = resolveResource(module, scriptServer);
if (dataFile == null || !Files.exists(dataFile) || !(Files.isRegularFile(dataFile)))
{
return null;
@@ -102,9 +100,9 @@ public record Module(String name, String code, boolean library)
}
}
public static void saveData(final Module module, final Tag globalState)
public static void saveData(final Module module, final Tag globalState, final ScriptServer scriptServer)
{
final Path dataFile = resolveResource(module);
final Path dataFile = resolveResource(module, scriptServer);
if (dataFile == null)
{
return;
@@ -126,9 +124,8 @@ public record Module(String name, String code, boolean library)
}
}
private static Path resolveResource(final Module module)
private static Path resolveResource(final Module module, final ScriptServer scriptServer)
{
return module == null ? null : CarpetServer.minecraft_server.getWorldPath(LevelResource.ROOT).resolve("scripts/" + module.name() + ".data.nbt"); // commandline app
return module == null ? null : scriptServer.resolveResource(module.name() + ".data.nbt");
}
}
@@ -1,21 +1,11 @@
package carpet.commands;
package carpet.script;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.utils.AppStoreManager;
import carpet.script.CarpetEventServer;
import carpet.script.CarpetExpression;
import carpet.script.CarpetScriptHost;
import carpet.script.Expression;
import carpet.script.LazyValue;
import carpet.script.ScriptHost;
import carpet.script.Tokenizer;
import carpet.script.exception.CarpetExpressionException;
import carpet.script.value.FunctionValue;
import carpet.script.value.Value;
import carpet.utils.CarpetProfiler;
import carpet.utils.CommandHelper;
import carpet.utils.Messenger;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
@@ -24,7 +14,6 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.world.level.GameRules;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
@@ -39,6 +28,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.blocks.BlockInput;
import net.minecraft.commands.arguments.blocks.BlockPredicateArgument;
@@ -60,52 +50,67 @@ public class ScriptCommand
{
private static final TreeSet<String> scarpetFunctions;
private static final TreeSet<String> APIFunctions;
static
{
Set<String> allFunctions = (new CarpetExpression(null, "null", null, null)).getExpr().getFunctionNames();
final Set<String> allFunctions = (new CarpetExpression(null, "null", null, null)).getExpr().getFunctionNames();
scarpetFunctions = new TreeSet<>(Expression.none.getFunctionNames());
APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new));
}
public static List<String> suggestFunctions(ScriptHost host, String previous, String prefix)
public static List<String> suggestFunctions(final ScriptHost host, String previous, final String prefix)
{
previous = previous.replace("\\'", "");
int quoteCount = StringUtils.countMatches(previous,'\'');
final int quoteCount = StringUtils.countMatches(previous, '\'');
if (quoteCount % 2 == 1)
{
return Collections.emptyList();
int maxLen = prefix.length()<3 ? (prefix.length()*2+1) : 1234;
String eventPrefix = prefix.startsWith("__on_")?prefix.substring(5):null;
List<String> scarpetMatches = scarpetFunctions.stream().
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s+"(").collect(Collectors.toList());
}
final int maxLen = prefix.length() < 3 ? (prefix.length() * 2 + 1) : 1234;
final String eventPrefix = prefix.startsWith("__on_") ? prefix.substring(5) : null;
final List<String> scarpetMatches = scarpetFunctions.stream().
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s + "(").collect(Collectors.toList());
scarpetMatches.addAll(APIFunctions.stream().
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s+"(").collect(Collectors.toList()));
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s + "(").toList());
// not that useful in commandline, more so in external scripts, so skipping here
if (eventPrefix != null) scarpetMatches.addAll(CarpetEventServer.Event.publicEvents(null).stream().
filter(e -> e.name.startsWith(eventPrefix)).map(s -> "__on_"+s.name+"(").collect(Collectors.toList()));
scarpetMatches.addAll(host.globalFunctionNames(host.main, s -> s.startsWith(prefix)).map(s -> s+"(").collect(Collectors.toList()));
scarpetMatches.addAll(host.globalVariableNames(host.main, s -> s.startsWith(prefix)).collect(Collectors.toList()));
if (eventPrefix != null)
{
scarpetMatches.addAll(CarpetEventServer.Event.publicEvents(null).stream().
filter(e -> e.name.startsWith(eventPrefix)).map(s -> "__on_" + s.name + "(").toList());
}
scarpetMatches.addAll(host.globalFunctionNames(host.main, s -> s.startsWith(prefix)).map(s -> s + "(").toList());
scarpetMatches.addAll(host.globalVariableNames(host.main, s -> s.startsWith(prefix)).toList());
return scarpetMatches;
}
private static CompletableFuture<Suggestions> suggestCode(
CommandContext<CommandSourceStack> context,
SuggestionsBuilder suggestionsBuilder
final CommandContext<CommandSourceStack> context,
final SuggestionsBuilder suggestionsBuilder
) throws CommandSyntaxException
{
CarpetScriptHost currentHost = getHost(context);
String previous = suggestionsBuilder.getRemaining();
int strlen = previous.length();
StringBuilder lastToken = new StringBuilder();
for (int idx = strlen-1; idx >=0; idx--)
final CarpetScriptHost currentHost = getHost(context);
final String previous = suggestionsBuilder.getRemaining();
final int strlen = previous.length();
final StringBuilder lastToken = new StringBuilder();
for (int idx = strlen - 1; idx >= 0; idx--)
{
char ch = previous.charAt(idx);
if (Character.isLetterOrDigit(ch) || ch == '_') lastToken.append(ch); else break;
final char ch = previous.charAt(idx);
if (Character.isLetterOrDigit(ch) || ch == '_')
{
lastToken.append(ch);
}
else
{
break;
}
}
if (lastToken.length() == 0)
{
return suggestionsBuilder.buildFuture();
String prefix = lastToken.reverse().toString();
String previousString = previous.substring(0,previous.length()-prefix.length()) ;
suggestFunctions(currentHost, previousString, prefix).forEach(text -> suggestionsBuilder.suggest(previousString+text));
}
final String prefix = lastToken.reverse().toString();
final String previousString = previous.substring(0, previous.length() - prefix.length());
suggestFunctions(currentHost, previousString, prefix).forEach(text -> suggestionsBuilder.suggest(previousString + text));
return suggestionsBuilder.buildFuture();
}
@@ -114,59 +119,72 @@ public class ScriptCommand
* variable.
*/
private static CompletableFuture<Suggestions> suggestDownloadableApps(
CommandContext<CommandSourceStack> context,
SuggestionsBuilder suggestionsBuilder
) throws CommandSyntaxException {
return CompletableFuture.supplyAsync(()->{
String previous = suggestionsBuilder.getRemaining();
try {
final CommandContext<CommandSourceStack> context,
final SuggestionsBuilder suggestionsBuilder
) throws CommandSyntaxException
{
return CompletableFuture.supplyAsync(() -> {
final String previous = suggestionsBuilder.getRemaining();
try
{
AppStoreManager.suggestionsFromPath(previous).forEach(suggestionsBuilder::suggest);
}
catch (IOException e)
catch (final IOException e)
{
CarpetSettings.LOG.warn("Exception when fetching app store structure", e);
CarpetScriptServer.LOG.warn("Exception when fetching app store structure", e);
}
return suggestionsBuilder.build();
});
}
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, final CommandBuildContext commandBuildContext)
private static CarpetScriptServer ss(final CommandContext<CommandSourceStack> context)
{
LiteralArgumentBuilder<CommandSourceStack> b = literal("globals").
return Vanilla.MinecraftServer_getScriptServer(context.getSource().getServer());
}
public static void register(final CommandDispatcher<CommandSourceStack> dispatcher, final CommandBuildContext commandBuildContext)
{
final LiteralArgumentBuilder<CommandSourceStack> b = literal("globals").
executes(context -> listGlobals(context, false)).
then(literal("all").executes(context -> listGlobals(context, true)));
LiteralArgumentBuilder<CommandSourceStack> o = literal("stop").
executes( (cc) -> { CarpetServer.scriptServer.stopAll = true; return 1;});
LiteralArgumentBuilder<CommandSourceStack> u = literal("resume").
executes( (cc) -> { CarpetServer.scriptServer.stopAll = false; return 1;});
LiteralArgumentBuilder<CommandSourceStack> l = literal("run").
requires((player) -> CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE)).
final LiteralArgumentBuilder<CommandSourceStack> o = literal("stop").
executes((cc) -> {
ss(cc).stopAll = true;
return 1;
});
final LiteralArgumentBuilder<CommandSourceStack> u = literal("resume").
executes((cc) -> {
ss(cc).stopAll = false;
return 1;
});
final LiteralArgumentBuilder<CommandSourceStack> l = literal("run").
requires(Vanilla::ServerPlayer_canScriptACE).
then(argument("expr", StringArgumentType.greedyString()).suggests(ScriptCommand::suggestCode).
executes((cc) -> compute(
cc,
StringArgumentType.getString(cc, "expr"))));
LiteralArgumentBuilder<CommandSourceStack> s = literal("invoke").
then(argument("call", StringArgumentType.word()).suggests( (cc, bb)->suggest(suggestFunctionCalls(cc),bb)).
executes( (cc) -> invoke(
final LiteralArgumentBuilder<CommandSourceStack> s = literal("invoke").
then(argument("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
executes((cc) -> invoke(
cc,
StringArgumentType.getString(cc, "call"),
null,
null,
""
)) .
)).
then(argument("arguments", StringArgumentType.greedyString()).
executes( (cc) -> invoke(
executes((cc) -> invoke(
cc,
StringArgumentType.getString(cc, "call"),
null,
null,
StringArgumentType.getString(cc, "arguments")
))));
LiteralArgumentBuilder<CommandSourceStack> c = literal("invokepoint").
then(argument("call", StringArgumentType.word()).suggests( (cc, bb)->suggest(suggestFunctionCalls(cc),bb)).
final LiteralArgumentBuilder<CommandSourceStack> c = literal("invokepoint").
then(argument("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
then(argument("origin", BlockPosArgument.blockPos()).
executes( (cc) -> invoke(
executes((cc) -> invoke(
cc,
StringArgumentType.getString(cc, "call"),
BlockPosArgument.getSpawnablePos(cc, "origin"),
@@ -174,18 +192,18 @@ public class ScriptCommand
""
)).
then(argument("arguments", StringArgumentType.greedyString()).
executes( (cc) -> invoke(
executes((cc) -> invoke(
cc,
StringArgumentType.getString(cc, "call"),
BlockPosArgument.getSpawnablePos(cc, "origin"),
null,
StringArgumentType.getString(cc, "arguments")
)))));
LiteralArgumentBuilder<CommandSourceStack> h = literal("invokearea").
then(argument("call", StringArgumentType.word()).suggests( (cc, bb)->suggest(suggestFunctionCalls(cc),bb)).
final LiteralArgumentBuilder<CommandSourceStack> h = literal("invokearea").
then(argument("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
then(argument("from", BlockPosArgument.blockPos()).
then(argument("to", BlockPosArgument.blockPos()).
executes( (cc) -> invoke(
executes((cc) -> invoke(
cc,
StringArgumentType.getString(cc, "call"),
BlockPosArgument.getSpawnablePos(cc, "from"),
@@ -193,27 +211,27 @@ public class ScriptCommand
""
)).
then(argument("arguments", StringArgumentType.greedyString()).
executes( (cc) -> invoke(
executes((cc) -> invoke(
cc,
StringArgumentType.getString(cc, "call"),
BlockPosArgument.getSpawnablePos(cc, "from"),
BlockPosArgument.getSpawnablePos(cc, "to"),
StringArgumentType.getString(cc, "arguments")
))))));
LiteralArgumentBuilder<CommandSourceStack> i = literal("scan").requires((player) -> player.hasPermission(2)).
final LiteralArgumentBuilder<CommandSourceStack> i = literal("scan").requires((player) -> player.hasPermission(2)).
then(argument("origin", BlockPosArgument.blockPos()).
then(argument("from", BlockPosArgument.blockPos()).
then(argument("to", BlockPosArgument.blockPos()).
then(argument("expr", StringArgumentType.greedyString()).
suggests(ScriptCommand::suggestCode).
executes( (cc) -> scriptScan(
executes((cc) -> scriptScan(
cc,
BlockPosArgument.getSpawnablePos(cc, "origin"),
BlockPosArgument.getSpawnablePos(cc, "from"),
BlockPosArgument.getSpawnablePos(cc, "to"),
StringArgumentType.getString(cc, "expr")
))))));
LiteralArgumentBuilder<CommandSourceStack> e = literal("fill").requires((player) -> player.hasPermission(2)).
final LiteralArgumentBuilder<CommandSourceStack> e = literal("fill").requires((player) -> player.hasPermission(2)).
then(argument("origin", BlockPosArgument.blockPos()).
then(argument("from", BlockPosArgument.blockPos()).
then(argument("to", BlockPosArgument.blockPos()).
@@ -240,7 +258,7 @@ public class ScriptCommand
BlockPredicateArgument.getBlockPredicate(cc, "filter"),
"solid"
)))))))));
LiteralArgumentBuilder<CommandSourceStack> t = literal("outline").requires((player) -> player.hasPermission(2)).
final LiteralArgumentBuilder<CommandSourceStack> t = literal("outline").requires((player) -> player.hasPermission(2)).
then(argument("origin", BlockPosArgument.blockPos()).
then(argument("from", BlockPosArgument.blockPos()).
then(argument("to", BlockPosArgument.blockPos()).
@@ -267,179 +285,187 @@ public class ScriptCommand
BlockPredicateArgument.getBlockPredicate(cc, "filter"),
"outline"
)))))))));
LiteralArgumentBuilder<CommandSourceStack> a = literal("load").requires( (player) -> CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE) ).
final LiteralArgumentBuilder<CommandSourceStack> a = literal("load").requires(Vanilla::ServerPlayer_canScriptACE).
then(argument("app", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(CarpetServer.scriptServer.listAvailableModules(true),bb)).
suggests((cc, bb) -> suggest(ss(cc).listAvailableModules(true), bb)).
executes((cc) ->
{
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, true, false, false, null);
return success?1:0;
final boolean success = ss(cc).addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, true, false, false, null);
return success ? 1 : 0;
}).
then(literal("global").
executes((cc) ->
{
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, false, false, false, null);
return success?1:0;
}
{
final boolean success = ss(cc).addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, false, false, false, null);
return success ? 1 : 0;
}
)
)
);
LiteralArgumentBuilder<CommandSourceStack> f = literal("unload").requires( (player) -> CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE) ).
final LiteralArgumentBuilder<CommandSourceStack> f = literal("unload").requires(Vanilla::ServerPlayer_canScriptACE).
then(argument("app", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(CarpetServer.scriptServer.unloadableModules,bb)).
suggests((cc, bb) -> suggest(ss(cc).unloadableModules, bb)).
executes((cc) ->
{
boolean success =CarpetServer.scriptServer.removeScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), true, false);
return success?1:0;
final boolean success = ss(cc).removeScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), true, false);
return success ? 1 : 0;
}));
LiteralArgumentBuilder<CommandSourceStack> q = literal("event").requires( (player) -> CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE) ).
executes( (cc) -> listEvents(cc.getSource())).
final LiteralArgumentBuilder<CommandSourceStack> q = literal("event").requires(Vanilla::ServerPlayer_canScriptACE).
executes(ScriptCommand::listEvents).
then(literal("add_to").
then(argument("event", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(CarpetEventServer.Event.publicEvents(CarpetServer.scriptServer).stream().map(ev -> ev.name).collect(Collectors.toList()),bb)).
suggests((cc, bb) -> suggest(CarpetEventServer.Event.publicEvents(ss(cc)).stream().map(ev -> ev.name).collect(Collectors.toList()), bb)).
then(argument("call", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
executes( (cc) -> CarpetServer.scriptServer.events.addEventFromCommand(
suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
executes((cc) -> ss(cc).events.addEventFromCommand(
cc.getSource(),
StringArgumentType.getString(cc, "event"),
null,
StringArgumentType.getString(cc, "call")
)?1:0)).
) ? 1 : 0)).
then(literal("from").
then(argument("app", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(CarpetServer.scriptServer.modules.keySet(), bb)).
suggests((cc, bb) -> suggest(ss(cc).modules.keySet(), bb)).
then(argument("call", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
executes( (cc) -> CarpetServer.scriptServer.events.addEventFromCommand(
suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
executes((cc) -> ss(cc).events.addEventFromCommand(
cc.getSource(),
StringArgumentType.getString(cc, "event"),
StringArgumentType.getString(cc, "app"),
StringArgumentType.getString(cc, "call")
)?1:0)))))).
) ? 1 : 0)))))).
then(literal("remove_from").
then(argument("event", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(CarpetEventServer.Event.publicEvents(CarpetServer.scriptServer).stream().filter(CarpetEventServer.Event::isNeeded).map(ev -> ev.name).collect(Collectors.toList()) ,bb)).
suggests((cc, bb) -> suggest(CarpetEventServer.Event.publicEvents(ss(cc)).stream().filter(CarpetEventServer.Event::isNeeded).map(ev -> ev.name).collect(Collectors.toList()), bb)).
then(argument("call", StringArgumentType.greedyString()).
suggests( (cc, bb) -> suggest(CarpetEventServer.Event.getEvent(StringArgumentType.getString(cc, "event"), CarpetServer.scriptServer).handler.inspectCurrentCalls().stream().map(CarpetEventServer.Callback::toString), bb)).
executes( (cc) -> CarpetServer.scriptServer.events.removeEventFromCommand(
suggests((cc, bb) -> suggest(CarpetEventServer.Event.getEvent(StringArgumentType.getString(cc, "event"), ss(cc)).handler.inspectCurrentCalls().stream().map(CarpetEventServer.Callback::toString), bb)).
executes((cc) -> ss(cc).events.removeEventFromCommand(
cc.getSource(),
StringArgumentType.getString(cc, "event"),
StringArgumentType.getString(cc, "call")
)?1:0))));
) ? 1 : 0))));
LiteralArgumentBuilder<CommandSourceStack> d = literal("download").requires((player) -> CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE)).
final LiteralArgumentBuilder<CommandSourceStack> d = literal("download").requires(Vanilla::ServerPlayer_canScriptACE).
then(argument("path", StringArgumentType.greedyString()).
suggests(ScriptCommand::suggestDownloadableApps).
executes(cc-> AppStoreManager.downloadScript(cc.getSource(), StringArgumentType.getString(cc,"path"))));
LiteralArgumentBuilder<CommandSourceStack> r = literal("remove").requires( (player) -> CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE) ).
executes(cc -> AppStoreManager.downloadScript(cc.getSource(), StringArgumentType.getString(cc, "path"))));
final LiteralArgumentBuilder<CommandSourceStack> r = literal("remove").requires(Vanilla::ServerPlayer_canScriptACE).
then(argument("app", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(CarpetServer.scriptServer.unloadableModules,bb)).
suggests((cc, bb) -> suggest(ss(cc).unloadableModules, bb)).
executes((cc) ->
{
boolean success =CarpetServer.scriptServer.uninstallApp(cc.getSource(), StringArgumentType.getString(cc, "app"));
return success?1:0;
final boolean success = ss(cc).uninstallApp(cc.getSource(), StringArgumentType.getString(cc, "app"));
return success ? 1 : 0;
}));
dispatcher.register(literal("script").
requires((player) -> CommandHelper.canUseCommand(player, CarpetSettings.commandScript)).
requires(Vanilla::ServerPlayer_canScriptGeneral).
then(b).then(u).then(o).then(l).then(s).then(c).then(h).then(i).then(e).then(t).then(a).then(f).then(q).then(d).then(r));
dispatcher.register(literal("script").
requires((player) -> CommandHelper.canUseCommand(player, CarpetSettings.commandScript)).
requires(Vanilla::ServerPlayer_canScriptGeneral).
then(literal("in").
then(argument("app", StringArgumentType.word()).
suggests( (cc, bb) -> suggest(CarpetServer.scriptServer.modules.keySet(), bb)).
suggests((cc, bb) -> suggest(ss(cc).modules.keySet(), bb)).
then(b).then(u).then(o).then(l).then(s).then(c).then(h).then(i).then(e).then(t))));
}
private static CarpetScriptHost getHost(CommandContext<CommandSourceStack> context) throws CommandSyntaxException
private static CarpetScriptHost getHost(final CommandContext<CommandSourceStack> context) throws CommandSyntaxException
{
CarpetScriptHost host;
final CarpetScriptServer scriptServer = ss(context);
try
{
String name = StringArgumentType.getString(context, "app").toLowerCase(Locale.ROOT);
CarpetScriptHost parentHost = CarpetServer.scriptServer.modules.getOrDefault(name, CarpetServer.scriptServer.globalHost);
host = parentHost.retrieveOwnForExecution(context.getSource());
final String name = StringArgumentType.getString(context, "app").toLowerCase(Locale.ROOT);
final CarpetScriptHost parentHost = scriptServer.modules.getOrDefault(name, scriptServer.globalHost);
host = parentHost.retrieveOwnForExecution(context.getSource());
}
catch (IllegalArgumentException ignored)
catch (final IllegalArgumentException ignored)
{
host = CarpetServer.scriptServer.globalHost;
host = scriptServer.globalHost;
}
host.setChatErrorSnooper(context.getSource());
return host;
}
private static Collection<String> suggestFunctionCalls(CommandContext<CommandSourceStack> c) throws CommandSyntaxException
private static Collection<String> suggestFunctionCalls(final CommandContext<CommandSourceStack> c) throws CommandSyntaxException
{
CarpetScriptHost host = getHost(c);
return host.globalFunctionNames(host.main, s -> !s.startsWith("_")).sorted().collect(Collectors.toList());
final CarpetScriptHost host = getHost(c);
return host.globalFunctionNames(host.main, s -> !s.startsWith("_")).sorted().collect(Collectors.toList());
}
private static int listEvents(CommandSourceStack source)
private static int listEvents(final CommandContext<CommandSourceStack> context)
{
Messenger.m(source, "w Lists ALL event handlers:");
for (CarpetEventServer.Event event: CarpetEventServer.Event.getAllEvents(CarpetServer.scriptServer, null))
CarpetScriptServer scriptServer = ss(context);
CommandSourceStack source = context.getSource();
Carpet.Messenger_message(source, "w Lists ALL event handlers:");
for (final CarpetEventServer.Event event : CarpetEventServer.Event.getAllEvents(scriptServer, null))
{
boolean shownEvent = false;
for (CarpetEventServer.Callback c: event.handler.inspectCurrentCalls())
for (final CarpetEventServer.Callback c : event.handler.inspectCurrentCalls())
{
if (!shownEvent)
{
Messenger.m(source, "w Handlers for "+event.name+": ");
Carpet.Messenger_message(source, "w Handlers for " + event.name + ": ");
shownEvent = true;
}
Messenger.m(source, "w - "+c.function.getString() +(c.host==null?"":" (from "+c.host+")"));
Carpet.Messenger_message(source, "w - " + c.function.getString() + (c.host == null ? "" : " (from " + c.host + ")"));
}
}
return 1;
}
private static int listGlobals(CommandContext<CommandSourceStack> context, boolean all) throws CommandSyntaxException
{
CarpetScriptHost host = getHost(context);
CommandSourceStack source = context.getSource();
Messenger.m(source, "lb Stored functions"+((host == CarpetServer.scriptServer.globalHost)?":":" in "+host.getName()+":"));
host.globalFunctionNames(host.main, (str) -> all || !str.startsWith("__")).sorted().forEach( (s) -> {
FunctionValue fun = host.getFunction(s);
private static int listGlobals(final CommandContext<CommandSourceStack> context, final boolean all) throws CommandSyntaxException
{
final CarpetScriptHost host = getHost(context);
final CommandSourceStack source = context.getSource();
final CarpetScriptServer scriptServer = ss(context);
Carpet.Messenger_message(source, "lb Stored functions" + ((host == scriptServer.globalHost) ? ":" : " in " + host.getName() + ":"));
host.globalFunctionNames(host.main, (str) -> all || !str.startsWith("__")).sorted().forEach((s) -> {
final FunctionValue fun = host.getFunction(s);
if (fun == null)
{
Messenger.m(source, "gb "+s, "g - unused import");
Messenger.m(source, "gi ----------------");
Carpet.Messenger_message(source, "gb " + s, "g - unused import");
Carpet.Messenger_message(source, "gi ----------------");
return;
}
Expression expr = fun.getExpression();
Tokenizer.Token tok = fun.getToken();
List<String> snippet = expr.getExpressionSnippet(tok);
Messenger.m(source, "wb "+fun.fullName(),"t defined at: line "+(tok.lineno+1)+" pos "+(tok.linepos+1));
for (String snippetLine: snippet)
final Expression expr = fun.getExpression();
final Tokenizer.Token tok = fun.getToken();
final List<String> snippet = expr.getExpressionSnippet(tok);
Carpet.Messenger_message(source, "wb " + fun.fullName(), "t defined at: line " + (tok.lineno + 1) + " pos " + (tok.linepos + 1));
for (final String snippetLine : snippet)
{
Messenger.m(source, "w "+snippetLine);
Carpet.Messenger_message(source, "w " + snippetLine);
}
Messenger.m(source, "gi ----------------");
Carpet.Messenger_message(source, "gi ----------------");
});
//Messenger.m(source, "w "+code);
Messenger.m(source, "w ");
Messenger.m(source, "lb Global variables"+((host == CarpetServer.scriptServer.globalHost)?":":" in "+host.getName()+":"));
host.globalVariableNames(host.main, (s) -> s.startsWith("global_")).sorted().forEach( (s) -> {
LazyValue variable = host.getGlobalVariable(s);
Carpet.Messenger_message(source, "w ");
Carpet.Messenger_message(source, "lb Global variables" + ((host == scriptServer.globalHost) ? ":" : " in " + host.getName() + ":"));
host.globalVariableNames(host.main, (s) -> s.startsWith("global_")).sorted().forEach((s) -> {
final LazyValue variable = host.getGlobalVariable(s);
if (variable == null)
{
Messenger.m(source, "gb "+s, "g - unused import");
Carpet.Messenger_message(source, "gb " + s, "g - unused import");
}
else
{
Messenger.m(source, "wb "+s+": ", "w "+ variable.evalValue(null).getPrettyString());
Carpet.Messenger_message(source, "wb " + s + ": ", "w " + variable.evalValue(null).getPrettyString());
}
});
return 1;
}
public static int handleCall(CommandSourceStack source, CarpetScriptHost host, Supplier<Value> call)
public static int handleCall(final CommandSourceStack source, final CarpetScriptHost host, final Supplier<Value> call)
{
try
{
CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet run", CarpetProfiler.TYPE.GENERAL);
final Runnable token = Carpet.startProfilerSection("Scarpet run");
host.setChatErrorSnooper(source);
long start = System.nanoTime();
Value result = call.get();
long time = ((System.nanoTime()-start)/1000);
final long start = System.nanoTime();
final Value result = call.get();
long time = ((System.nanoTime() - start) / 1000);
String metric = "\u00B5s";
if (time > 5000)
{
@@ -451,20 +477,20 @@ public class ScriptCommand
time /= 1000;
metric = "s";
}
Messenger.m(source, "wi = ", "wb "+result.getString(), "gi ("+time+metric+")");
int intres = (int)result.readInteger();
CarpetProfiler.end_current_section(currentSection);
Carpet.Messenger_message(source, "wi = ", "wb " + result.getString(), "gi (" + time + metric + ")");
final int intres = (int) result.readInteger();
token.run();
return intres;
}
catch (CarpetExpressionException e)
catch (final CarpetExpressionException e)
{
host.handleErrorWithStack("Error while evaluating expression", e);
}
catch (ArithmeticException ae)
catch (final ArithmeticException ae)
{
host.handleErrorWithStack("Math doesn't compute", ae);
}
catch (StackOverflowError soe)
catch (final StackOverflowError soe)
{
host.handleErrorWithStack("Your thoughts are too deep", soe);
}
@@ -472,16 +498,16 @@ public class ScriptCommand
//host.resetErrorSnooper(); // lets say no need to reset the snooper in case something happens on the way
}
private static int invoke(CommandContext<CommandSourceStack> context, String call, BlockPos pos1, BlockPos pos2, String args) throws CommandSyntaxException
private static int invoke(final CommandContext<CommandSourceStack> context, final String call, final BlockPos pos1, final BlockPos pos2, final String args) throws CommandSyntaxException
{
CommandSourceStack source = context.getSource();
CarpetScriptHost host = getHost(context);
final CommandSourceStack source = context.getSource();
final CarpetScriptHost host = getHost(context);
if (call.startsWith("__"))
{
Messenger.m(source, "r Hidden functions are only callable in scripts");
Carpet.Messenger_message(source, "r Hidden functions are only callable in scripts");
return 0;
}
List<Integer> positions = new ArrayList<>();
final List<Integer> positions = new ArrayList<>();
if (pos1 != null)
{
positions.add(pos1.getX());
@@ -496,34 +522,34 @@ public class ScriptCommand
}
//if (!(args.trim().isEmpty()))
// arguments.addAll(Arrays.asList(args.trim().split("\\s+")));
return handleCall(source, host, () -> host.callLegacy(source, call, positions, args));
return handleCall(source, host, () -> host.callLegacy(source, call, positions, args));
}
private static int compute(CommandContext<CommandSourceStack> context, String expr) throws CommandSyntaxException
private static int compute(final CommandContext<CommandSourceStack> context, final String expr) throws CommandSyntaxException
{
CommandSourceStack source = context.getSource();
CarpetScriptHost host = getHost(context);
final CommandSourceStack source = context.getSource();
final CarpetScriptHost host = getHost(context);
return handleCall(source, host, () -> {
CarpetExpression ex = new CarpetExpression(host.main, expr, source, new BlockPos(0, 0, 0));
final CarpetExpression ex = new CarpetExpression(host.main, expr, source, new BlockPos(0, 0, 0));
return ex.scriptRunCommand(host, new BlockPos(source.getPosition()));
});
}
private static int scriptScan(CommandContext<CommandSourceStack> context, BlockPos origin, BlockPos a, BlockPos b, String expr) throws CommandSyntaxException
private static int scriptScan(final CommandContext<CommandSourceStack> context, final BlockPos origin, final BlockPos a, final BlockPos b, final String expr) throws CommandSyntaxException
{
CommandSourceStack source = context.getSource();
CarpetScriptHost host = getHost(context);
BoundingBox area = BoundingBox.fromCorners(a, b);
CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan(); // X Y Z
if (int_1 > Math.max(source.getServer().getGameRules().getInt(GameRules.RULE_COMMAND_MODIFICATION_BLOCK_LIMIT), CarpetSettings.fillLimit))
final CommandSourceStack source = context.getSource();
final CarpetScriptHost host = getHost(context);
final BoundingBox area = BoundingBox.fromCorners(a, b);
final CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
final int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan(); // X Y Z
if (int_1 > Vanilla.MinecraftServer_getFillLimit(source.getServer()) )
{
Messenger.m(source, "r too many blocks to evaluate: " + int_1);
Carpet.Messenger_message(source, "r too many blocks to evaluate: " + int_1);
return 1;
}
int successCount = 0;
CarpetSettings.impendingFillSkipUpdates.set(!CarpetSettings.fillUpdates);
Carpet.getImpendingFillSkipUpdates().set(!Carpet.getFillUpdates());
try
{
for (int x = area.minX(); x <= area.maxX(); x++)
@@ -534,48 +560,51 @@ public class ScriptCommand
{
try
{
if (cexpr.fillAndScanCommand(host, x, y, z)) successCount++;
if (cexpr.fillAndScanCommand(host, x, y, z))
{
successCount++;
}
}
catch (ArithmeticException ignored)
catch (final ArithmeticException ignored)
{
}
}
}
}
}
catch (CarpetExpressionException exc)
catch (final CarpetExpressionException exc)
{
host.handleErrorWithStack("Error while processing command", exc);
return 0;
}
finally
{
CarpetSettings.impendingFillSkipUpdates.set(false);
Carpet.getImpendingFillSkipUpdates().set(false);
}
Messenger.m(source, "w Expression successful in " + successCount + " out of " + int_1 + " blocks");
Carpet.Messenger_message(source, "w Expression successful in " + successCount + " out of " + int_1 + " blocks");
return successCount;
}
private static int scriptFill(CommandContext<CommandSourceStack> context, BlockPos origin, BlockPos a, BlockPos b, String expr,
BlockInput block, Predicate<BlockInWorld> replacement, String mode) throws CommandSyntaxException
private static int scriptFill(final CommandContext<CommandSourceStack> context, final BlockPos origin, final BlockPos a, final BlockPos b, final String expr,
final BlockInput block, final Predicate<BlockInWorld> replacement, final String mode) throws CommandSyntaxException
{
CommandSourceStack source = context.getSource();
CarpetScriptHost host = getHost(context);
BoundingBox area = BoundingBox.fromCorners(a, b);
CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan();
if (int_1 > Math.max(source.getServer().getGameRules().getInt(GameRules.RULE_COMMAND_MODIFICATION_BLOCK_LIMIT), CarpetSettings.fillLimit))
final CommandSourceStack source = context.getSource();
final CarpetScriptHost host = getHost(context);
final BoundingBox area = BoundingBox.fromCorners(a, b);
final CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
final int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan();
if (int_1 > Vanilla.MinecraftServer_getFillLimit(source.getServer()))
{
Messenger.m(source, "r too many blocks to evaluate: "+ int_1);
Carpet.Messenger_message(source, "r too many blocks to evaluate: " + int_1);
return 1;
}
boolean[][][] volume = new boolean[area.getXSpan()][area.getYSpan()][area.getZSpan()]; //X then Y then Z got messedup
BlockPos.MutableBlockPos mbpos = origin.mutable();
ServerLevel world = source.getLevel();
final BlockPos.MutableBlockPos mbpos = origin.mutable();
final ServerLevel world = source.getLevel();
for (int x = area.minX(); x <= area.maxX(); x++)
{
@@ -587,26 +616,26 @@ public class ScriptCommand
{
if (cexpr.fillAndScanCommand(host, x, y, z))
{
volume[x-area.minX()][y-area.minY()][z-area.minZ()]=true;
volume[x - area.minX()][y - area.minY()][z - area.minZ()] = true;
}
}
catch (CarpetExpressionException e)
catch (final CarpetExpressionException e)
{
host.handleErrorWithStack("Exception while filling the area", e);
return 0;
}
catch (ArithmeticException e)
catch (final ArithmeticException e)
{
}
}
}
}
final int maxx = area.getXSpan()-1;
final int maxy = area.getYSpan()-1;
final int maxz = area.getZSpan()-1;
final int maxx = area.getXSpan() - 1;
final int maxy = area.getYSpan() - 1;
final int maxz = area.getZSpan() - 1;
if ("outline".equalsIgnoreCase(mode))
{
boolean[][][] newVolume = new boolean[area.getXSpan()][area.getYSpan()][area.getZSpan()];
final boolean[][][] newVolume = new boolean[area.getXSpan()][area.getYSpan()][area.getZSpan()];
for (int x = 0; x <= maxx; x++)
{
for (int y = 0; y <= maxy; y++)
@@ -615,12 +644,12 @@ public class ScriptCommand
{
if (volume[x][y][z])
{
if ( ( (x != 0 && !volume[x-1][y ][z ]) ||
(x != maxx && !volume[x+1][y ][z ]) ||
(y != 0 && !volume[x ][y-1][z ]) ||
(y != maxy && !volume[x ][y+1][z ]) ||
(z != 0 && !volume[x ][y ][z-1]) ||
(z != maxz && !volume[x ][y ][z+1])
if (((x != 0 && !volume[x - 1][y][z]) ||
(x != maxx && !volume[x + 1][y][z]) ||
(y != 0 && !volume[x][y - 1][z]) ||
(y != maxy && !volume[x][y + 1][z]) ||
(z != 0 && !volume[x][y][z - 1]) ||
(z != maxz && !volume[x][y][z + 1])
))
{
newVolume[x][y][z] = true;
@@ -633,7 +662,7 @@ public class ScriptCommand
}
int affected = 0;
CarpetSettings.impendingFillSkipUpdates.set(!CarpetSettings.fillUpdates);
Carpet.getImpendingFillSkipUpdates().set(!Carpet.getFillUpdates());
for (int x = 0; x <= maxx; x++)
{
for (int y = 0; y <= maxy; y++)
@@ -642,14 +671,14 @@ public class ScriptCommand
{
if (volume[x][y][z])
{
mbpos.set(x+area.minX(), y+area.minY(), z+area.minZ());
mbpos.set(x + area.minX(), y + area.minY(), z + area.minZ());
if (replacement == null || replacement.test(
new BlockInWorld( world, mbpos, true)))
new BlockInWorld(world, mbpos, true)))
{
BlockEntity tileentity = world.getBlockEntity(mbpos);
final BlockEntity tileentity = world.getBlockEntity(mbpos);
Clearable.tryClear(tileentity);
if (block.place(world, mbpos,2))
if (block.place(world, mbpos, 2))
{
++affected;
}
@@ -658,9 +687,9 @@ public class ScriptCommand
}
}
}
CarpetSettings.impendingFillSkipUpdates.set(false);
Carpet.getImpendingFillSkipUpdates().set(false);
if (CarpetSettings.fillUpdates && block != null)
if (Carpet.getFillUpdates() && block != null)
{
for (int x = 0; x <= maxx; x++)
{
@@ -670,15 +699,15 @@ public class ScriptCommand
{
if (volume[x][y][z])
{
mbpos.set(x+area.minX(), y+area.minY(), z+area.minZ());
Block blokc = world.getBlockState(mbpos).getBlock();
mbpos.set(x + area.minX(), y + area.minY(), z + area.minZ());
final Block blokc = world.getBlockState(mbpos).getBlock();
world.blockUpdated(mbpos, blokc);
}
}
}
}
}
Messenger.m(source, "gi Affected "+affected+" blocks in "+area.getXSpan() * area.getYSpan() * area.getZSpan()+" block volume");
Carpet.Messenger_message(source, "gi Affected " + affected + " blocks in " + area.getXSpan() * area.getYSpan() * area.getZSpan() + " block volume");
return 1;
}
}
@@ -10,6 +10,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -52,6 +53,11 @@ public abstract class ScriptHost
return randomizers.remove(aLong) != null;
}
public Path resolveScriptFile(final String suffix)
{
return scriptServer.resolveResource(suffix);
}
public static class ModuleData
{
Module parent;
@@ -1,12 +1,15 @@
package carpet.script;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import carpet.script.value.Value;
// WIP
public class ScriptServer
public abstract class ScriptServer
{
public final Map<Value, Value> systemGlobals = new ConcurrentHashMap<>();
public abstract Path resolveResource(final String suffix);
}
+27 -30
View File
@@ -1,10 +1,7 @@
package carpet.script.api;
import carpet.CarpetServer;
import carpet.fakes.MinecraftServerInterface;
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
import carpet.helpers.FeatureGenerator;
import carpet.logging.HUDController;
import carpet.script.external.Vanilla;
import carpet.script.utils.FeatureGenerator;
import carpet.script.argument.FileArgument;
import carpet.script.CarpetContext;
import carpet.script.CarpetEventServer;
@@ -19,6 +16,7 @@ import carpet.script.exception.ExitStatement;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.external.Carpet;
import carpet.script.utils.SnoopyCommandSource;
import carpet.script.utils.SystemInfo;
import carpet.script.utils.InputValidator;
@@ -36,7 +34,6 @@ import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.utils.Messenger;
import com.google.common.collect.Lists;
import net.minecraft.SharedConstants;
import net.minecraft.commands.CommandSourceStack;
@@ -73,7 +70,6 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.decoration.ArmorStand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
@@ -613,11 +609,11 @@ public class Auxiliary
final Map<String, Component> map;
if (actionString.equals("player_list_header"))
{
map = HUDController.scarpet_headers;
map = Carpet.getScarpetHeaders();
}
else
{
map = HUDController.scarpet_footers;
map = Carpet.getScarpetFooters();
}
final AtomicInteger total = new AtomicInteger(0);
@@ -636,7 +632,7 @@ public class Auxiliary
total.getAndIncrement();
});
}
HUDController.update_hud(((CarpetContext) c).server(), targetList);
Carpet.updateScarpetHUDs(((CarpetContext) c).server(), targetList);
return NumericValue.of(total.get());
}
final ClientboundSetTitlesAnimationPacket timesPacket; // TimesPacket
@@ -678,7 +674,7 @@ public class Auxiliary
{
values = list.getItems();
}
return new FormattedTextValue(Messenger.c(values.stream().map(Value::getString).toArray()));
return new FormattedTextValue(Carpet.Messenger_compose(values.stream().map(Value::getString).toArray()));
});
expression.addContextFunction("run", 1, (c, t, lv) ->
@@ -750,7 +746,8 @@ public class Auxiliary
expression.addContextFunction("game_tick", -1, (c, t, lv) -> {
final CarpetContext cc = (CarpetContext) c;
final MinecraftServer server = cc.server();
if (CarpetServer.scriptServer == null)
final CarpetScriptServer scriptServer = (CarpetScriptServer) c.host.scriptServer();
if (scriptServer == null)
{
return Value.NULL;
}
@@ -758,18 +755,18 @@ public class Auxiliary
{
throw new InternalExpressionException("Unable to run ticks from threads");
}
if (CarpetServer.scriptServer.tickDepth > 16)
if (scriptServer.tickDepth > 16)
{
throw new InternalExpressionException("'game_tick' function caused other 'game_tick' functions to run. You should not allow that.");
}
try
{
CarpetServer.scriptServer.tickDepth++;
((MinecraftServerInterface) server).forceTick(() -> System.nanoTime() - CarpetServer.scriptServer.tickStart < 50000000L);
scriptServer.tickDepth++;
Vanilla.MinecraftServer_forceTick(server, () -> System.nanoTime() - scriptServer.tickStart < 50000000L);
if (lv.size() > 0)
{
final long ms_total = NumericValue.asNumber(lv.get(0)).getLong();
final long end_expected = CarpetServer.scriptServer.tickStart + ms_total * 1000000L;
final long end_expected = scriptServer.tickStart + ms_total * 1000000L;
final long wait = end_expected - System.nanoTime();
if (wait > 0L)
{
@@ -782,17 +779,17 @@ public class Auxiliary
}
}
}
CarpetServer.scriptServer.tickStart = System.nanoTime(); // for the next tick
scriptServer.tickStart = System.nanoTime(); // for the next tick
Thread.yield();
}
finally
{
if (CarpetServer.scriptServer != null)
if (scriptServer != null)
{
CarpetServer.scriptServer.tickDepth--;
scriptServer.tickDepth--;
}
}
if (CarpetServer.scriptServer != null && CarpetServer.scriptServer.stopAll)
if (scriptServer != null && scriptServer.stopAll)
{
throw new ExitStatement(Value.NULL);
}
@@ -811,7 +808,7 @@ public class Auxiliary
final BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
final BlockPos pos = locator.block.getPos();
final ServerLevel world = cc.level();
((ThreadedAnvilChunkStorageInterface) world.getChunkSource().chunkMap).relightChunk(new ChunkPos(pos));
Vanilla.ChunkMap_relightChunk(world.getChunkSource().chunkMap, new ChunkPos(pos));
WorldTools.forceChunkUpdate(pos, world);
return Value.TRUE;
});
@@ -896,7 +893,7 @@ public class Auxiliary
final long delay = NumericValue.asNumber(lv.get(0)).getLong();
final FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, false);
CarpetServer.scriptServer.events.scheduleCall(
((CarpetScriptServer)c.host.scriptServer()).events.scheduleCall(
(CarpetContext) c,
functionArgument.function,
functionArgument.checkedArgs(),
@@ -938,14 +935,14 @@ public class Auxiliary
expression.addContextFunction("list_files", 2, (c, t, lv) ->
{
final FileArgument fdesc = FileArgument.from(lv, true, FileArgument.Reason.READ);
final FileArgument fdesc = FileArgument.from(c, lv, true, FileArgument.Reason.READ);
final Stream<String> files = ((CarpetScriptHost) c.host).listFolder(fdesc);
return files == null ? Value.NULL : ListValue.wrap(files.map(StringValue::of));
});
expression.addContextFunction("read_file", 2, (c, t, lv) ->
{
final FileArgument fdesc = FileArgument.from(lv, false, FileArgument.Reason.READ);
final FileArgument fdesc = FileArgument.from(c, lv, false, FileArgument.Reason.READ);
if (fdesc.type == FileArgument.Type.NBT)
{
final Tag state = ((CarpetScriptHost) c.host).readFileTag(fdesc);
@@ -966,14 +963,14 @@ public class Auxiliary
});
expression.addContextFunction("delete_file", 2, (c, t, lv) ->
BooleanValue.of(((CarpetScriptHost) c.host).removeResourceFile(FileArgument.from(lv, false, FileArgument.Reason.DELETE))));
BooleanValue.of(((CarpetScriptHost) c.host).removeResourceFile(FileArgument.from(c, lv, false, FileArgument.Reason.DELETE))));
expression.addContextFunction("write_file", -1, (c, t, lv) -> {
if (lv.size() < 3)
{
throw new InternalExpressionException("'write_file' requires three or more arguments");
}
final FileArgument fdesc = FileArgument.from(lv, false, FileArgument.Reason.CREATE);
final FileArgument fdesc = FileArgument.from(c, lv, false, FileArgument.Reason.CREATE);
final boolean success;
if (fdesc.type == FileArgument.Type.NBT)
@@ -1021,13 +1018,13 @@ public class Auxiliary
expression.addContextFunction("load_app_data", -1, (c, t, lv) ->
{
FileArgument fdesc = new FileArgument(null, FileArgument.Type.NBT, null, false, false, FileArgument.Reason.READ);
FileArgument fdesc = new FileArgument(null, FileArgument.Type.NBT, null, false, false, FileArgument.Reason.READ, c.host);
if (lv.size() > 0)
{
c.host.issueDeprecation("load_app_data(...) with arguments");
final String resource = recognizeResource(lv.get(0), false);
final boolean shared = lv.size() > 1 && lv.get(1).getBoolean();
fdesc = new FileArgument(resource, FileArgument.Type.NBT, null, false, shared, FileArgument.Reason.READ);
fdesc = new FileArgument(resource, FileArgument.Type.NBT, null, false, shared, FileArgument.Reason.READ, c.host);
}
return NBTSerializableValue.of(((CarpetScriptHost) c.host).readFileTag(fdesc));
});
@@ -1039,13 +1036,13 @@ public class Auxiliary
throw new InternalExpressionException("'store_app_data' needs NBT tag and an optional file");
}
final Value val = lv.get(0);
FileArgument fdesc = new FileArgument(null, FileArgument.Type.NBT, null, false, false, FileArgument.Reason.CREATE);
FileArgument fdesc = new FileArgument(null, FileArgument.Type.NBT, null, false, false, FileArgument.Reason.CREATE, c.host);
if (lv.size() > 1)
{
c.host.issueDeprecation("store_app_data(...) with more than one argument");
final String resource = recognizeResource(lv.get(1), false);
final boolean shared = lv.size() > 2 && lv.get(2).getBoolean();
fdesc = new FileArgument(resource, FileArgument.Type.NBT, null, false, shared, FileArgument.Reason.CREATE);
fdesc = new FileArgument(resource, FileArgument.Type.NBT, null, false, shared, FileArgument.Reason.CREATE, c.host);
}
final NBTSerializableValue tagValue = (val instanceof final NBTSerializableValue nbtsv)
? nbtsv
@@ -1,13 +1,12 @@
package carpet.script.api;
import carpet.fakes.IngredientInterface;
import carpet.fakes.RecipeManagerInterface;
import carpet.script.CarpetContext;
import carpet.script.Expression;
import carpet.script.argument.FunctionArgument;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.external.Vanilla;
import carpet.script.utils.InputValidator;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
@@ -111,7 +110,7 @@ public class Inventories
final String recipeType = lv.get(1).getString();
type = cc.registry(Registries.RECIPE_TYPE).get(InputValidator.identifierOf(recipeType));
}
final List<Recipe<?>> recipes = ((RecipeManagerInterface) cc.server().getRecipeManager()).getAllMatching(type, InputValidator.identifierOf(recipeName), cc.registryAccess());
final List<Recipe<?>> recipes = Vanilla.RecipeManager_getAllMatching(cc.server().getRecipeManager(), type, InputValidator.identifierOf(recipeName), cc.registryAccess());
if (recipes.isEmpty())
{
return Value.NULL;
@@ -126,7 +125,7 @@ public class Inventories
// I am flattening ingredient lists per slot.
// consider recipe_data('wooden_sword','crafting') and ('iron_nugget', 'blasting') and notice difference
// in depths of lists.
final List<Collection<ItemStack>> stacks = ((IngredientInterface) (Object) ingredient).getRecipeStacks();
final List<Collection<ItemStack>> stacks = Vanilla.Ingredient_getRecipeStacks(ingredient);
if (stacks.isEmpty())
{
ingredientValue.add(Value.NULL);
@@ -3,13 +3,13 @@ package carpet.script.api;
import carpet.script.CarpetContext;
import carpet.script.Expression;
import carpet.script.exception.InternalExpressionException;
import carpet.script.external.Vanilla;
import carpet.script.utils.SystemInfo;
import carpet.script.value.ListValue;
import carpet.script.value.MapValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.utils.SpawnReporter;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import java.util.Arrays;
@@ -64,7 +64,7 @@ public class Monitoring
final Map<Value, Value> retDict = new HashMap<>();
for (final MobCategory category : mobcounts.keySet())
{
final int currentCap = category.getMaxInstancesPerChunk() * chunks / SpawnReporter.MAGIC_NUMBER;
final int currentCap = category.getMaxInstancesPerChunk() * chunks / Vanilla.NaturalSpawner_MAGIC_NUMBER();
retDict.put(
new StringValue(category.getSerializedName().toLowerCase(Locale.ROOT)),
ListValue.of(
@@ -82,7 +82,7 @@ public class Monitoring
}
return ListValue.of(
new NumericValue(mobcounts.getInt(cat)),
new NumericValue((int) (cat.getMaxInstancesPerChunk() * chunks / SpawnReporter.MAGIC_NUMBER))
new NumericValue((int) (cat.getMaxInstancesPerChunk() * chunks / Vanilla.NaturalSpawner_MAGIC_NUMBER()))
);
});
}
@@ -1,12 +1,11 @@
package carpet.script.api;
import carpet.mixins.Objective_scarpetMixin;
import carpet.mixins.Scoreboard_scarpetMixin;
import carpet.script.CarpetContext;
import carpet.script.Expression;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.external.Vanilla;
import carpet.script.utils.InputValidator;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
@@ -164,9 +163,9 @@ public class Scoreboards
{
return Value.NULL;
}
((Scoreboard_scarpetMixin) scoreboard).getObjectivesByCriterion().get(objective.getCriteria()).remove(objective);
((Objective_scarpetMixin) objective).setCriterion(criterion);
(((Scoreboard_scarpetMixin) scoreboard).getObjectivesByCriterion().computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
Vanilla.Objective_setCriterion(objective, criterion);
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
scoreboard.onObjectiveAdded(objective);
return Value.FALSE;
}
@@ -209,9 +208,9 @@ public class Scoreboards
{
return Value.FALSE;
}
((Scoreboard_scarpetMixin) scoreboard).getObjectivesByCriterion().get(objective.getCriteria()).remove(objective);
((Objective_scarpetMixin) objective).setCriterion(criterion);
(((Scoreboard_scarpetMixin) scoreboard).getObjectivesByCriterion().computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
Vanilla.Objective_setCriterion(objective, criterion);
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
scoreboard.onObjectiveAdded(objective);
return Value.TRUE;
}
@@ -1,21 +1,14 @@
package carpet.script.api;
import carpet.CarpetSettings;
import carpet.fakes.ChunkGeneratorInterface;
import carpet.fakes.ChunkTicketManagerInterface;
import carpet.fakes.RandomStateVisitorAccessor;
import carpet.fakes.ServerChunkManagerInterface;
import carpet.fakes.ServerWorldInterface;
import carpet.fakes.SpawnHelperInnerInterface;
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
import carpet.helpers.FeatureGenerator;
import carpet.mixins.PoiRecord_scarpetMixin;
import carpet.script.CarpetContext;
import carpet.script.CarpetScriptServer;
import carpet.script.Context;
import carpet.script.Expression;
import carpet.script.Fluff;
import carpet.script.annotation.Locator;
import carpet.script.annotation.ScarpetFunction;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.utils.FeatureGenerator;
import carpet.mixins.PoiRecord_scarpetMixin;
import carpet.script.argument.BlockArgument;
import carpet.script.argument.Vector3Argument;
import carpet.script.exception.InternalExpressionException;
@@ -34,7 +27,6 @@ import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.utils.BlockInfo;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@@ -48,6 +40,11 @@ import net.minecraft.core.QuartPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.Ticket;
import net.minecraft.server.level.TicketType;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.PalettedContainer;
@@ -59,7 +56,6 @@ import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.StructureType;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -82,10 +78,6 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.Ticket;
import net.minecraft.server.level.TicketType;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.util.SortedArraySet;
@@ -135,6 +127,8 @@ import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.level.storage.ServerLevelData;
import net.minecraft.world.phys.Vec3;
import javax.annotation.Nullable;
import static carpet.script.utils.WorldTools.canHasChunk;
public class WorldAccess
@@ -256,7 +250,7 @@ public class WorldAccess
{
synchronized (level)
{
((ChunkGeneratorInterface) level.getChunkSource().getGenerator()).initStrongholds(level);
level.getChunkSource().getGeneratorState().ensureStructuresGenerated();
}
}
@@ -444,7 +438,7 @@ public class WorldAccess
}
final Value weather = lv.get(0);
final ServerLevelData worldProperties = ((ServerWorldInterface) world).getWorldPropertiesCM();
final ServerLevelData worldProperties = Vanilla.ServerLevel_getWorldProperties(world);
if (lv.size() == 1)
{
return new NumericValue(switch (weather.getString().toLowerCase(Locale.ROOT))
@@ -644,10 +638,9 @@ public class WorldAccess
expression.addContextFunction("chunk_tickets", -1, (c, t, lv) ->
{
final ServerLevel world = ((CarpetContext) c).level();
final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> levelTickets = (
(ChunkTicketManagerInterface) ((ServerChunkManagerInterface) world.getChunkSource())
.getCMTicketManager()
).getTicketsByPosition();
DistanceManager foo = Vanilla.ServerChunkCache_getCMTicketManager(world.getChunkSource());
final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> levelTickets = Vanilla.ChunkTicketManager_getTicketsByPosition(foo);
final List<Value> res = new ArrayList<>();
if (lv.size() == 0)
{
@@ -723,22 +716,23 @@ public class WorldAccess
// lazy cause its parked execution
expression.addLazyFunction("without_updates", 1, (c, t, lv) ->
{
final boolean previous = CarpetSettings.impendingFillSkipUpdates.get();
if (previous)
if (Carpet.getImpendingFillSkipUpdates().get())
{
return lv.get(0);
}
final Value[] result = new Value[]{Value.NULL};
((CarpetContext) c).server().executeBlocking(() ->
{
final ThreadLocal<Boolean> skipUpdates = Carpet.getImpendingFillSkipUpdates();
final boolean previous = skipUpdates.get();
try
{
CarpetSettings.impendingFillSkipUpdates.set(true);
skipUpdates.set(true);
result[0] = lv.get(0).evalValue(c, t);
}
finally
{
CarpetSettings.impendingFillSkipUpdates.set(false);
skipUpdates.set(previous);
}
});
return (cc, tt) -> result[0];
@@ -1080,7 +1074,9 @@ public class WorldAccess
final Explosion explosion = new Explosion(cc.level(), source, null, null, pos.x, pos.y, pos.z, powah, createFire, mode)
{
@Override
public @Nullable LivingEntity getIndirectSourceEntity()
@Nullable
public
LivingEntity getIndirectSourceEntity()
{
return theAttacker;
}
@@ -1168,15 +1164,15 @@ public class WorldAccess
expression.addContextFunction("block_sound", -1, (c, t, lv) ->
stateStringQuery(c, "block_sound", lv, (s, p) ->
BlockInfo.soundName.get(s.getSoundType())));
Carpet.getSoundTypeNames().get(s.getSoundType())));
expression.addContextFunction("material", -1, (c, t, lv) ->
stateStringQuery(c, "material", lv, (s, p) ->
BlockInfo.materialName.get(s.getMaterial())));
Carpet.getMaterialNames().get(s.getMaterial())));
expression.addContextFunction("map_colour", -1, (c, t, lv) ->
stateStringQuery(c, "map_colour", lv, (s, p) ->
BlockInfo.mapColourName.get(s.getMapColor(((CarpetContext) c).level(), p))));
Carpet.getMapColorNames().get(s.getMapColor(((CarpetContext) c).level(), p))));
// Deprecated for block_state()
@@ -1485,7 +1481,7 @@ public class WorldAccess
}
catch (final NullPointerException npe)
{
CarpetSettings.LOG.error("Failed to detect structure: " + reg.getKey(str));
CarpetScriptServer.LOG.error("Failed to detect structure: " + reg.getKey(str));
start = null;
}
@@ -1649,7 +1645,7 @@ public class WorldAccess
final Value[] result = new Value[]{Value.NULL};
((CarpetContext) c).server().executeBlocking(() ->
{
final Map<String, Integer> report = ((ThreadedAnvilChunkStorageInterface) world.getChunkSource().chunkMap).regenerateChunkRegion(requestedChunks);
final Map<String, Integer> report = Vanilla.ChunkMap_regenerateChunkRegion(world.getChunkSource().chunkMap, requestedChunks);
result[0] = MapValue.wrap(report.entrySet().stream().collect(Collectors.toMap(
e -> new StringValue(e.getKey()),
e -> new NumericValue(e.getValue())
@@ -1677,9 +1673,7 @@ public class WorldAccess
required_charge = NumericValue.asNumber(lv.get(locator.offset)).getDouble();
}
final NaturalSpawner.SpawnState charger = cc.level().getChunkSource().getLastSpawnState();
return charger == null ? Value.NULL : new NumericValue(
((SpawnHelperInnerInterface) charger).getPotentialCalculator().
getPotentialEnergyChange(pos, required_charge)
return charger == null ? Value.NULL : new NumericValue(Vanilla.SpawnState_getPotentialCalculator(charger).getPotentialEnergyChange(pos, required_charge)
);
});
@@ -1809,7 +1803,7 @@ public class WorldAccess
noiseBasedChunkGenerator.generatorSettings().value(),
level.registryAccess().lookupOrThrow(Registries.NOISE), level.getSeed()
);
DensityFunction.Visitor visitor = ((RandomStateVisitorAccessor) (Object) randomState).getVisitor();
DensityFunction.Visitor visitor = Vanilla.RandomState_getVisitor(randomState);
return densityFunction.mapAll(visitor);
}
@@ -1,8 +1,9 @@
package carpet.script.argument;
import carpet.CarpetServer;
import carpet.script.CarpetScriptServer;
import carpet.script.Context;
import carpet.script.Module;
import carpet.script.ScriptHost;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
@@ -18,7 +19,6 @@ import net.minecraft.nbt.NbtAccounter;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.TagTypes;
import net.minecraft.world.level.storage.LevelResource;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.tuple.Pair;
@@ -58,6 +58,7 @@ public class FileArgument
public Reason reason;
private FileSystem zfs;
private Path zipPath;
private ScriptHost host;
public static final Object writeIOSync = new Object();
@@ -103,7 +104,7 @@ public class FileArgument
READ, CREATE, DELETE
}
public FileArgument(final String resource, final Type type, final String zipContainer, final boolean isFolder, final boolean isShared, final Reason reason)
public FileArgument(final String resource, final Type type, final String zipContainer, final boolean isFolder, final boolean isShared, final Reason reason, final ScriptHost host)
{
this.resource = resource;
this.type = type;
@@ -113,6 +114,7 @@ public class FileArgument
this.reason = reason;
this.zfs = null;
this.zipPath = null;
this.host = host;
}
@Override
@@ -121,7 +123,7 @@ public class FileArgument
return "path: " + resource + " zip: " + zipContainer + " type: " + type.id + " folder: " + isFolder + " shared: " + isShared + " reason: " + reason.toString();
}
public static FileArgument from(final List<Value> lv, final boolean isFolder, final Reason reason)
public static FileArgument from(final Context context, final List<Value> lv, final boolean isFolder, final Reason reason)
{
if (lv.size() < 2)
{
@@ -140,14 +142,14 @@ public class FileArgument
{
throw new InternalExpressionException("Folder types are no supported for this IO function");
}
return new FileArgument(resource.getLeft(), type, resource.getRight(), isFolder, shared, reason);
return new FileArgument(resource.getLeft(), type, resource.getRight(), isFolder, shared, reason, context.host);
}
public static FileArgument resourceFromPath(final String path, final Reason reason, final boolean shared)
public static FileArgument resourceFromPath(final ScriptHost host, final String path, final Reason reason, final boolean shared)
{
final Pair<String, String> resource = recognizeResource(path, false, Type.ANY);
return new FileArgument(resource.getLeft(), Type.ANY, resource.getRight(), false, shared, reason);
return new FileArgument(resource.getLeft(), Type.ANY, resource.getRight(), false, shared, reason, host);
}
public static Pair<String, String> recognizeResource(final String origfile, final boolean isFolder, final Type type)
@@ -196,11 +198,7 @@ public class FileArgument
private Path resolve(final String suffix)
{
if (CarpetServer.minecraft_server == null)
{
throw new InternalExpressionException("Accessing world files without server running");
}
return CarpetServer.minecraft_server.getWorldPath(LevelResource.ROOT).resolve("scripts/" + suffix);
return host.resolveScriptFile(suffix);
}
private Path toPath(final Module module)
@@ -1,9 +1,10 @@
package carpet.script.command;
import carpet.CarpetServer;
import carpet.fakes.BlockStateArgumentInterface;
import carpet.script.CarpetScriptHost;
import carpet.script.CarpetScriptServer;
import carpet.script.argument.FunctionArgument;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.value.BlockValue;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
@@ -15,8 +16,6 @@ import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.utils.CarpetProfiler;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.datafixers.util.Either;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
@@ -134,7 +133,7 @@ public abstract class CommandArgument
new VanillaUnconfigurableArgument("block", BlockStateArgument::block,
(c, p) -> {
BlockInput result = BlockStateArgument.getBlock(c, p);
return new BlockValue(result.getState(), c.getSource().getLevel(), null, ((BlockStateArgumentInterface) result).getCMTag());
return new BlockValue(result.getState(), c.getSource().getLevel(), null, Vanilla.BlockInput_getTag(result));
},
param -> (ctx, builder) -> ctx.getArgument(param, BlockStateArgument.class).listSuggestions(ctx, builder)
),
@@ -318,8 +317,9 @@ public abstract class CommandArgument
return argument(param, arg.getArgumentType(host));
}
final String hostName = host.getName();
final CarpetScriptServer scriptServer = host.scriptServer();
return argument(param, arg.getArgumentType(host)).suggests((ctx, b) -> {
final CarpetScriptHost cHost = CarpetServer.scriptServer.modules.get(hostName).retrieveOwnForExecution(ctx.getSource());
final CarpetScriptHost cHost = scriptServer.modules.get(hostName).retrieveOwnForExecution(ctx.getSource());
return arg.suggest(ctx, b, cHost);
});
}
@@ -426,7 +426,7 @@ public abstract class CommandArgument
{
if (customSuggester != null)
{
final CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet command", CarpetProfiler.TYPE.GENERAL);
final Runnable currentSection = Carpet.startProfilerSection("Scarpet command");
final Map<Value, Value> params = new HashMap<>();
for (final ParsedCommandNode<CommandSourceStack> pnode : context.getNodes())
{
@@ -445,7 +445,7 @@ public abstract class CommandArgument
throw error("Custom suggester should return a list of options" + " for custom type " + suffix);
}
final Collection<String> res = ((ListValue) response).getItems().stream().map(Value::getString).collect(Collectors.toList());
CarpetProfiler.end_current_section(currentSection);
currentSection.run();
return res;
}
return needsMatching ? examples : Collections.singletonList("... " + getTypeSuffix());
@@ -1,7 +1,7 @@
package carpet.script.exception;
import carpet.script.external.Carpet;
import carpet.script.value.FunctionValue;
import carpet.utils.Messenger;
import java.util.List;
@@ -23,7 +23,7 @@ public class CarpetExpressionException extends StacklessRuntimeException impleme
{
for (final FunctionValue fun : stack)
{
Messenger.m(source, "e ... in " + fun.fullName(), "e /" + (fun.getToken().lineno + 1) + ":" + (fun.getToken().linepos + 1));
Carpet.Messenger_message(source, "e ... in " + fun.fullName(), "e /" + (fun.getToken().lineno + 1) + ":" + (fun.getToken().linepos + 1));
}
}
}
@@ -3,8 +3,8 @@ package carpet.script.exception;
import carpet.script.Context;
import carpet.script.Expression;
import carpet.script.Tokenizer;
import carpet.script.external.Carpet;
import carpet.script.value.FunctionValue;
import carpet.utils.Messenger;
import java.util.ArrayList;
import java.util.Collections;
@@ -22,7 +22,7 @@ public class ExpressionException extends StacklessRuntimeException implements Re
public static void prepareForDoom()
{
Messenger.c("foo bar");
Carpet.Messenger_compose("foo bar");
}
public ExpressionException(final Context c, final Expression e, final String message)
@@ -3,7 +3,7 @@ package carpet.script.exception;
/**
* A type of {@link RuntimeException} that doesn't spend time producing and filling a stacktrace
*/
abstract class StacklessRuntimeException extends RuntimeException
public abstract class StacklessRuntimeException extends RuntimeException
{
public StacklessRuntimeException()
{
+181
View File
@@ -0,0 +1,181 @@
package carpet.script.external;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.api.settings.CarpetRule;
import carpet.api.settings.RuleHelper;
import carpet.api.settings.SettingsManager;
import carpet.api.settings.Validator;
import carpet.fakes.MinecraftServerInterface;
import carpet.helpers.TickSpeed;
import carpet.logging.HUDController;
import carpet.network.ServerNetworkHandler;
import carpet.patches.EntityPlayerMPFake;
import carpet.script.CarpetExpression;
import carpet.script.CarpetScriptServer;
import carpet.script.utils.AppStoreManager;
import carpet.script.value.MapValue;
import carpet.script.value.StringValue;
import carpet.utils.BlockInfo;
import carpet.utils.CarpetProfiler;
import carpet.utils.Messenger;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.material.MaterialColor;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class Carpet
{
public static Map<String, Component> getScarpetHeaders()
{
return HUDController.scarpet_headers;
}
public static Map<String, Component> getScarpetFooters()
{
return HUDController.scarpet_footers;
}
public static void updateScarpetHUDs(final MinecraftServer server, final List<ServerPlayer> players)
{
HUDController.update_hud(server, players);
}
public static Component Messenger_compose(final Object... messages)
{
return Messenger.c(messages);
}
public static void Messenger_message(final CommandSourceStack source, final Object... messages)
{
Messenger.m(source, messages);
}
public static ThreadLocal<Boolean> getImpendingFillSkipUpdates()
{
return CarpetSettings.impendingFillSkipUpdates;
}
public static Map<SoundType, String> getSoundTypeNames()
{
return BlockInfo.soundName;
}
public static Map<MaterialColor, String> getMapColorNames()
{
return BlockInfo.mapColourName;
}
public static Map<Material, String> getMaterialNames()
{
return BlockInfo.materialName;
}
public static Runnable startProfilerSection(final String name)
{
final CarpetProfiler.ProfilerToken token = CarpetProfiler.start_section(null, name, CarpetProfiler.TYPE.GENERAL);
return () -> CarpetProfiler.end_current_section(token);
}
public static void MinecraftServer_addScriptServer(final MinecraftServer server, final CarpetScriptServer scriptServer)
{
((MinecraftServerInterface) server).addScriptServer(scriptServer);
}
public static boolean isValidCarpetPlayer(final ServerPlayer player)
{
return ServerNetworkHandler.isValidCarpetPlayer(player);
}
public static String getPlayerStatus(final ServerPlayer player)
{
return ServerNetworkHandler.getPlayerStatus(player);
}
public static MapValue getAllCarpetRules()
{
final Collection<CarpetRule<?>> rules = CarpetServer.settingsManager.getCarpetRules();
final MapValue carpetRules = new MapValue(Collections.emptyList());
rules.forEach(rule -> carpetRules.put(new StringValue(rule.name()), new StringValue(RuleHelper.toRuleString(rule.value()))));
CarpetServer.extensions.forEach(e -> {
final SettingsManager manager = e.extensionSettingsManager();
if (manager == null)
{
return;
}
manager.getCarpetRules().forEach(rule -> carpetRules.put(new StringValue(manager.identifier() + ":" + rule.name()), new StringValue(RuleHelper.toRuleString(rule.value()))));
});
return carpetRules;
}
public static String getCarpetVersion()
{
return CarpetSettings.carpetVersion;
}
@Nullable
public static String isModdedPlayer(final Player p)
{
if (p instanceof final EntityPlayerMPFake fake)
{
return fake.isAShadow ? "shadow" : "fake";
}
return null;
}
public static boolean isTickProcessingPaused()
{
return !TickSpeed.process_entities;
}
public static void handleExtensionsAPI(final CarpetExpression expression)
{
CarpetServer.extensions.forEach(e -> e.scarpetApi(expression));
}
public static boolean getFillUpdates()
{
return CarpetSettings.fillUpdates;
}
public static class ScarpetAppStoreValidator extends Validator<String>
{
@Override
public String validate(final CommandSourceStack source, final CarpetRule<String> currentRule, String newValue, final String stringInput)
{
if (newValue.equals(currentRule.value()))
{
// Don't refresh the local repo if it's the same (world change), helps preventing hitting rate limits from github when
// getting suggestions. Pending is a way to invalidate the cache when it gets old, and investigating api usage further
return newValue;
}
if (newValue.equalsIgnoreCase("none"))
{
AppStoreManager.setScarpetRepoLink(null);
return newValue;
}
if (newValue.endsWith("/"))
{
newValue = newValue.replaceAll("/$", "");
}
AppStoreManager.setScarpetRepoLink("https://api.github.com/repos/" + newValue + "/");
return newValue;
}
@Override
public String description()
{
return "Appstore link should point to a valid github repository";
}
}
}
+364
View File
@@ -0,0 +1,364 @@
package carpet.script.external;
import carpet.CarpetSettings;
import carpet.fakes.BiomeInterface;
import carpet.fakes.BlockPredicateInterface;
import carpet.fakes.BlockStateArgumentInterface;
import carpet.fakes.ChunkTicketManagerInterface;
import carpet.fakes.CommandDispatcherInterface;
import carpet.fakes.EntityInterface;
import carpet.fakes.IngredientInterface;
import carpet.fakes.InventoryBearerInterface;
import carpet.fakes.ItemEntityInterface;
import carpet.fakes.LivingEntityInterface;
import carpet.fakes.MinecraftServerInterface;
import carpet.fakes.MobEntityInterface;
import carpet.fakes.RandomStateVisitorAccessor;
import carpet.fakes.RecipeManagerInterface;
import carpet.fakes.AbstractContainerMenuInterface;
import carpet.fakes.ServerChunkManagerInterface;
import carpet.fakes.ServerPlayerInterface;
import carpet.fakes.ServerPlayerInteractionManagerInterface;
import carpet.fakes.ServerWorldInterface;
import carpet.fakes.SpawnHelperInnerInterface;
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
import carpet.mixins.Objective_scarpetMixin;
import carpet.mixins.Scoreboard_scarpetMixin;
import carpet.network.ServerNetworkHandler;
import carpet.script.CarpetScriptServer;
import carpet.script.EntityEventsGroup;
import carpet.script.value.MapValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.utils.CommandHelper;
import carpet.utils.SpawnReporter;
import com.mojang.brigadier.CommandDispatcher;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.blocks.BlockInput;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.server.level.Ticket;
import net.minecraft.tags.TagKey;
import net.minecraft.util.SortedArraySet;
import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.ai.goal.GoalSelector;
import net.minecraft.world.entity.animal.horse.AbstractHorse;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.DataSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.NaturalSpawner;
import net.minecraft.world.level.PotentialCalculator;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.ServerLevelData;
import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.Scoreboard;
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BooleanSupplier;
import java.util.function.Predicate;
public class Vanilla
{
public static void MinecraftServer_forceTick(final MinecraftServer server, final BooleanSupplier sup)
{
((MinecraftServerInterface) server).forceTick(sup);
}
public static void ChunkMap_relightChunk(final ChunkMap chunkMap, final ChunkPos pos)
{
((ThreadedAnvilChunkStorageInterface) chunkMap).relightChunk(pos);
}
public static Map<String, Integer> ChunkMap_regenerateChunkRegion(final ChunkMap chunkMap, final List<ChunkPos> requestedChunks)
{
return ((ThreadedAnvilChunkStorageInterface) chunkMap).regenerateChunkRegion(requestedChunks);
}
public static List<Collection<ItemStack>> Ingredient_getRecipeStacks(final Ingredient ingredient)
{
return ((IngredientInterface) (Object) ingredient).getRecipeStacks();
}
public static List<Recipe<?>> RecipeManager_getAllMatching(final RecipeManager recipeManager, final RecipeType<?> type, final ResourceLocation output, final RegistryAccess registryAccess)
{
return ((RecipeManagerInterface) recipeManager).getAllMatching(type, output, registryAccess);
}
public static int NaturalSpawner_MAGIC_NUMBER()
{
return SpawnReporter.MAGIC_NUMBER;
}
public static PotentialCalculator SpawnState_getPotentialCalculator(final NaturalSpawner.SpawnState spawnState)
{
return ((SpawnHelperInnerInterface) spawnState).getPotentialCalculator();
}
public static void Objective_setCriterion(final Objective objective, final ObjectiveCriteria criterion)
{
((Objective_scarpetMixin) objective).setCriterion(criterion);
}
public static Map<ObjectiveCriteria, List<Objective>> Scoreboard_getObjectivesByCriterion(final Scoreboard scoreboard)
{
return ((Scoreboard_scarpetMixin) scoreboard).getObjectivesByCriterion();
}
public static ServerLevelData ServerLevel_getWorldProperties(final ServerLevel world)
{
return ((ServerWorldInterface) world).getWorldPropertiesCM();
}
public static DistanceManager ServerChunkCache_getCMTicketManager(final ServerChunkCache chunkCache)
{
return ((ServerChunkManagerInterface) chunkCache).getCMTicketManager();
}
public static Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> ChunkTicketManager_getTicketsByPosition(final DistanceManager ticketManager)
{
return ((ChunkTicketManagerInterface) ticketManager).getTicketsByPosition();
}
public static DensityFunction.Visitor RandomState_getVisitor(final RandomState randomState)
{
return ((RandomStateVisitorAccessor) (Object) randomState).getVisitor();
}
public static CompoundTag BlockInput_getTag(final BlockInput blockInput)
{
return ((BlockStateArgumentInterface) blockInput).getCMTag();
}
public static CarpetScriptServer MinecraftServer_getScriptServer(final MinecraftServer server)
{
return ((MinecraftServerInterface) server).getScriptServer();
}
public static Biome.ClimateSettings Biome_getClimateSettings(final Biome biome)
{
return ((BiomeInterface) (Object) biome).getClimateSettings();
}
public static ThreadLocal<Boolean> skipGenerationChecks(final ServerLevel level)
{ // not sure does vanilla care at all - needs checking
return CarpetSettings.skipGenerationChecks;
}
public static void sendScarpetShapesDataToPlayer(final ServerPlayer player, final Tag data)
{ // dont forget to add the packet to vanilla packed handler and call ShapesRenderer.addShape to handle on client
ServerNetworkHandler.sendCustomCommand(player, "scShapes", data);
}
public static int MinecraftServer_getRunPermissionLevel(final MinecraftServer server)
{
return CarpetSettings.runPermissionLevel;
}
public static String MinecraftServer_getReleaseTarget(final MinecraftServer server)
{
return CarpetSettings.releaseTarget;
}
public static boolean isDevelopmentEnvironment()
{
return FabricLoader.getInstance().isDevelopmentEnvironment();
}
public static MapValue getServerMods(final MinecraftServer server)
{
final Map<Value, Value> ret = new HashMap<>();
for (final ModContainer mod : FabricLoader.getInstance().getAllMods())
{
ret.put(new StringValue(mod.getMetadata().getId()), new StringValue(mod.getMetadata().getVersion().getFriendlyString()));
}
return MapValue.wrap(ret);
}
public static LevelStorageSource.LevelStorageAccess MinecraftServer_storageSource(final MinecraftServer server)
{
return ((MinecraftServerInterface) server).getCMSession();
}
public static BlockPos ServerPlayerGameMode_getCurrentBlockPosition(final ServerPlayerGameMode gameMode)
{
return ((ServerPlayerInteractionManagerInterface) gameMode).getCurrentBreakingBlock();
}
public static int ServerPlayerGameMode_getCurrentBlockBreakingProgress(final ServerPlayerGameMode gameMode)
{
return ((ServerPlayerInteractionManagerInterface) gameMode).getCurrentBlockBreakingProgress();
}
public static void ServerPlayerGameMode_setBlockBreakingProgress(final ServerPlayerGameMode gameMode, final int progress)
{
((ServerPlayerInteractionManagerInterface) gameMode).setBlockBreakingProgress(progress);
}
public static boolean ServerPlayer_isInvalidEntityObject(final ServerPlayer player)
{
return ((ServerPlayerInterface) player).isInvalidEntityObject();
}
public static String ServerPlayer_getLanguage(final ServerPlayer player)
{
return ((ServerPlayerInterface) player).getLanguage();
}
public static GoalSelector Mob_getAI(final Mob mob, final boolean target)
{
return ((MobEntityInterface) mob).getAI(target);
}
public static Map<String, Goal> Mob_getTemporaryTasks(final Mob mob)
{
return ((MobEntityInterface) mob).getTemporaryTasks();
}
public static void Mob_setPersistence(final Mob mob, final boolean what)
{
((MobEntityInterface) mob).setPersistence(what);
}
public static EntityEventsGroup Entity_getEventContainer(final Entity entity)
{
return ((EntityInterface) entity).getEventContainer();
}
public static boolean Entity_isPermanentVehicle(final Entity entity)
{
return ((EntityInterface) entity).isPermanentVehicle();
}
public static void Entity_setPermanentVehicle(final Entity entity, final boolean permanent)
{
((EntityInterface) entity).setPermanentVehicle(permanent);
}
public static int Entity_getPortalTimer(final Entity entity)
{
return ((EntityInterface) entity).getPortalTimer();
}
public static void Entity_setPortalTimer(final Entity entity, final int amount)
{
((EntityInterface) entity).setPortalTimer(amount);
}
public static int Entity_getPublicNetherPortalCooldown(final Entity entity)
{
return ((EntityInterface) entity).getPublicNetherPortalCooldown();
}
public static void Entity_setPublicNetherPortalCooldown(final Entity entity, final int what)
{
((EntityInterface) entity).setPublicNetherPortalCooldown(what);
}
public static int ItemEntity_getPickupDelay(final ItemEntity entity)
{
return ((ItemEntityInterface) entity).getPickupDelayCM();
}
public static boolean LivingEntity_isJumping(final LivingEntity entity)
{
return ((LivingEntityInterface) entity).isJumpingCM();
}
public static void LivingEntity_setJumping(final LivingEntity entity)
{
((LivingEntityInterface) entity).doJumpCM();
}
public static Container AbstractHorse_getInventory(final AbstractHorse horse)
{
return ((InventoryBearerInterface) horse).getCMInventory();
}
public static DataSlot AbstractContainerMenu_getDataSlot(final AbstractContainerMenu handler, final int index)
{
return ((AbstractContainerMenuInterface) handler).getDataSlot(index);
}
public static void CommandDispatcher_unregisterCommand(final CommandDispatcher<CommandSourceStack> dispatcher, final String name)
{
((CommandDispatcherInterface) dispatcher).carpet$unregister(name);
}
public static boolean MinecraftServer_doScriptsAutoload(final MinecraftServer server)
{
return CarpetSettings.scriptsAutoload;
}
public static void MinecraftServer_notifyPlayersCommandsChanged(final MinecraftServer server)
{
CommandHelper.notifyPlayersCommandsChanged(server);
}
public static boolean ScriptServer_scriptOptimizations(final MinecraftServer scriptServer)
{
return CarpetSettings.scriptsOptimization;
}
public static boolean ScriptServer_scriptDebugging(final MinecraftServer server)
{
return CarpetSettings.scriptsDebugging;
}
public static boolean ServerPlayer_canScriptACE(final CommandSourceStack player)
{
return CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE);
}
public static boolean ServerPlayer_canScriptGeneral(final CommandSourceStack player)
{
return CommandHelper.canUseCommand(player, CarpetSettings.commandScript);
}
public static int MinecraftServer_getFillLimit(final MinecraftServer server)
{
return Math.max(server.getGameRules().getInt(GameRules.RULE_COMMAND_MODIFICATION_BLOCK_LIMIT), CarpetSettings.fillLimit);
}
public record BlockPredicatePayload(BlockState state, TagKey<Block> tagKey, Map<Value, Value> properties, CompoundTag tag) {
public static BlockPredicatePayload of(final Predicate<BlockInWorld> blockPredicate)
{
final BlockPredicateInterface predicateData = (BlockPredicateInterface) blockPredicate;
return new BlockPredicatePayload(predicateData.getCMBlockState(), predicateData.getCMBlockTagKey(), predicateData.getCMProperties(), predicateData.getCMDataTag());
}
}
}
+13
View File
@@ -0,0 +1,13 @@
package carpet.script.external;
import carpet.mixins.ShulkerBoxAccessMixin;
import net.minecraft.client.model.ShulkerModel;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
public class VanillaClient
{
public static ShulkerModel<?> ShulkerBoxRenderer_model(final BlockEntityRenderer<ShulkerBoxBlockEntity> shulkerBoxRenderer) {
return ((ShulkerBoxAccessMixin)shulkerBoxRenderer).getModel();
}
}
@@ -0,0 +1,8 @@
@ParametersAreNonnullByDefault
@FieldsAreNonnullByDefault
@MethodsReturnNonnullByDefault
package carpet.script.external;
import net.minecraft.FieldsAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;
@@ -1,15 +1,13 @@
package carpet.script.utils;
import carpet.CarpetServer;
import carpet.api.settings.CarpetRule;
import carpet.api.settings.Validator;
import carpet.script.CarpetScriptHost;
import carpet.script.CarpetScriptServer;
import carpet.script.exception.InternalExpressionException;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.value.MapValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.utils.Messenger;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -36,6 +34,8 @@ import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import javax.annotation.Nullable;
/**
* A class used to save scarpet app store scripts to disk
*/
@@ -52,40 +52,15 @@ public class AppStoreManager
*/
private static String scarpetRepoLink = "https://api.github.com/repos/gnembon/scarpet/contents/programs/";
private record AppInfo(String name, String url, StoreNode source)
public static void setScarpetRepoLink(@Nullable final String link)
{
APP_STORE_ROOT = AppStoreManager.StoreNode.folder(null, "");
scarpetRepoLink = link;
}
public static class ScarpetAppStoreValidator extends Validator<String>
{
@Override
public String validate(final CommandSourceStack source, final CarpetRule<String> currentRule, String newValue, final String stringInput)
{
if (newValue.equals(currentRule.value()))
{
// Don't refresh the local repo if it's the same (world change), helps preventing hitting rate limits from github when
// getting suggestions. Pending is a way to invalidate the cache when it gets old, and investigating api usage further
return newValue;
}
APP_STORE_ROOT = StoreNode.folder(null, "");
if (newValue.equalsIgnoreCase("none"))
{
scarpetRepoLink = null;
return newValue;
}
if (newValue.endsWith("/"))
{
newValue = newValue.replaceAll("/$", "");
}
scarpetRepoLink = "https://api.github.com/repos/" + newValue + "/";
return newValue;
}
@Override
public String description()
{
return "Appstore link should point to a valid github repository";
}
private record AppInfo(String name, String url, StoreNode source)
{
}
public static class StoreNode
@@ -291,13 +266,13 @@ public class AppStoreManager
}
catch (final IOException e)
{
throw new CommandRuntimeException(Messenger.c("rb Failed to obtain app file content: " + e.getMessage()));
throw new CommandRuntimeException(Carpet.Messenger_compose("rb Failed to obtain app file content: " + e.getMessage()));
}
if (!saveScriptToFile(source, path, nodeInfo.name(), code, false, useTrash))
{
return 0;
}
final boolean success = CarpetServer.scriptServer.addScriptHost(source, nodeInfo.name().replaceFirst("\\.sc$", ""), null, true, false, false, nodeInfo.source());
final boolean success = Vanilla.MinecraftServer_getScriptServer(source.getServer()).addScriptHost(source, nodeInfo.name().replaceFirst("\\.sc$", ""), null, true, false, false, nodeInfo.source());
return success ? 1 : 0;
}
@@ -328,7 +303,7 @@ public class AppStoreManager
}
catch (final IOException e)
{
throw new CommandRuntimeException(Messenger.c("rb '" + appPath + "' is not a valid path to a scarpet app: " + e.getMessage()));
throw new CommandRuntimeException(Carpet.Messenger_compose("rb '" + appPath + "' is not a valid path to a scarpet app: " + e.getMessage()));
}
}
@@ -363,7 +338,7 @@ public class AppStoreManager
}
Files.move(scriptLocation, trashPath);
}
Messenger.m(source, String.format("gi Note: replaced existing app '%s'" + (useTrash ? " (old moved to /trash folder)" : ""), appFileName));
Carpet.Messenger_message(source, String.format("gi Note: replaced existing app '%s'" + (useTrash ? " (old moved to /trash folder)" : ""), appFileName));
}
final BufferedWriter writer = Files.newBufferedWriter(scriptLocation);
writer.write(code);
@@ -371,7 +346,7 @@ public class AppStoreManager
}
catch (final IOException e)
{
Messenger.m(source, "r Error while downloading app: " + e);
Carpet.Messenger_message(source, "r Error while downloading app: " + e);
CarpetScriptServer.LOG.warn("Error while downloading app", e);
return false;
}
@@ -1,6 +1,6 @@
package carpet.script.utils;
import carpet.fakes.BiomeInterface;
import carpet.script.external.Vanilla;
import carpet.script.value.ListValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
@@ -30,7 +30,7 @@ public class BiomeInfo
put("sky_color", (w, b) -> ValueConversions.ofRGB(b.getSpecialEffects().getSkyColor()));
put("water_color", (w, b) -> ValueConversions.ofRGB(b.getSpecialEffects().getWaterColor()));
put("water_fog_color", (w, b) -> ValueConversions.ofRGB(b.getSpecialEffects().getWaterFogColor()));
put("humidity", (w, b) -> NumericValue.of(((BiomeInterface) (Object) b).getClimateSettings().downfall()));
put("humidity", (w, b) -> NumericValue.of(Vanilla.Biome_getClimateSettings(b).downfall()));
put("precipitation", (w, b) -> StringValue.of(b.getPrecipitationAt(new BlockPos(0, w.getSeaLevel(), 0)).name().toLowerCase(Locale.ROOT)));
put("features", (w, b) -> {
final Registry<ConfiguredFeature<?, ?>> registry = w.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE);
@@ -0,0 +1,34 @@
package carpet.script.utils;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.Vec3;
public class EntityTools
{
/**
* Not a replacement for living entity jump() - this barely is to allow other entities that can't jump in vanilla to 'jump'
*
* @param e
*/
public static void genericJump(final Entity e)
{
if (!e.isOnGround() && !e.isInWaterOrBubble() && !e.isInLava())
{
return;
}
final float m = e.level.getBlockState(e.blockPosition()).getBlock().getJumpFactor();
final float g = e.level.getBlockState(new BlockPos(e.getX(), e.getBoundingBox().minY - 0.5000001D, e.getZ())).getBlock().getJumpFactor();
final float jumpVelocityMultiplier = m == 1.0D ? g : m;
final float jumpStrength = (0.42F * jumpVelocityMultiplier);
final Vec3 vec3d = e.getDeltaMovement();
e.setDeltaMovement(vec3d.x, jumpStrength, vec3d.z);
if (e.isSprinting())
{
final float u = e.getYRot() * 0.017453292F; // yaw
e.setDeltaMovement(e.getDeltaMovement().add((-Mth.sin(g) * 0.2F), 0.0D, (Mth.cos(u) * 0.2F)));
}
e.hasImpulse = true;
}
}
@@ -1,7 +1,7 @@
package carpet.script.utils;
import carpet.fakes.MinecraftServerInterface;
import carpet.fakes.ServerWorldInterface;
//import carpet.fakes.MinecraftServerInterface;
//import carpet.fakes.ServerWorldInterface;
import carpet.script.CarpetScriptServer;
import carpet.script.value.ListValue;
import carpet.script.value.Value;
@@ -1,9 +1,8 @@
package carpet.helpers;
package carpet.script.utils;
import carpet.CarpetSettings;
import carpet.fakes.ChunkGeneratorInterface;
import carpet.script.CarpetScriptServer;
import carpet.script.external.Vanilla;
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Pair;
import java.util.HashMap;
import java.util.List;
@@ -13,19 +12,19 @@ import java.util.Optional;
import java.util.OptionalInt;
import java.util.function.Function;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.HolderSet;
import net.minecraft.core.QuartPos;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.Pools;
import net.minecraft.data.worldgen.ProcessorLists;
import net.minecraft.data.worldgen.placement.PlacementUtils;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BiomeTags;
import net.minecraft.util.RandomSource;
@@ -35,6 +34,7 @@ import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.levelgen.VerticalAnchor;
@@ -63,75 +63,88 @@ import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement
import net.minecraft.world.level.levelgen.structure.structures.JigsawStructure;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
import javax.annotation.Nullable;
public class FeatureGenerator
{
synchronized public static Boolean plop(String featureName, ServerLevel world, BlockPos pos)
@Nullable
public static synchronized Boolean plop(final String featureName, final ServerLevel world, final BlockPos pos)
{
Function<ServerLevel, Thing> custom = featureMap.get(featureName);
final Function<ServerLevel, Thing> custom = featureMap.get(featureName);
if (custom != null)
{
return custom.apply(world).plop(world, pos);
}
ResourceLocation id = new ResourceLocation(featureName);
Structure structure = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
final ResourceLocation id = new ResourceLocation(featureName);
final Structure structure = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
if (structure != null)
{
return plopAnywhere( structure, world, pos, world.getChunkSource().getGenerator(), false);
return plopAnywhere(structure, world, pos, world.getChunkSource().getGenerator(), false);
}
ConfiguredFeature<?, ?> configuredFeature = world.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(id);
final ConfiguredFeature<?, ?> configuredFeature = world.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(id);
if (configuredFeature != null)
{
CarpetSettings.skipGenerationChecks.set(true);
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
checks.set(true);
try
{
return configuredFeature.place(world, world.getChunkSource().getGenerator(), world.random, pos);
}
finally
{
CarpetSettings.skipGenerationChecks.set(false);
checks.set(false);
}
}
Optional<StructureType<?>> structureType = world.registryAccess().registryOrThrow(Registries.STRUCTURE_TYPE).getOptional(id);
final Optional<StructureType<?>> structureType = world.registryAccess().registryOrThrow(Registries.STRUCTURE_TYPE).getOptional(id);
if (structureType.isPresent())
{
Structure configuredStandard = getDefaultFeature(structureType.get(), world, pos);
if (configuredStandard != null)
return plopAnywhere(configuredStandard, world, pos, world.getChunkSource().getGenerator(), false);
}
Feature<?> feature = world.registryAccess().registryOrThrow(Registries.FEATURE).get(id);
if (feature != null)
{
ConfiguredFeature<?,?> configuredStandard = getDefaultFeature(feature, world, pos, true);
final Structure configuredStandard = getDefaultFeature(structureType.get(), world, pos);
if (configuredStandard != null)
{
CarpetSettings.skipGenerationChecks.set(true);
return plopAnywhere(configuredStandard, world, pos, world.getChunkSource().getGenerator(), false);
}
}
final Feature<?> feature = world.registryAccess().registryOrThrow(Registries.FEATURE).get(id);
if (feature != null)
{
final ConfiguredFeature<?, ?> configuredStandard = getDefaultFeature(feature, world, pos, true);
if (configuredStandard != null)
{
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
checks.set(true);
try
{
return configuredStandard.place(world, world.getChunkSource().getGenerator(), world.random, pos);
}
finally
{
CarpetSettings.skipGenerationChecks.set(false);
checks.set(false);
}
}
}
return null;
}
public static Structure resolveConfiguredStructure(String name, ServerLevel world, BlockPos pos)
public static Structure resolveConfiguredStructure(final String name, final ServerLevel world, final BlockPos pos)
{
ResourceLocation id = new ResourceLocation(name);
Structure configuredStructureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
if (configuredStructureFeature != null) return configuredStructureFeature;
StructureType<?> structureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE_TYPE).get(id);
if (structureFeature == null) return null;
final ResourceLocation id = new ResourceLocation(name);
final Structure configuredStructureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
if (configuredStructureFeature != null)
{
return configuredStructureFeature;
}
final StructureType<?> structureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE_TYPE).get(id);
if (structureFeature == null)
{
return null;
}
return getDefaultFeature(structureFeature, world, pos);
}
synchronized public static Boolean plopGrid(Structure structureFeature, ServerLevel world, BlockPos pos)
public static synchronized Boolean plopGrid(final Structure structureFeature, final ServerLevel world, final BlockPos pos)
{
return plopAnywhere( structureFeature, world, pos, world.getChunkSource().getGenerator(), true);
return plopAnywhere(structureFeature, world, pos, world.getChunkSource().getGenerator(), true);
}
@FunctionalInterface
@@ -139,85 +152,102 @@ public class FeatureGenerator
{
Boolean plop(ServerLevel world, BlockPos pos);
}
private static Thing simplePlop(ConfiguredFeature<?,?> feature)
private static Thing simplePlop(final ConfiguredFeature<?, ?> feature)
{
return (w, p) -> {
CarpetSettings.skipGenerationChecks.set(true);
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(w);
checks.set(true);
try
{
return feature.place(w, w.getChunkSource().getGenerator(), w.random, p);
}
finally
{
CarpetSettings.skipGenerationChecks.set(false);
checks.set(false);
}
};
}
private static <FC extends FeatureConfiguration, F extends Feature<FC>> Thing simplePlop(F feature, FC config)
private static <FC extends FeatureConfiguration, F extends Feature<FC>> Thing simplePlop(final F feature, final FC config)
{
return simplePlop(new ConfiguredFeature<>(feature, config));
}
private static Thing simpleTree(TreeConfiguration config)
private static Thing simpleTree(final TreeConfiguration config)
{
//config.ignoreFluidCheck();
return simplePlop(new ConfiguredFeature<>(Feature.TREE, config));
}
private static Thing spawnCustomStructure(Structure structure)
private static Thing spawnCustomStructure(final Structure structure)
{
return setupCustomStructure(structure,false);
return setupCustomStructure(structure, false);
}
private static Thing setupCustomStructure(Structure structure, boolean wireOnly)
{
private static Thing setupCustomStructure(final Structure structure, final boolean wireOnly)
{
return (w, p) -> plopAnywhere(structure, w, p, w.getChunkSource().getGenerator(), wireOnly);
}
private static Structure getDefaultFeature(StructureType<?> structure, ServerLevel world, BlockPos pos)
private static Structure getDefaultFeature(final StructureType<?> structure, final ServerLevel world, final BlockPos pos)
{
// would be nice to have a way to grab structures of this type for position
// TODO allow old types, like vaillage, or bastion
Holder<Biome> existingBiome = world.getBiome(pos);
final Holder<Biome> existingBiome = world.getBiome(pos);
Structure result = null;
for (Structure confstr : world.registryAccess().registryOrThrow(Registries.STRUCTURE).entrySet().stream().
filter(cS -> cS.getValue().type() == structure).map(Map.Entry::getValue).toList())
for (final Structure confstr : world.registryAccess().registryOrThrow(Registries.STRUCTURE).entrySet().stream().
filter(cS -> cS.getValue().type() == structure).map(Map.Entry::getValue).toList())
{
result = confstr;
if (confstr.biomes().contains(existingBiome)) return result;
if (confstr.biomes().contains(existingBiome))
{
return result;
}
}
return result;
}
private static ConfiguredFeature<?, ?> getDefaultFeature(Feature<?> feature, ServerLevel world, BlockPos pos, boolean tryHard)
private static ConfiguredFeature<?, ?> getDefaultFeature(final Feature<?> feature, final ServerLevel world, final BlockPos pos, final boolean tryHard)
{
List<HolderSet<PlacedFeature>> configuredStepFeatures = world.getBiome(pos).value().getGenerationSettings().features();
for (HolderSet<PlacedFeature> step: configuredStepFeatures)
for (Holder<PlacedFeature> provider: step)
final List<HolderSet<PlacedFeature>> configuredStepFeatures = world.getBiome(pos).value().getGenerationSettings().features();
for (final HolderSet<PlacedFeature> step : configuredStepFeatures)
{
for (final Holder<PlacedFeature> provider : step)
{
if (provider.value().feature().value().feature() == feature)
{
return provider.value().feature().value();
}
}
if (!tryHard) return null;
}
if (!tryHard)
{
return null;
}
return world.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).entrySet().stream().
filter(cS -> cS.getValue().feature() == feature).
findFirst().map(Map.Entry::getValue).orElse(null);
}
public static <T extends FeatureConfiguration> StructureStart shouldStructureStartAt(ServerLevel world, BlockPos pos, Structure structure, boolean computeBox)
public static <T extends FeatureConfiguration> StructureStart shouldStructureStartAt(final ServerLevel world, final BlockPos pos, final Structure structure, final boolean computeBox)
{
//long seed = world.getSeed();
RandomState seed = world.getChunkSource().randomState();
ChunkGenerator generator = world.getChunkSource().getGenerator();
ChunkGeneratorInterface cgi = (ChunkGeneratorInterface) generator;
List<StructurePlacement> structureConfig = cgi.getPlacementsForFeatureCM(world, structure);
ChunkPos chunkPos = new ChunkPos(pos);
boolean couldPlace = structureConfig.stream().anyMatch(p -> p.isStructureChunk(world.getChunkSource().getGeneratorState(), chunkPos.x, chunkPos.z));
if (!couldPlace) return null;
final ServerChunkCache chunkSource = world.getChunkSource();
final RandomState seed = chunkSource.randomState();
final ChunkGenerator generator = chunkSource.getGenerator();
final ChunkGeneratorStructureState structureState = chunkSource.getGeneratorState();
final List<StructurePlacement> structureConfig = structureState.getPlacementsForStructure(Holder.direct(structure));
final ChunkPos chunkPos = new ChunkPos(pos);
final boolean couldPlace = structureConfig.stream().anyMatch(p -> p.isStructureChunk(structureState, chunkPos.x, chunkPos.z));
if (!couldPlace)
{
return null;
}
final HolderSet<Biome> structureBiomes = structure.biomes();
if (!computeBox) {
if (!computeBox)
{
//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(
world.registryAccess(), generator, generator.getBiomeSource(),
@@ -227,26 +257,30 @@ public class FeatureGenerator
return StructureStart.INVALID_START;
}
}
else {
else
{
final StructureStart filledStructure = structure.generate(
world.registryAccess(), generator, generator.getBiomeSource(), seed, world.getStructureManager(),
world.getSeed(), chunkPos, 0, world, structureBiomes::contains);
if (filledStructure != null && filledStructure.isValid()) {
if (filledStructure != null && filledStructure.isValid())
{
return filledStructure;
}
}
return null;
}
private static TreeConfiguration.TreeConfigurationBuilder createTree(Block block, Block block2, int i, int j, int k, int l) {
private static TreeConfiguration.TreeConfigurationBuilder createTree(final Block block, final Block block2, final int i, final int j, final int k, final int l)
{
return new TreeConfiguration.TreeConfigurationBuilder(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));
}
public static final Map<String, Function<ServerLevel, Thing>> featureMap = new HashMap<>() {{
public static final Map<String, Function<ServerLevel, Thing>> featureMap = new HashMap<>()
{{
put("oak_bees", l -> simpleTree( createTree(Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build()));
put("fancy_oak_bees", l -> simpleTree( (new TreeConfiguration.TreeConfigurationBuilder(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)))).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build()));
put("birch_bees", l -> simpleTree( createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build()));
put("oak_bees", l -> simpleTree(createTree(Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build()));
put("fancy_oak_bees", l -> simpleTree((new TreeConfiguration.TreeConfigurationBuilder(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)))).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build()));
put("birch_bees", l -> simpleTree(createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build()));
put("coral_tree", l -> simplePlop(Feature.CORAL_TREE, FeatureConfiguration.NONE));
@@ -258,7 +292,7 @@ public class FeatureGenerator
PlacementUtils.inlinePlaced(Feature.CORAL_MUSHROOM, FeatureConfiguration.NONE)
))));
put("bastion_remnant_units", l -> {
RegistryAccess regs = l.registryAccess();
final RegistryAccess regs = l.registryAccess();
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
@@ -288,7 +322,7 @@ public class FeatureGenerator
);
});
put("bastion_remnant_hoglin_stable", l -> {
RegistryAccess regs = l.registryAccess();
final RegistryAccess regs = l.registryAccess();
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
@@ -317,7 +351,7 @@ public class FeatureGenerator
);
});
put("bastion_remnant_treasure", l -> {
RegistryAccess regs = l.registryAccess();
final RegistryAccess regs = l.registryAccess();
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
@@ -346,7 +380,7 @@ public class FeatureGenerator
);
});
put("bastion_remnant_bridge", l -> {
RegistryAccess regs = l.registryAccess();
final RegistryAccess regs = l.registryAccess();
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
@@ -377,28 +411,29 @@ public class FeatureGenerator
}};
public static boolean plopAnywhere(Structure structure, ServerLevel world, BlockPos pos, ChunkGenerator generator, boolean wireOnly)
public static boolean plopAnywhere(final Structure structure, final ServerLevel world, final BlockPos pos, final ChunkGenerator generator, final boolean wireOnly)
{
CarpetSettings.skipGenerationChecks.set(true);
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
checks.set(true);
try
{
StructureStart start = structure.generate(world.registryAccess(), generator, generator.getBiomeSource(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), new ChunkPos(pos), 0, world, b -> true );
final StructureStart start = structure.generate(world.registryAccess(), generator, generator.getBiomeSource(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), new ChunkPos(pos), 0, world, b -> true);
if (start == StructureStart.INVALID_START)
{
return false;
}
RandomSource rand = RandomSource.create(world.getRandom().nextInt());
int j = pos.getX() >> 4;
int k = pos.getZ() >> 4;
long chId = ChunkPos.asLong(j, k);
final RandomSource rand = RandomSource.create(world.getRandom().nextInt());
final int j = pos.getX() >> 4;
final int k = pos.getZ() >> 4;
final long chId = ChunkPos.asLong(j, k);
world.getChunk(j, k).setStartForStructure(structure, start);
world.getChunk(j, k).addReferenceForStructure(structure, chId);
BoundingBox box = start.getBoundingBox();
final BoundingBox box = start.getBoundingBox();
if (!wireOnly)
{
Registry<Structure> registry3 = world.registryAccess().registryOrThrow(Registries.STRUCTURE);
final Registry<Structure> registry3 = world.registryAccess().registryOrThrow(Registries.STRUCTURE);
world.setCurrentlyGenerating(() -> {
Objects.requireNonNull(structure);
return registry3.getResourceKey(structure).map(Object::toString).orElseGet(structure::toString);
@@ -406,29 +441,32 @@ public class FeatureGenerator
start.placeInChunk(world, world.structureManager(), generator, rand, box, new ChunkPos(j, k));
}
//structurestart.notifyPostProcessAt(new ChunkPos(j, k));
int i = Math.max(box.getXSpan(),box.getZSpan())/16+1;
final int i = Math.max(box.getXSpan(), box.getZSpan()) / 16 + 1;
//int i = getRadius();
for (int k1 = j - i; k1 <= j + i; ++k1)
{
for (int l1 = k - i; l1 <= k + i; ++l1)
{
if (k1 == j && l1 == k) continue;
if (box.intersects(k1<<4, l1<<4, (k1<<4) + 15, (l1<<4) + 15))
if (k1 == j && l1 == k)
{
continue;
}
if (box.intersects(k1 << 4, l1 << 4, (k1 << 4) + 15, (l1 << 4) + 15))
{
world.getChunk(k1, l1).addReferenceForStructure(structure, chId);
}
}
}
}
catch (Exception booboo)
catch (final Exception booboo)
{
CarpetSettings.LOG.error("Unknown Exception while plopping structure: "+booboo, booboo);
CarpetScriptServer.LOG.error("Unknown Exception while plopping structure: " + booboo, booboo);
return false;
}
finally
{
CarpetSettings.skipGenerationChecks.set(false);
checks.set(false);
}
return true;
}
@@ -0,0 +1,42 @@
package carpet.script.utils;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.commands.arguments.ParticleArgument;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
import java.util.HashMap;
import java.util.Map;
public class ParticleParser
{
private static final Map<String, ParticleOptions> particleCache = new HashMap<>(); // we reset this on reloads, but probably need something better
private static ParticleOptions parseParticle(final String name, final HolderLookup<ParticleType<?>> lookup)
{
try
{
return ParticleArgument.readParticle(new StringReader(name), lookup);
}
catch (final CommandSyntaxException e)
{
throw new IllegalArgumentException("No such particle: " + name);
}
}
public static ParticleOptions getEffect(final String name, final HolderLookup<ParticleType<?>> lookup)
{
if (name == null)
{
return null;
}
return particleCache.computeIfAbsent(name, particle -> parseParticle(particle, lookup));
}
public static void resetCache()
{
particleCache.clear();
}
}
@@ -1,11 +1,11 @@
package carpet.script.utils;
import carpet.CarpetSettings;
import carpet.helpers.ParticleDisplay;
import carpet.network.ServerNetworkHandler;
import carpet.script.CarpetScriptServer;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.language.Sys;
import carpet.script.utils.shapes.ShapeDirection;
import carpet.script.value.AbstractListValue;
@@ -149,7 +149,7 @@ public class ShapeDispatcher
final List<ServerPlayer> alternativePlayers = new ArrayList<>();
for (final ServerPlayer player : players)
{
(ServerNetworkHandler.isValidCarpetPlayer(player) ? clientPlayers : alternativePlayers).add(player);
(Carpet.isValidCarpetPlayer(player) ? clientPlayers : alternativePlayers).add(player);
}
if (!clientPlayers.isEmpty())
{
@@ -162,14 +162,14 @@ public class ShapeDispatcher
{
tagcount = 0;
final Tag finalTag = tag;
clientPlayers.forEach(p -> ServerNetworkHandler.sendCustomCommand(p, "scShapes", finalTag));
clientPlayers.forEach(p -> Vanilla.sendScarpetShapesDataToPlayer(p, finalTag));
tag = new ListTag();
}
}
final Tag finalTag = tag;
if (!tag.isEmpty())
{
clientPlayers.forEach(p -> ServerNetworkHandler.sendCustomCommand(p, "scShapes", finalTag));
clientPlayers.forEach(p -> Vanilla.sendScarpetShapesDataToPlayer(p, finalTag));
}
}
if (!alternativePlayers.isEmpty())
@@ -184,7 +184,7 @@ public class ShapeDispatcher
{
try
{
return ParticleDisplay.getEffect(name, regs.lookupOrThrow(Registries.PARTICLE_TYPE));
return ParticleParser.getEffect(name, regs.lookupOrThrow(Registries.PARTICLE_TYPE));
}
catch (final IllegalArgumentException e)
{
@@ -239,7 +239,7 @@ public class ShapeDispatcher
final Param decoder = Param.of.get(key);
if (decoder == null)
{
CarpetSettings.LOG.info("Unknown parameter for shape: " + key);
CarpetScriptServer.LOG.info("Unknown parameter for shape: " + key);
return null;
}
final Value decodedValue = decoder.decode(tag.get(key), level);
@@ -248,13 +248,13 @@ public class ShapeDispatcher
final Value shapeValue = options.get("shape");
if (shapeValue == null)
{
CarpetSettings.LOG.info("Shape id missing in " + String.join(", ", tag.getAllKeys()));
CarpetScriptServer.LOG.info("Shape id missing in " + String.join(", ", tag.getAllKeys()));
return null;
}
final BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeValue.getString());
if (factory == null)
{
CarpetSettings.LOG.info("Unknown shape: " + shapeValue.getString());
CarpetScriptServer.LOG.info("Unknown shape: " + shapeValue.getString());
return null;
}
try
@@ -263,7 +263,7 @@ public class ShapeDispatcher
}
catch (final InternalExpressionException exc)
{
CarpetSettings.LOG.info(exc.getMessage());
CarpetScriptServer.LOG.info(exc.getMessage());
}
return null;
}
@@ -2022,7 +2022,7 @@ public class ShapeDispatcher
new NumericValue(e.getZ())
);
}
CarpetSettings.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");
}
@@ -1,9 +1,9 @@
package carpet.script.utils;
import carpet.CarpetSettings;
import carpet.mixins.ShulkerBoxAccessMixin;
import carpet.script.CarpetScriptServer;
import carpet.script.external.Carpet;
import carpet.script.external.VanillaClient;
import carpet.script.utils.shapes.ShapeDirection;
import carpet.utils.CarpetProfiler;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder;
@@ -82,7 +82,7 @@ public class ShapesRenderer
public void render(final PoseStack matrices, final Camera camera, final float partialTick)
{
final CarpetProfiler.ProfilerToken token = CarpetProfiler.start_section(null, "Scarpet client", CarpetProfiler.TYPE.GENERAL);
final Runnable token = Carpet.startProfilerSection("Scarpet client");
//Camera camera = this.client.gameRenderer.getCamera();
final ClientLevel iWorld = this.client.level;
final ResourceKey<Level> dimensionType = iWorld.dimension();
@@ -163,17 +163,17 @@ public class ShapesRenderer
RenderSystem.depthMask(true);
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
CarpetProfiler.end_current_section(token);
token.run();
}
public void addShapes(final ListTag tag)
{
final CarpetProfiler.ProfilerToken token = CarpetProfiler.start_section(null, "Scarpet client", CarpetProfiler.TYPE.GENERAL);
final Runnable token = Carpet.startProfilerSection("Scarpet client");
for (int i = 0, count = tag.size(); i < count; i++)
{
addShape(tag.getCompound(i));
}
CarpetProfiler.end_current_section(token);
token.run();
}
public void addShape(final CompoundTag tag)
@@ -187,7 +187,7 @@ public class ShapesRenderer
shapeFactory = renderedShapes.get(tag.getString("shape"));
if (shapeFactory == null)
{
CarpetSettings.LOG.info("Unrecognized shape: " + tag.getString("shape"));
CarpetScriptServer.LOG.info("Unrecognized shape: " + tag.getString("shape"));
}
else
{
@@ -217,11 +217,11 @@ public class ShapesRenderer
public void renewShapes()
{
final CarpetProfiler.ProfilerToken token = CarpetProfiler.start_section(null, "Scarpet client", CarpetProfiler.TYPE.GENERAL);
final Runnable token = Carpet.startProfilerSection("Scarpet client");
shapes.values().forEach(el -> el.values().forEach(shape -> shape.expiryTick++));
labels.values().forEach(el -> el.values().forEach(shape -> shape.expiryTick++));
CarpetProfiler.end_current_section(token);
token.run();
}
public abstract static class RenderedShape<T extends ShapeDispatcher.ExpiringShape>
@@ -468,7 +468,7 @@ public class ShapesRenderer
poseStack.mulPose(direction.getRotation());
poseStack.scale(1.0F, -1.0F, -1.0F);
poseStack.translate(0.0, -1.0, 0.0);
final ShulkerModel<?> model = ((ShulkerBoxAccessMixin) client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity)).getModel();
final ShulkerModel<?> model = VanillaClient.ShulkerBoxRenderer_model(client.getBlockEntityRenderDispatcher().getRenderer(shulkerBoxBlockEntity));
final ModelPart modelPart = model.getLid();
modelPart.setPos(0.0F, 24.0F - shulkerBoxBlockEntity.getProgress(f) * 0.5F * 16.0F, 0.0F);
modelPart.yRot = 270.0F * shulkerBoxBlockEntity.getProgress(f) * (float) (Math.PI / 180.0);
@@ -561,7 +561,7 @@ public class ShapesRenderer
}
catch (final ClassCastException ignored)
{
CarpetSettings.LOG.error("shape " + rshape.shape.getClass() + " cannot cast to a Label");
CarpetScriptServer.LOG.error("shape " + rshape.shape.getClass() + " cannot cast to a Label");
}
}
}
@@ -1,6 +1,6 @@
package carpet.script.utils;
import carpet.CarpetSettings;
import carpet.script.external.Vanilla;
import com.mojang.brigadier.ResultConsumer;
import net.minecraft.commands.CommandSigningContext;
import net.minecraft.commands.CommandSource;
@@ -42,14 +42,14 @@ public class SnoopyCommandSource extends CommandSourceStack
public SnoopyCommandSource(final CommandSourceStack original, final Component[] error, final List<Component> chatOutput)
{
super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), CarpetSettings.runPermissionLevel,
super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()),
original.getTextName(), original.getDisplayName(), original.getServer(), original.getEntity(), false,
(ctx, succ, res) -> {
}, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer()));
this.output = CommandSource.NULL;
this.position = original.getPosition();
this.world = original.getLevel();
this.level = CarpetSettings.runPermissionLevel;
this.level = Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer());
this.simpleName = original.getTextName();
this.name = original.getDisplayName();
this.server = original.getServer();
@@ -1,11 +1,9 @@
package carpet.script.utils;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.api.settings.CarpetRule;
import carpet.api.settings.RuleHelper;
import carpet.script.CarpetContext;
import carpet.script.CarpetScriptHost;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
import carpet.script.value.ListValue;
@@ -14,10 +12,7 @@ import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.api.settings.SettingsManager;
import com.sun.management.OperatingSystemMXBean;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.SharedConstants;
import net.minecraft.server.packs.PackType;
import net.minecraft.world.level.GameRules;
@@ -29,7 +24,6 @@ import net.minecraft.world.phys.Vec2;
import java.lang.management.ManagementFactory;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -93,14 +87,14 @@ public class SystemInfo
put("game_view_distance", c -> new NumericValue(c.server().getPlayerList().getViewDistance()));
put("game_mod_name", c -> StringValue.of(c.server().getServerModName()));
put("game_version", c -> StringValue.of(c.server().getServerVersion()));
put("game_target", c -> StringValue.of(CarpetSettings.releaseTarget));
put("game_target", c -> StringValue.of(Vanilla.MinecraftServer_getReleaseTarget(c.server())));
put("game_protocol", c -> NumericValue.of(SharedConstants.getProtocolVersion()));
put("game_major_target", c -> {
final String[] vers = CarpetSettings.releaseTarget.split("\\.");
final String[] vers = Vanilla.MinecraftServer_getReleaseTarget(c.server()).split("\\.");
return NumericValue.of((vers.length > 1) ? Integer.parseInt(vers[1]) : 0);
});
put("game_minor_target", c -> {
final String[] vers = CarpetSettings.releaseTarget.split("\\.");
final String[] vers = Vanilla.MinecraftServer_getReleaseTarget(c.server()).split("\\.");
return NumericValue.of((vers.length > 2) ? Integer.parseInt(vers[2]) : 0);
});
put("game_stable", c -> BooleanValue.of(SharedConstants.getCurrentVersion().isStable()));
@@ -133,15 +127,8 @@ public class SystemInfo
}
return whitelist;
});
put("server_dev_environment", c -> BooleanValue.of(FabricLoader.getInstance().isDevelopmentEnvironment()));
put("server_mods", c -> {
final Map<Value, Value> ret = new HashMap<>();
for (final ModContainer mod : FabricLoader.getInstance().getAllMods())
{
ret.put(new StringValue(mod.getMetadata().getId()), new StringValue(mod.getMetadata().getVersion().getFriendlyString()));
}
return MapValue.wrap(ret);
});
put("server_dev_environment", c -> BooleanValue.of(Vanilla.isDevelopmentEnvironment()));
put("server_mods", c -> Vanilla.getServerMods(c.server()));
put("server_last_tick_times", c -> {
//assuming we are in the tick world section
// might be off one tick when run in the off tasks or asynchronously.
@@ -181,20 +168,7 @@ public class SystemInfo
OperatingSystemMXBean.class);
return new NumericValue(osBean.getProcessCpuLoad());
});
put("world_carpet_rules", c -> {
final Collection<CarpetRule<?>> rules = CarpetServer.settingsManager.getCarpetRules();
final MapValue carpetRules = new MapValue(Collections.emptyList());
rules.forEach(rule -> carpetRules.put(new StringValue(rule.name()), new StringValue(RuleHelper.toRuleString(rule.value()))));
CarpetServer.extensions.forEach(e -> {
final SettingsManager manager = e.extensionSettingsManager();
if (manager == null)
{
return;
}
manager.getCarpetRules().forEach(rule -> carpetRules.put(new StringValue(manager.identifier() + ":" + rule.name()), new StringValue(RuleHelper.toRuleString(rule.value()))));
});
return carpetRules;
});
put("world_carpet_rules", c -> Carpet.getAllCarpetRules());
put("world_gamerules", c -> {
final Map<Value, Value> rules = new HashMap<>();
final GameRules gameRules = c.level().getGameRules();
@@ -217,9 +191,7 @@ public class SystemInfo
final Vec2 rotation = c.source().getRotation();
return ListValue.of(new NumericValue(rotation.x), new NumericValue(rotation.y));
});
put("scarpet_version", c -> StringValue.of(CarpetSettings.carpetVersion));
put("scarpet_version", c -> StringValue.of(Carpet.getCarpetVersion()));
}};
public static Value get(final String what, final CarpetContext cc)
@@ -1,7 +1,8 @@
package carpet.helpers;
package carpet.script.utils;
import java.util.Optional;
import java.util.function.Predicate;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
@@ -13,45 +14,45 @@ import net.minecraft.world.phys.Vec3;
public class Tracer
{
public static HitResult rayTrace(Entity source, float partialTicks, double reach, boolean fluids)
public static HitResult rayTrace(final Entity source, final float partialTicks, final double reach, final boolean fluids)
{
BlockHitResult blockHit = rayTraceBlocks(source, partialTicks, reach, fluids);
final BlockHitResult blockHit = rayTraceBlocks(source, partialTicks, reach, fluids);
double maxSqDist = reach * reach;
if (blockHit != null)
{
maxSqDist = blockHit.getLocation().distanceToSqr(source.getEyePosition(partialTicks));
}
EntityHitResult entityHit = rayTraceEntities(source, partialTicks, reach, maxSqDist);
final EntityHitResult entityHit = rayTraceEntities(source, partialTicks, reach, maxSqDist);
return entityHit == null ? blockHit : entityHit;
}
public static BlockHitResult rayTraceBlocks(Entity source, float partialTicks, double reach, boolean fluids)
public static BlockHitResult rayTraceBlocks(final Entity source, final float partialTicks, final double reach, final boolean fluids)
{
Vec3 pos = source.getEyePosition(partialTicks);
Vec3 rotation = source.getViewVector(partialTicks);
Vec3 reachEnd = pos.add(rotation.x * reach, rotation.y * reach, rotation.z * reach);
final Vec3 pos = source.getEyePosition(partialTicks);
final Vec3 rotation = source.getViewVector(partialTicks);
final Vec3 reachEnd = pos.add(rotation.x * reach, rotation.y * reach, rotation.z * reach);
return source.level.clip(new ClipContext(pos, reachEnd, ClipContext.Block.OUTLINE, fluids ?
ClipContext.Fluid.ANY : ClipContext.Fluid.NONE, source));
}
public static EntityHitResult rayTraceEntities(Entity source, float partialTicks, double reach, double maxSqDist)
public static EntityHitResult rayTraceEntities(final Entity source, final float partialTicks, final double reach, final double maxSqDist)
{
Vec3 pos = source.getEyePosition(partialTicks);
Vec3 reachVec = source.getViewVector(partialTicks).scale(reach);
AABB box = source.getBoundingBox().expandTowards(reachVec).inflate(1);
final Vec3 pos = source.getEyePosition(partialTicks);
final Vec3 reachVec = source.getViewVector(partialTicks).scale(reach);
final AABB box = source.getBoundingBox().expandTowards(reachVec).inflate(1);
return rayTraceEntities(source, pos, pos.add(reachVec), box, e -> !e.isSpectator() && e.isPickable(), maxSqDist);
}
public static EntityHitResult rayTraceEntities(Entity source, Vec3 start, Vec3 end, AABB box, Predicate<Entity> predicate, double maxSqDistance)
public static EntityHitResult rayTraceEntities(final Entity source, final Vec3 start, final Vec3 end, final AABB box, final Predicate<Entity> predicate, final double maxSqDistance)
{
Level world = source.level;
final Level world = source.level;
double targetDistance = maxSqDistance;
Entity target = null;
Vec3 targetHitPos = null;
for (Entity current : world.getEntities(source, box, predicate))
for (final Entity current : world.getEntities(source, box, predicate))
{
AABB currentBox = current.getBoundingBox().inflate(current.getPickRadius());
Optional<Vec3> currentHit = currentBox.clip(start, end);
final AABB currentBox = current.getBoundingBox().inflate(current.getPickRadius());
final Optional<Vec3> currentHit = currentBox.clip(start, end);
if (currentBox.contains(start))
{
if (targetDistance >= 0)
@@ -63,8 +64,8 @@ public class Tracer
}
else if (currentHit.isPresent())
{
Vec3 currentHitPos = currentHit.get();
double currentDistance = start.distanceToSqr(currentHitPos);
final Vec3 currentHitPos = currentHit.get();
final double currentDistance = start.distanceToSqr(currentHitPos);
if (currentDistance < targetDistance || targetDistance == 0)
{
if (current.getRootVehicle() == source.getRootVehicle())
@@ -84,7 +85,6 @@ public class Tracer
}
}
}
if (target == null) return null;
return new EntityHitResult(target, targetHitPos);
return target == null ? null : new EntityHitResult(target, targetHitPos);
}
}
@@ -1,8 +1,9 @@
package carpet.script.utils;
import carpet.fakes.MinecraftServerInterface;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
//import carpet.fakes.MinecraftServerInterface;
import carpet.script.external.Vanilla;
//import net.fabricmc.api.EnvType;
//import net.fabricmc.api.Environment;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
@@ -59,7 +60,7 @@ public class WorldTools
}
return region.hasChunk(chpos);
}
final Path regionsFolder = ((MinecraftServerInterface) world.getServer()).getCMSession().getDimensionPath(world.dimension()).resolve("region");
final Path regionsFolder = Vanilla.MinecraftServer_storageSource(world.getServer()).getDimensionPath(world.dimension()).resolve("region");
final Path regionPath = regionsFolder.resolve(currentRegionName);
if (!regionPath.toFile().exists())
{
@@ -169,7 +170,7 @@ public class WorldTools
}
}
/*
private static class NoopWorldGenerationProgressListener implements ChunkProgressListener
{
@Override
@@ -182,7 +183,7 @@ public class WorldTools
{
}
@Environment(EnvType.CLIENT)
//@Environment(EnvType.CLIENT)
@Override
public void start()
{
@@ -195,4 +196,6 @@ public class WorldTools
}
public static final ChunkProgressListener NOOP_LISTENER = new NoopWorldGenerationProgressListener();
*/
}
@@ -3,7 +3,6 @@ package carpet.script.value;
import carpet.script.exception.InternalExpressionException;
import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
public abstract class AbstractListValue extends Value implements Iterable<Value>
@@ -21,7 +21,6 @@ import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.GlobalPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.StringTag;
@@ -38,7 +37,6 @@ import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
@@ -46,7 +44,6 @@ public class BlockValue extends Value
{
private BlockState blockState;
private final BlockPos pos;
@NotNull
private final Level world;
private CompoundTag data;
@@ -143,7 +140,7 @@ public class BlockValue extends Value
}
public BlockValue(final BlockState state, @NotNull final Level world, final BlockPos position)
public BlockValue(final BlockState state, final Level world, final BlockPos position)
{
this.world = world;
blockState = state;
@@ -151,7 +148,7 @@ public class BlockValue extends Value
data = null;
}
public BlockValue(final BlockState state, @NotNull final Level world, final BlockPos position, final CompoundTag nbt)
public BlockValue(final BlockState state, final Level world, final BlockPos position, final CompoundTag nbt)
{
this.world = world;
blockState = state;
@@ -1,19 +1,14 @@
package carpet.script.value;
import carpet.fakes.EntityInterface;
import carpet.fakes.ItemEntityInterface;
import carpet.fakes.LivingEntityInterface;
import carpet.fakes.MobEntityInterface;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInteractionManagerInterface;
import carpet.helpers.Tracer;
import carpet.network.ServerNetworkHandler;
import carpet.patches.EntityPlayerMPFake;
import carpet.script.external.Vanilla;
import carpet.script.utils.Tracer;
import carpet.script.CarpetContext;
import carpet.script.CarpetScriptServer;
import carpet.script.EntityEventsGroup;
import carpet.script.argument.Vector3Argument;
import carpet.script.exception.InternalExpressionException;
import carpet.script.external.Carpet;
import carpet.script.utils.EntityTools;
import carpet.script.utils.InputValidator;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -96,7 +91,6 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
import static carpet.utils.MobAI.genericJump;
// TODO: decide whether copy(entity) should duplicate entity in the world.
public class EntityValue extends Value
@@ -136,7 +130,7 @@ public class EntityValue extends Value
public Entity getEntity()
{
if (entity instanceof ServerPlayer && ((ServerPlayerEntityInterface) entity).isInvalidEntityObject())
if (entity instanceof final ServerPlayer serverPlayer && Vanilla.ServerPlayer_isInvalidEntityObject(serverPlayer))
{
final ServerPlayer newPlayer = entity.getServer().getPlayerList().getPlayer(entity.getUUID());
if (newPlayer != null)
@@ -449,7 +443,7 @@ public class EntityValue extends Value
put("is_ridden", (e, a) -> BooleanValue.of(e.isVehicle()));
put("passengers", (e, a) -> ListValue.wrap(e.getPassengers().stream().map(EntityValue::new)));
put("mount", (e, a) -> (e.getVehicle() != null) ? new EntityValue(e.getVehicle()) : Value.NULL);
put("unmountable", (e, a) -> BooleanValue.of(((EntityInterface) e).isPermanentVehicle()));
put("unmountable", (e, a) -> BooleanValue.of(Vanilla.Entity_isPermanentVehicle(e)));
// deprecated
put("tags", (e, a) -> ListValue.wrap(e.getTags().stream().map(StringValue::new)));
@@ -505,9 +499,9 @@ public class EntityValue extends Value
put("offering_flower", (e, a) -> e instanceof final IronGolem ig ? BooleanValue.of(ig.getOfferFlowerTick() > 0) : Value.NULL);
put("item", (e, a) -> e instanceof final ItemEntity ie ? ValueConversions.of(ie.getItem(), e.getServer().registryAccess()) : e instanceof final ItemFrame frame ? ValueConversions.of(frame.getItem(), e.getServer().registryAccess()) : Value.NULL);
put("count", (e, a) -> (e instanceof final ItemEntity ie) ? new NumericValue(ie.getItem().getCount()) : Value.NULL);
put("pickup_delay", (e, a) -> (e instanceof ItemEntity) ? new NumericValue(((ItemEntityInterface) e).getPickupDelayCM()) : Value.NULL);
put("portal_cooldown", (e, a) -> new NumericValue(((EntityInterface) e).getPublicNetherPortalCooldown()));
put("portal_timer", (e, a) -> new NumericValue(((EntityInterface) e).getPortalTimer()));
put("pickup_delay", (e, a) -> (e instanceof final ItemEntity ie) ? new NumericValue(Vanilla.ItemEntity_getPickupDelay(ie)) : Value.NULL);
put("portal_cooldown", (e, a) -> new NumericValue(Vanilla.Entity_getPublicNetherPortalCooldown(e)));
put("portal_timer", (e, a) -> new NumericValue(Vanilla.Entity_getPortalTimer(e)));
// ItemEntity -> despawn timer via ssGetAge
put("is_baby", (e, a) -> (e instanceof final LivingEntity le) ? BooleanValue.of(le.isBaby()) : Value.NULL);
put("target", (e, a) -> {
@@ -544,7 +538,7 @@ public class EntityValue extends Value
put("swimming", (e, a) -> e.isSwimming() ? Value.TRUE : Value.FALSE);
put("swinging", (e, a) -> e instanceof final LivingEntity le ? BooleanValue.of(le.swinging) : Value.NULL);
put("air", (e, a) -> new NumericValue(e.getAirSupply()));
put("language", (e, a) -> !(e instanceof ServerPlayer) ? NULL : StringValue.of(((ServerPlayerEntityInterface) e).getLanguage()));
put("language", (e, a) -> !(e instanceof final ServerPlayer p) ? NULL : StringValue.of(Vanilla.ServerPlayer_getLanguage(p)));
put("persistence", (e, a) -> e instanceof final Mob mob ? BooleanValue.of(mob.isPersistenceRequired()) : Value.NULL);
put("hunger", (e, a) -> e instanceof final Player player ? new NumericValue(player.getFoodData().getFoodLevel()) : Value.NULL);
put("saturation", (e, a) -> e instanceof final Player player ? new NumericValue(player.getFoodData().getSaturationLevel()) : Value.NULL);
@@ -554,7 +548,7 @@ public class EntityValue extends Value
put("xp_level", (e, a) -> e instanceof final Player player ? new NumericValue(player.experienceLevel) : Value.NULL);
put("xp_progress", (e, a) -> e instanceof final Player player ? new NumericValue(player.experienceProgress) : Value.NULL);
put("score", (e, a) -> e instanceof final Player player ? new NumericValue(player.getScore()) : Value.NULL);
put("jumping", (e, a) -> e instanceof LivingEntity ? ((LivingEntityInterface) e).isJumpingCM() ? Value.TRUE : Value.FALSE : Value.NULL);
put("jumping", (e, a) -> e instanceof final LivingEntity le ? Vanilla.LivingEntity_isJumping(le) ? Value.TRUE : Value.FALSE : Value.NULL);
put("gamemode", (e, a) -> e instanceof final ServerPlayer sp ? new StringValue(sp.gameMode.getGameModeForPlayer().getName()) : Value.NULL);
put("path", (e, a) -> {
if (e instanceof final Mob mob)
@@ -610,9 +604,10 @@ public class EntityValue extends Value
put("player_type", (e, a) -> {
if (e instanceof final Player p)
{
if (e instanceof final EntityPlayerMPFake fake)
final String moddedType = Carpet.isModdedPlayer(p);
if (moddedType != null)
{
return new StringValue(fake.isAShadow ? "shadow" : "fake");
return StringValue.of(moddedType);
}
final MinecraftServer server = p.getCommandSenderWorld().getServer();
if (server.isDedicatedServer())
@@ -635,7 +630,7 @@ public class EntityValue extends Value
return Value.NULL;
});
put("client_brand", (e, a) -> e instanceof final ServerPlayer sp ? StringValue.of(ServerNetworkHandler.getPlayerStatus(sp)) : Value.NULL);
put("client_brand", (e, a) -> e instanceof final ServerPlayer sp ? StringValue.of(Carpet.getPlayerStatus(sp)) : Value.NULL);
put("team", (e, a) -> e.getTeam() == null ? Value.NULL : new StringValue(e.getTeam().getName()));
put("ping", (e, a) -> e instanceof final ServerPlayer sp ? new NumericValue(sp.latency) : Value.NULL);
@@ -703,8 +698,7 @@ public class EntityValue extends Value
put("active_block", (e, a) -> {
if (e instanceof final ServerPlayer sp)
{
final ServerPlayerInteractionManagerInterface manager = (ServerPlayerInteractionManagerInterface) (sp.gameMode);
final BlockPos pos = manager.getCurrentBreakingBlock();
final BlockPos pos = Vanilla.ServerPlayerGameMode_getCurrentBlockPosition(sp.gameMode);
if (pos == null)
{
return Value.NULL;
@@ -717,8 +711,7 @@ public class EntityValue extends Value
put("breaking_progress", (e, a) -> {
if (e instanceof final ServerPlayer sp)
{
final ServerPlayerInteractionManagerInterface manager = (ServerPlayerInteractionManagerInterface) (sp.gameMode);
final int progress = manager.getCurrentBlockBreakingProgress();
final int progress = Vanilla.ServerPlayerGameMode_getCurrentBlockBreakingProgress (sp.gameMode);
return progress < 0 ? Value.NULL : new NumericValue(progress);
}
return Value.NULL;
@@ -1204,7 +1197,7 @@ public class EntityValue extends Value
put("persistence", (e, v) ->
{
if (!(e instanceof Mob))
if (!(e instanceof final Mob mob))
{
return;
}
@@ -1212,7 +1205,7 @@ public class EntityValue extends Value
{
v = Value.TRUE;
}
((MobEntityInterface) e).setPersistence(v.getBoolean());
Vanilla.Mob_setPersistence(mob, v.getBoolean());
});
put("dismount", (e, v) -> e.stopRiding());
@@ -1226,7 +1219,7 @@ public class EntityValue extends Value
sp.connection.send(new ClientboundSetPassengersPacket(e));
}
});
put("unmountable", (e, v) -> ((EntityInterface) e).setPermanentVehicle(v == null || v.getBoolean()));
put("unmountable", (e, v) -> Vanilla.Entity_setPermanentVehicle(e, v == null || v.getBoolean()));
put("drop_passengers", (e, v) -> e.ejectPassengers());
put("mount_passengers", (e, v) -> {
if (v == null)
@@ -1316,8 +1309,8 @@ public class EntityValue extends Value
if (v.isNull())
{
ec.restrictTo(BlockPos.ZERO, -1);
final Map<String, Goal> tasks = ((MobEntityInterface) ec).getTemporaryTasks();
((MobEntityInterface) ec).getAI(false).removeGoal(tasks.get("home"));
final Map<String, Goal> tasks = Vanilla.Mob_getTemporaryTasks(ec);
Vanilla.Mob_getAI(ec, false).removeGoal(tasks.get("home"));
tasks.remove("home");
return;
}
@@ -1349,12 +1342,12 @@ public class EntityValue extends Value
}
ec.restrictTo(pos, distance);
final Map<String, Goal> tasks = ((MobEntityInterface) ec).getTemporaryTasks();
final Map<String, Goal> tasks = Vanilla.Mob_getTemporaryTasks(ec);
if (!tasks.containsKey("home"))
{
final Goal task = new MoveTowardsRestrictionGoal(ec, 1.0D);
tasks.put("home", task);
((MobEntityInterface) ec).getAI(false).addGoal(10, task);
Vanilla.Mob_getAI(ec, false).addGoal(10, task);
}
}); //requires mixing
@@ -1430,7 +1423,7 @@ public class EntityValue extends Value
{
throw new InternalExpressionException("'portal_cooldown' requires a value to set");
}
((EntityInterface) e).setPublicNetherPortalCooldown(NumericValue.asNumber(v).getInt());
Vanilla.Entity_setPublicNetherPortalCooldown(e, NumericValue.asNumber(v).getInt());
});
put("portal_timer", (e, v) ->
@@ -1439,7 +1432,7 @@ public class EntityValue extends Value
{
throw new InternalExpressionException("'portal_timer' requires a value to set");
}
((EntityInterface) e).setPortalTimer(NumericValue.asNumber(v).getInt());
Vanilla.Entity_setPortalTimer(e, NumericValue.asNumber(v).getInt());
});
put("ai", (e, v) ->
@@ -1555,13 +1548,13 @@ public class EntityValue extends Value
});
put("jump", (e, v) -> {
if (e instanceof LivingEntity)
if (e instanceof final LivingEntity le)
{
((LivingEntityInterface) e).doJumpCM();
Vanilla.LivingEntity_setJumping(le);
}
else
{
genericJump(e);
EntityTools.genericJump(e);
}
});
@@ -1671,8 +1664,7 @@ public class EntityValue extends Value
if (e instanceof final ServerPlayer sp)
{
final int progress = (a == null || a.isNull()) ? -1 : NumericValue.asNumber(a).getInt();
final ServerPlayerInteractionManagerInterface manager = (ServerPlayerInteractionManagerInterface) (sp.gameMode);
manager.setBlockBreakingProgress(progress);
Vanilla.ServerPlayerGameMode_setBlockBreakingProgress(sp.gameMode, progress);
}
});
@@ -1740,7 +1732,7 @@ public class EntityValue extends Value
{
throw new InternalExpressionException("Unknown entity event: " + eventName);
}
((EntityInterface) getEntity()).getEventContainer().addEvent(event, cc.host, fun, args);
Vanilla.Entity_getEventContainer(getEntity()).addEvent(event, cc.host, fun, args);
}
@Override
@@ -1,6 +1,6 @@
package carpet.script.value;
import carpet.CarpetSettings;
import carpet.script.CarpetScriptServer;
import carpet.script.Context;
import carpet.script.Expression;
import carpet.script.Fluff;
@@ -18,7 +18,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
@@ -200,7 +199,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
final Value param = lv.evalValue(c, Context.NONE);
if (param instanceof FunctionUnpackedArgumentsValue)
{
CarpetSettings.LOG.error("How did we get here?");
CarpetScriptServer.LOG.error("How did we get here?");
params.addAll(((ListValue) param).getItems());
}
else
@@ -1,10 +1,10 @@
package carpet.script.value;
import carpet.fakes.InventoryBearerInterface;
import carpet.script.CarpetContext;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.external.Vanilla;
import carpet.script.utils.EquipmentInventory;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -44,6 +44,7 @@ import net.minecraft.world.WorldlyContainerHolder;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySelector;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.animal.horse.AbstractHorse;
import net.minecraft.world.entity.npc.InventoryCarrier;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
@@ -280,9 +281,9 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
{
inv = io.getInventory();
}
else if (e instanceof final InventoryBearerInterface ibi)
else if (e instanceof final AbstractHorse ibi)
{
inv = ibi.getCMInventory(); // horse only
inv = Vanilla.AbstractHorse_getInventory(ibi); // horse only
}
else if (e instanceof final LivingEntity le)
{
@@ -1,9 +1,5 @@
package carpet.script.value;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.fakes.ScreenHandlerInterface;
import carpet.script.CarpetScriptHost;
import carpet.script.CarpetScriptServer;
import carpet.script.Context;
@@ -12,6 +8,7 @@ import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.InvalidCallbackException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.external.Vanilla;
import java.util.Arrays;
import java.util.HashMap;
@@ -31,7 +28,32 @@ import net.minecraft.world.SimpleContainer;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.*;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.AbstractFurnaceMenu;
import net.minecraft.world.inventory.AnvilMenu;
import net.minecraft.world.inventory.BeaconMenu;
import net.minecraft.world.inventory.BlastFurnaceMenu;
import net.minecraft.world.inventory.BrewingStandMenu;
import net.minecraft.world.inventory.CartographyTableMenu;
import net.minecraft.world.inventory.ChestMenu;
import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.inventory.ContainerListener;
import net.minecraft.world.inventory.CraftingMenu;
import net.minecraft.world.inventory.DataSlot;
import net.minecraft.world.inventory.EnchantmentMenu;
import net.minecraft.world.inventory.FurnaceMenu;
import net.minecraft.world.inventory.GrindstoneMenu;
import net.minecraft.world.inventory.HopperMenu;
import net.minecraft.world.inventory.LecternMenu;
import net.minecraft.world.inventory.LegacySmithingMenu;
import net.minecraft.world.inventory.LoomMenu;
import net.minecraft.world.inventory.MerchantMenu;
import net.minecraft.world.inventory.ShulkerBoxMenu;
import net.minecraft.world.inventory.SimpleContainerData;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.inventory.SmithingMenu;
import net.minecraft.world.inventory.SmokerMenu;
import net.minecraft.world.inventory.StonecutterMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe;
@@ -47,6 +69,7 @@ public class ScreenValue extends Value
private final FunctionValue callback;
private final String hostname;
private final ServerPlayer player;
private final CarpetScriptServer scriptServer;
public static Map<String, ScarpetScreenHandlerFactory> screenHandlerFactories;
@@ -96,6 +119,7 @@ public class ScreenValue extends Value
}
this.callback = callback;
this.hostname = c.host.getName();
this.scriptServer = (CarpetScriptServer) c.host.scriptServer();
this.player = player;
final MenuProvider factory = this.createScreenHandlerFactory();
if (factory == null)
@@ -167,18 +191,19 @@ public class ScreenValue extends Value
final Value actionValue = StringValue.of(action);
final Value dataValue = MapValue.wrap(data);
final List<Value> args = Arrays.asList(this, playerValue, actionValue, dataValue);
final CarpetScriptHost appHost = CarpetServer.scriptServer.getAppHostByName(this.hostname);
final CarpetScriptHost appHost = scriptServer.getAppHostByName(this.hostname);
if (appHost == null)
{
this.close();
this.screenHandler = null;
return false;
}
final CommandSourceStack source = player.createCommandSourceStack().withPermission(CarpetSettings.runPermissionLevel);
final int runPermissionLevel = Vanilla.MinecraftServer_getRunPermissionLevel(player.server);
final CommandSourceStack source = player.createCommandSourceStack().withPermission(runPermissionLevel);
final CarpetScriptHost executingHost = appHost.retrieveForExecution(source, player);
try
{
final Value cancelValue = executingHost.callUDF(source.withPermission(CarpetSettings.runPermissionLevel), callback, args);
final Value cancelValue = executingHost.callUDF(source, callback, args);
return cancelValue.getString().equals("cancel");
}
catch (final NullPointerException | InvalidCallbackException | IntegrityException error)
@@ -255,7 +280,7 @@ public class ScreenValue extends Value
{
if (screenHandlerClass.isInstance(this.screenHandler))
{
return ((ScreenHandlerInterface) this.screenHandler).getProperty(propertyIndex);
return Vanilla.AbstractContainerMenu_getDataSlot(this.screenHandler, propertyIndex);
}
if (!this.isOpen())
{
+2 -2
View File
@@ -1,6 +1,6 @@
package carpet.script.value;
import carpet.CarpetSettings;
import carpet.script.CarpetScriptServer;
import carpet.script.exception.InternalExpressionException;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
@@ -46,7 +46,7 @@ public abstract class Value implements Comparable<Value>, Cloneable
catch (final CloneNotSupportedException e)
{
// should not happen
CarpetSettings.LOG.error("Failed to clone variable", e);
CarpetScriptServer.LOG.error("Failed to clone variable", e);
throw new InternalExpressionException("Variable of type " + getTypeString() + " is not cloneable. Tell gnembon about it, this shoudn't happen");
}
copy.boundVariable = value;
@@ -1,10 +1,10 @@
package carpet.script.value;
import carpet.fakes.BlockPredicateInterface;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.utils.BlockInfo;
import carpet.script.external.Carpet;
import carpet.script.external.Vanilla;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.advancements.critereon.MinMaxBounds;
@@ -83,7 +83,7 @@ public class ValueConversions
public static Value of(final MaterialColor color)
{
return ListValue.of(StringValue.of(BlockInfo.mapColourName.get(color)), ofRGB(color.col));
return ListValue.of(StringValue.of(Carpet.getMapColorNames().get(color)), ofRGB(color.col));
}
public static <T extends Number> Value of(final MinMaxBounds<T> range)
@@ -451,13 +451,13 @@ public class ValueConversions
public static Value ofBlockPredicate(final RegistryAccess registryAccess, final Predicate<BlockInWorld> blockPredicate)
{
final BlockPredicateInterface predicateData = (BlockPredicateInterface) blockPredicate;
final Vanilla.BlockPredicatePayload payload = Vanilla.BlockPredicatePayload.of(blockPredicate);
final Registry<Block> blocks = registryAccess.registryOrThrow(Registries.BLOCK);
return ListValue.of(
predicateData.getCMBlockState() == null ? Value.NULL : of(blocks.getKey(predicateData.getCMBlockState().getBlock())),
predicateData.getCMBlockTagKey() == null ? Value.NULL : of(blocks.getTag(predicateData.getCMBlockTagKey()).get().key()),
MapValue.wrap(predicateData.getCMProperties()),
predicateData.getCMDataTag() == null ? Value.NULL : new NBTSerializableValue(predicateData.getCMDataTag())
payload.state() == null ? Value.NULL : of(blocks.getKey(payload.state().getBlock())),
payload.tagKey() == null ? Value.NULL : of(blocks.getTag(payload.tagKey()).get().key()),
MapValue.wrap(payload.properties()),
payload.tag() == null ? Value.NULL : new NBTSerializableValue(payload.tag())
);
}
+3 -24
View File
@@ -13,6 +13,7 @@ import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@@ -38,10 +39,10 @@ public class MobAI
return currentTrackers.contains(type);
}
public static void clearTracking(EntityType<? extends Entity> etype)
public static void clearTracking(final MinecraftServer server, EntityType<? extends Entity> etype)
{
aiTrackers.remove(etype);
for(ServerLevel world : CarpetServer.minecraft_server.getAllLevels() )
for(ServerLevel world : server.getAllLevels() )
{
for (Entity e: world.getEntities(etype, Entity::hasCustomName))
{
@@ -86,26 +87,4 @@ public class MobAI
types = applicableTypes;
}
}
/**
* Not a replacement for living entity jump() - this barely is to allow other entities that can't jump in vanilla to 'jump'
* @param e
*/
public static void genericJump(Entity e)
{
if (!e.isOnGround() && !e.isInWaterOrBubble() && !e.isInLava()) return;
float m = e.level.getBlockState(e.blockPosition()).getBlock().getJumpFactor();
float g = e.level.getBlockState(new BlockPos(e.getX(), e.getBoundingBox().minY - 0.5000001D, e.getZ())).getBlock().getJumpFactor();
float jumpVelocityMultiplier = (double) m == 1.0D ? g : m;
float jumpStrength = (0.42F * jumpVelocityMultiplier);
Vec3 vec3d = e.getDeltaMovement();
e.setDeltaMovement(vec3d.x, jumpStrength, vec3d.z);
if (e.isSprinting())
{
float u = e.getYRot() * 0.017453292F; // yaw
e.setDeltaMovement(e.getDeltaMovement().add((-Mth.sin(g) * 0.2F), 0.0D, (Mth.cos(u) * 0.2F)));
}
e.hasImpulse = true;
}
}
-1
View File
@@ -88,7 +88,6 @@
"Player_parrotMixin",
"SaplingBlock_desertShrubsMixin",
"EntityMixin",
"ChunkGenerator_scarpetMixin",
"Guardian_renewableSpongesMixin",
"Husk_templesMixin",
"ChunkGenerator_customMobSpawnsMixin",