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

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