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