Merge branch 'master' into future

This commit is contained in:
gnembon committed 2021-08-08 21:51:42 -03:00
commit 6594c2c07f
63 files changed
+711 -849

No files matched your search

@@ -3,7 +3,9 @@ package carpet.script;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.helpers.TickSpeed;
import carpet.script.exception.IntegrityException;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.InvalidCallbackException;
import carpet.script.value.BlockValue;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
@@ -25,7 +27,6 @@ import net.minecraft.entity.TntEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.passive.MerchantEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.server.network.ServerPlayerEntity;
@@ -46,7 +47,6 @@ import net.minecraft.village.Merchant;
import net.minecraft.village.TradeOffer;
import net.minecraft.world.World;
import net.minecraft.world.explosion.Explosion;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.Arrays;
@@ -70,10 +70,17 @@ import java.util.stream.Collectors;
public class CarpetEventServer
{
public final List<ScheduledCall> scheduledCalls = new LinkedList<>();
public final MinecraftServer server;
public final CarpetScriptServer scriptServer;
private static final List<Value> NOARGS = Collections.emptyList();
public final Map<String, Event> customEvents = new HashMap<>();
public enum CallbackResult
{
SUCCESS, PASS, FAIL
}
public static class Callback
{
public final String host;
@@ -81,7 +88,6 @@ public class CarpetEventServer
public final FunctionValue function;
public final List<Value> parametrizedArgs;
public Callback(String host, String target, FunctionValue function, List<Value> parametrizedArgs)
{
this.host = host;
@@ -95,18 +101,17 @@ public class CarpetEventServer
* @param sender - entity command source
* @param runtimeArgs = options
*/
public boolean execute(ServerCommandSource sender, List<Value> runtimeArgs)
public CallbackResult execute(ServerCommandSource sender, List<Value> runtimeArgs)
{
if (!this.parametrizedArgs.isEmpty())
{
runtimeArgs = new ArrayList<>(runtimeArgs);
runtimeArgs.addAll(this.parametrizedArgs);
}
if (CarpetServer.scriptServer == null) return false; // already stopped
return CarpetServer.scriptServer.runEventCall(
if (CarpetServer.scriptServer == null) return CallbackResult.FAIL; // already stopped
return CarpetServer.scriptServer.events.runEventCall(
sender.withLevel(CarpetSettings.runPermissionLevel),
host, optionalTarget, function, runtimeArgs
);
host, optionalTarget, function, runtimeArgs);
}
/**
@@ -115,18 +120,12 @@ public class CarpetEventServer
* @param optionalRecipient - optional target player argument
* @param runtimeArgs = options
*/
public int signal(ServerCommandSource sender, ServerPlayerEntity optionalRecipient, List<Value> runtimeArgs)
public CallbackResult signal(ServerCommandSource sender, ServerPlayerEntity optionalRecipient, List<Value> runtimeArgs)
{
// recipent of the call doesn't match the handlingHost
if (optionalRecipient != null && !optionalRecipient.getEntityName().equals(optionalTarget))
return 0;
List<Value> args = runtimeArgs;
if (!this.parametrizedArgs.isEmpty())
{
args = new ArrayList<>(runtimeArgs);
args.addAll(this.parametrizedArgs);
}
return CarpetServer.scriptServer.signal(sender, optionalRecipient, host, function, args, false);
return CallbackResult.FAIL;
return execute(sender, runtimeArgs);
}
@@ -135,18 +134,8 @@ public class CarpetEventServer
{
return function.getString()+((host==null)?"":"(from "+host+(optionalTarget == null?"":"/"+optionalTarget)+")");
}
public static class Signature
{
String function;
String host;
String target;
public Signature(String fun, String h, String t)
{
function = fun;
host = h;
target = t;
}
}
public static record Signature(String function, String host, String target) {}
public static Signature fromString(String str)
{
Pattern find = Pattern.compile("(\\w+)(?:\\(from (\\w+)(?:/(\\w+))?\\))?");
@@ -178,10 +167,8 @@ public class CarpetEventServer
*/
public void execute()
{
CarpetServer.scriptServer.runScheduledCall(ctx.origin, ctx.s, host, (CarpetScriptHost) ctx.host, function, parametrizedArgs);
CarpetServer.scriptServer.events.runScheduledCall(ctx.origin, ctx.s, host, (CarpetScriptHost) ctx.host, function, parametrizedArgs);
}
}
public static class CallbackList
@@ -190,7 +177,6 @@ public class CarpetEventServer
public final List<Callback> callList;
public final int reqArgs;
final boolean isSystem;
final boolean isGlobalOnly;
final boolean perPlayerDistribution;
public CallbackList(int reqArgs, boolean isSystem, boolean isGlobalOnly)
@@ -198,7 +184,6 @@ public class CarpetEventServer
this.callList = new ArrayList<>();
this.reqArgs = reqArgs;
this.isSystem = isSystem;
this.isGlobalOnly = isGlobalOnly;
perPlayerDistribution = isSystem && !isGlobalOnly;
}
@@ -230,7 +215,7 @@ public class CarpetEventServer
// 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;
if (!call.execute(source, argv)) fails.add(call);
if (call.execute(source, argv) == CallbackResult.FAIL) fails.add(call);
}
for (Callback call : fails) callList.remove(call);
CarpetProfiler.end_current_section(currentSection);
@@ -245,7 +230,9 @@ public class CarpetEventServer
int successes = 0;
for (Callback call: callList)
{
successes += Math.max(0, call.signal(sender, optinoalReceipient, callArg));
//successes += Math.max(0, call.signal(sender, optinoalReceipient, callArg));
if (call.signal(sender, optinoalReceipient, callArg) == CallbackResult.SUCCESS) successes ++;
}
//for (Callback call : fails) callList.remove(call);
return successes;
@@ -253,7 +240,7 @@ public class CarpetEventServer
public boolean addFromExternal(ServerCommandSource source, String hostName, String funName, Consumer<ScriptHost> hostOnEventHandler)
{
ScriptHost host = CarpetServer.scriptServer.getHostByName(hostName);
ScriptHost host = CarpetServer.scriptServer.getAppHostByName(hostName);
if (host == null)
{
// impossible call to add
@@ -991,8 +978,6 @@ public class CarpetEventServer
public final String name;
public final CallbackList handler;
@Deprecated
public final boolean globalOnly;
public final boolean isPublic; // public events can be targetted with __on_<event> defs
public Event(String name, int reqArgs, boolean isGlobalOnly)
{
@@ -1002,7 +987,6 @@ public class CarpetEventServer
{
this.name = name;
this.handler = new CallbackList(reqArgs, true, isGlobalOnly);
this.globalOnly = isGlobalOnly;
this.isPublic = isPublic;
byName.put(name, this);
}
@@ -1050,7 +1034,6 @@ public class CarpetEventServer
{
this.name = name;
this.handler = new CallbackList(1, false, false);
this.globalOnly = false;
this.isPublic = true;
server.events.customEvents.put(name, this);
}
@@ -1122,9 +1105,9 @@ public class CarpetEventServer
}
public CarpetEventServer(MinecraftServer server)
public CarpetEventServer(CarpetScriptServer scriptServer)
{
this.server = server;
this.scriptServer = scriptServer;
Event.clearAllBuiltinEvents();
}
@@ -1155,6 +1138,45 @@ public class CarpetEventServer
scheduledCalls.add(new ScheduledCall(context, function, args, due));
}
public void runScheduledCall(BlockPos origin, ServerCommandSource source, String hostname, CarpetScriptHost host, FunctionValue udf, List<Value> argv)
{
if (hostname != null && !scriptServer.modules.containsKey(hostname)) // well - scheduled call app got unloaded
return;
try
{
host.callUDF(origin, source, udf, argv);
}
catch (NullPointerException | InvalidCallbackException | IntegrityException ignored) { }
}
public CallbackResult runEventCall(ServerCommandSource sender, String hostname, String optionalTarget, FunctionValue udf, List<Value> argv)
{
CarpetScriptHost appHost = scriptServer.getAppHostByName(hostname);
// no such app
if (appHost == null) return CallbackResult.FAIL;
// dummy call for player apps that reside on the global copy - do not run them, but report as passes.
if (appHost.isPerUser() && optionalTarget==null) return CallbackResult.PASS;
ServerPlayerEntity target = null;
if (optionalTarget != null)
{
target = sender.getServer().getPlayerManager().getPlayer(optionalTarget);
if (target == null) return CallbackResult.FAIL;
}
ServerCommandSource source = sender.withLevel(CarpetSettings.runPermissionLevel);
CarpetScriptHost executingHost = appHost.retrieveForExecution(sender, target);
if (executingHost == null) return CallbackResult.FAIL;
try
{
executingHost.callUDF(BlockPos.ORIGIN, source.withLevel(CarpetSettings.runPermissionLevel), udf, argv);
return CallbackResult.SUCCESS;
}
catch (NullPointerException | InvalidCallbackException | IntegrityException error)
{
CarpetScriptServer.LOG.error("Got exception: "+error.getMessage());
return CallbackResult.FAIL;
}
}
public boolean addEventFromCommand(ServerCommandSource source, String event, String host, String funName)
{
Event ev = Event.getEvent(event, CarpetServer.scriptServer);
@@ -1178,7 +1200,7 @@ public class CarpetEventServer
public boolean handleCustomEvent(String event, CarpetScriptHost host, FunctionValue function, List<Value> args)
{
Event ev = Event.getOrCreateCustom(event, host.getScriptServer());
Event ev = Event.getOrCreateCustom(event, scriptServer);
onEventAddedToHost(ev, host);
return ev.handler.addEventCallInternal(host, function, args==null?NOARGS:args);
}
@@ -1233,15 +1255,4 @@ public class CarpetEventServer
// remove scheduled calls
scheduledCalls.removeIf(sc -> sc.host != null && sc.host.equals(host.getName()));
}
private Pair<String,String> decodeCallback(String funName)
{
Pattern find = Pattern.compile("(\\w+)\\(from (\\w+)\\)");
Matcher matcher = find.matcher(funName);
if(matcher.matches())
{
return Pair.of(matcher.group(2), matcher.group(1));
}
return Pair.of(null, funName);
}
}
@@ -10,6 +10,7 @@ import carpet.script.command.CommandArgument;
import carpet.script.command.CommandToken;
import carpet.script.exception.CarpetExpressionException;
import carpet.script.exception.ExpressionException;
import carpet.script.exception.IntegrityException;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.InvalidCallbackException;
import carpet.script.utils.AppStoreManager;
@@ -644,37 +645,19 @@ public class CarpetScriptHost extends ScriptHost
}
}
public List<CarpetScriptHost> retrieveForExecution(ServerCommandSource source, String optionalTarget)
public CarpetScriptHost retrieveForExecution(ServerCommandSource source, ServerPlayerEntity player)
{
List<CarpetScriptHost> targets = new ArrayList<>();
if (perUser)
CarpetScriptHost target = null;
if (!perUser)
{
if (optionalTarget == null)
{
for (ServerPlayerEntity player : source.getServer().getPlayerManager().getPlayerList())
{
CarpetScriptHost host = (CarpetScriptHost) retrieveForExecution(player.getEntityName());
targets.add(host);
if (host.errorSnooper == null) host.setChatErrorSnooper(player.getCommandSource());
}
}
else
{
ServerPlayerEntity player = source.getServer().getPlayerManager().getPlayer(optionalTarget);
if (player != null)
{
CarpetScriptHost host = (CarpetScriptHost) retrieveForExecution(player.getEntityName());
targets.add(host);
if (host.errorSnooper == null) host.setChatErrorSnooper(player.getCommandSource());
}
}
target = this;
}
else
else if (player != null)
{
targets.add(this);
if (this.errorSnooper == null) this.setChatErrorSnooper(source);
target = (CarpetScriptHost) retrieveForExecution(player.getEntityName());
}
return targets;
if (target != null && target.errorSnooper == null) target.setChatErrorSnooper(source);
return target;
}
public CarpetScriptHost retrieveOwnForExecution(ServerCommandSource source) throws CommandSyntaxException
@@ -830,6 +813,7 @@ public class CarpetScriptHost extends ScriptHost
try
{
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
assertAppIntegrity(function.getModule());
Context context = new CarpetContext(this, source, BlockPos.ORIGIN);
return function.getExpression().evalValue(
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
@@ -860,7 +844,7 @@ public class CarpetScriptHost extends ScriptHost
}
try
{
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
assertAppIntegrity(function.getModule());
Context context = new CarpetContext(this, source, BlockPos.ORIGIN);
return function.getExpression().evalValue(
() -> function.execute(context, Context.VOID, function.getExpression(), function.getToken(), argv),
@@ -874,7 +858,7 @@ public class CarpetScriptHost extends ScriptHost
}
}
public Value callUDF(BlockPos pos, ServerCommandSource source, FunctionValue fun, List<Value> argv) throws InvalidCallbackException
public Value callUDF(BlockPos pos, ServerCommandSource source, FunctionValue fun, List<Value> argv) throws InvalidCallbackException, IntegrityException
{
if (CarpetServer.scriptServer.stopAll)
return Value.NULL;
@@ -889,7 +873,7 @@ public class CarpetScriptHost extends ScriptHost
}
try
{
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
assertAppIntegrity(fun.getModule());
Context context = new CarpetContext(this, source, pos);
return fun.getExpression().evalValue(
() -> fun.execute(context, Context.VOID, fun.getExpression(), fun.getToken(), argv),
@@ -12,8 +12,6 @@ import carpet.script.bundled.BundledModule;
import carpet.CarpetServer;
import carpet.script.bundled.FileModule;
import carpet.script.bundled.Module;
import carpet.script.exception.IntegrityException;
import carpet.script.exception.InvalidCallbackException;
import carpet.script.language.Arithmetic;
import carpet.script.language.ControlFlow;
import carpet.script.language.DataStructures;
@@ -23,7 +21,6 @@ import carpet.script.language.Sys;
import carpet.script.language.Threading;
import carpet.script.utils.AppStoreManager;
import carpet.script.value.FunctionValue;
import carpet.script.value.Value;
import carpet.utils.CarpetProfiler;
import carpet.utils.Messenger;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -35,7 +32,6 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.WorldSavePath;
import net.minecraft.util.math.BlockPos;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -94,7 +90,7 @@ public class CarpetScriptServer
* @param app The {@link BundledModule} of the app.
*/
public static void registerSettingsApp(BundledModule app) {
ruleModuleData.add(app);
ruleModuleData.add(app);
}
static
@@ -120,9 +116,9 @@ public class CarpetScriptServer
private void init()
{
ScriptHost.systemGlobals.clear();
events = new CarpetEventServer(server);
events = new CarpetEventServer(this);
modules = new HashMap<>();
unloadableModules = new HashSet<String>();
unloadableModules = new HashSet<>();
tickStart = 0L;
stopAll = false;
holyMoly = server.getCommandManager().getDispatcher().getRoot().getChildren().stream().map(CommandNode::getName).collect(Collectors.toSet());
@@ -232,7 +228,7 @@ public class CarpetScriptServer
return moduleNames;
}
public ScriptHost getHostByName(String name)
public CarpetScriptHost getAppHostByName(String name)
{
if (name == null)
return globalHost;
@@ -310,7 +306,10 @@ public class CarpetScriptServer
if (newHost.isPerUser())
{
// that will provide player hosts right at the startup
newHost.retrieveForExecution(source, null);
for (ServerPlayerEntity player : source.getServer().getPlayerManager().getPlayerList())
{
newHost.retrieveForExecution(player.getCommandSource(), player);
}
}
else
{
@@ -372,86 +371,6 @@ public class CarpetScriptServer
return false;
}
public boolean runEventCall(ServerCommandSource sender, String hostname, String optionalTarget, FunctionValue udf, List<Value> argv)
{
CarpetScriptHost host = globalHost;
if (hostname != null)
host = modules.get(hostname);
if (host == null) return false;
// dummy call for player apps that reside on the global copy - do not run them, but report as successes.
if (host.isPerUser() && optionalTarget==null) return true;
ServerPlayerEntity target = null;
if (optionalTarget != null)
{
target = sender.getServer().getPlayerManager().getPlayer(optionalTarget);
if (target == null) return false;
}
int successes = signal(sender, target, hostname, udf, argv, true );
return successes >= 0;
}
public void runScheduledCall(BlockPos origin, ServerCommandSource source, String hostname, CarpetScriptHost host, FunctionValue udf, List<Value> argv)
{
if (hostname != null && !modules.containsKey(hostname)) // well - scheduled call app got unloaded
return;
try
{
host.callUDF(origin, source, udf, argv);
}
catch (NullPointerException | InvalidCallbackException ignored)
{
}
}
/**
* returns number of successful calls in the host or -1 if failed exceptionally
* @param sender
* @param optionalRecipient
* @param hostname
* @param udf
* @param argv
* @param reportFails - returns -1 when any call failed
* @return
*/
public int signal(ServerCommandSource sender, ServerPlayerEntity optionalRecipient, String hostname, FunctionValue udf, List<Value> argv, boolean reportFails)
{
if (hostname == null)
{
if (optionalRecipient != null) return 0;
try
{
globalHost.callUDF(BlockPos.ORIGIN, sender, udf, argv);
}
catch (NullPointerException | InvalidCallbackException npe)
{
return reportFails?-1:0;
}
return 1;
}
String hostRecipient = optionalRecipient == null?null:optionalRecipient.getEntityName();
ServerCommandSource source = (optionalRecipient == null)? sender : optionalRecipient.getCommandSource().withLevel(CarpetSettings.runPermissionLevel);
int successes = 0;
for (CarpetScriptHost host : modules.get(hostname).retrieveForExecution(sender, hostRecipient))
{
// getPlayer will always return nonnull cause retrieve for execution only returns hosts for existing players.
ServerCommandSource executingSource = host.perUser
? source.getServer().getPlayerManager().getPlayer(host.user).getCommandSource()
: source.getServer().getCommandSource();
try
{
host.callUDF(BlockPos.ORIGIN, source.withLevel(CarpetSettings.runPermissionLevel), udf, argv);
}
catch (NullPointerException | InvalidCallbackException | IntegrityException npe)
{
if (reportFails) return -1;
continue;
}
successes ++;
}
return successes;
}
public void tick()
{
CarpetProfiler.ProfilerToken token;
@@ -493,16 +412,11 @@ public class CarpetScriptServer
});
}
static class TransferData
private static record TransferData(boolean perUser, Predicate<ServerCommandSource> commandValidator, boolean isRuleApp)
{
boolean perUser;
Predicate<ServerCommandSource> commandValidator;
boolean isRuleApp;
private TransferData(CarpetScriptHost host)
{
perUser = host.perUser;
commandValidator = host.commandValidator;
isRuleApp = host.isRuleApp;
this(host.perUser, host.commandValidator, host.isRuleApp);
}
}
@@ -9,7 +9,6 @@ import carpet.script.value.StringValue;
import carpet.script.value.Value;
import net.minecraft.entity.Entity;
import net.minecraft.entity.damage.DamageSource;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Arrays;
import java.util.Collections;
@@ -20,7 +19,8 @@ import java.util.Map;
public class EntityEventsGroup
{
private final Map<Event, Map<Pair<String,String>, CarpetEventServer.Callback>> actions;
private static record EventKey(String host, String user) {}
private final Map<Event, Map<EventKey, CarpetEventServer.Callback>> actions;
private final Entity entity;
public EntityEventsGroup(Entity e)
{
@@ -31,28 +31,28 @@ public class EntityEventsGroup
public void onEvent(Event type, Object... args)
{
if (actions.isEmpty()) return; // most of the cases, trying to be nice
Map<Pair<String,String>, CarpetEventServer.Callback> actionSet = actions.get(type);
Map<EventKey, CarpetEventServer.Callback> actionSet = actions.get(type);
if (actionSet == null) return;
if (CarpetServer.scriptServer == null) return; // executed after world is closin down
for (Iterator<Map.Entry<Pair<String,String>, CarpetEventServer.Callback>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
for (Iterator<Map.Entry<EventKey, CarpetEventServer.Callback>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
{
Map.Entry<Pair<String,String>, CarpetEventServer.Callback> action = iterator.next();
Pair<String,String> key = action.getKey();
ScriptHost host = CarpetServer.scriptServer.getHostByName(key.getLeft());
Map.Entry<EventKey, CarpetEventServer.Callback> action = iterator.next();
EventKey key = action.getKey();
ScriptHost host = CarpetServer.scriptServer.getAppHostByName(key.host());
if (host == null)
{
iterator.remove();
continue;
}
if (key.getRight() != null)
if (key.user() != null)
{
if (entity.getServer().getPlayerManager().getPlayer(key.getRight())==null)
if (entity.getServer().getPlayerManager().getPlayer(key.user())==null)
{
iterator.remove();
continue;
}
}
if (!type.call(action.getValue(), entity, args))
if (type.call(action.getValue(), entity, args) == CarpetEventServer.CallbackResult.FAIL)
iterator.remove();
}
if (actionSet.isEmpty()) actions.remove(type);
@@ -60,7 +60,7 @@ public class EntityEventsGroup
public void addEvent(Event type, ScriptHost host, FunctionValue fun, List<Value> extraargs)
{
Pair<String,String> key = Pair.of(host.getName(), host.user);
EventKey key = new EventKey(host.getName(), host.user);
if (fun != null)
{
CarpetEventServer.Callback call = type.create(key, fun, extraargs);
@@ -117,15 +117,15 @@ public class EntityEventsGroup
argcount = args+1; // entity is not extra
byName.put(identifier, this);
}
public CarpetEventServer.Callback create(Pair<String,String> key, FunctionValue function, List<Value> extraArgs)
public CarpetEventServer.Callback create(EventKey key, FunctionValue function, List<Value> extraArgs)
{
if ((function.getArguments().size()-(extraArgs == null ? 0 : extraArgs.size())) != argcount)
{
return null;
}
return new CarpetEventServer.Callback(key.getLeft(), key.getRight(), function, extraArgs);
return new CarpetEventServer.Callback(key.host(), key.user(), function, extraArgs);
}
public boolean call(CarpetEventServer.Callback tickCall, Entity entity, Object ... args)
public CarpetEventServer.CallbackResult call(CarpetEventServer.Callback tickCall, Entity entity, Object ... args)
{
assert args.length == argcount-1;
return tickCall.execute(entity.getCommandSource(), makeArgs(entity, args));
+2 -4
View File
@@ -33,8 +33,6 @@ import carpet.script.value.FunctionValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.math.BigInteger;
@@ -98,7 +96,7 @@ public class Expression
functionalEquivalence.put(operator, function);
}
private final Map<String, Value> constants = ImmutableMap.of(
private final Map<String, Value> constants = Map.of(
"euler", Arithmetic.euler,
"pi", Arithmetic.PI,
"null", Value.NULL,
@@ -972,7 +970,7 @@ public class Expression
final ExpressionNode v1 = nodeStack.pop();
final ExpressionNode v2 = nodeStack.pop();
LazyValue result = (c,t) -> operators.get(token.surface).lazyEval(c, t,this, token, v2.op, v1.op).evalValue(c, t);
nodeStack.push(new ExpressionNode(result, ImmutableList.of(v2, v1), token ));
nodeStack.push(new ExpressionNode(result, List.of(v2, v1), token ));
break;
case VARIABLE:
Value constant = getConstantFor(token.surface);
+5
View File
@@ -101,10 +101,12 @@ public abstract class Fluff
return name;
}
@Override
public int getNumParams() {
return numParams;
}
@Override
public boolean numParamsVaries() {
return numParams < 0;
}
@@ -162,6 +164,7 @@ public abstract class Fluff
return new LazyValue()
{ // eager evaluation always ignores the required type and evals params by none default
private List<Value> params;
@Override
public Value evalValue(Context c, Context.Type type)
{
ILazyFunction.checkInterrupts();
@@ -202,10 +205,12 @@ public abstract class Fluff
this.leftAssoc = leftAssoc;
}
@Override
public int getPrecedence() {
return precedence;
}
@Override
public boolean isLeftAssoc() {
return leftAssoc;
}
@@ -305,6 +305,11 @@ public abstract class ScriptHost
return data;
}
protected void assertAppIntegrity(Module module)
{
getModuleData(module);
}
public void addUserDefinedFunction(Context ctx, Module module, String name, FunctionValue fun)
{
getModuleData(module).globalFunctions.put(name, fun);
@@ -12,8 +12,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import org.apache.commons.lang3.tuple.Pair;
import carpet.CarpetServer;
import carpet.script.Context;
import carpet.script.value.BooleanValue;
@@ -195,12 +193,8 @@ public interface Param
}
};
/**
* <p>Strict converters</p>
*
* <p>Stored as {@code <Pair<Type, shallow?>, Converter>}</p>
*/
private static final Map<Pair<Class<?>, Boolean>, ValueConverter<?>> strictParamsByClassAndShallowness = new HashMap<>();
static record StrictConverterInfo(Class<?> type, boolean shallow) {}
private static final Map<StrictConverterInfo, ValueConverter<?>> strictParamsByClassAndShallowness = new HashMap<>();
static
{ // TODO Specify strictness in name?
registerStrictConverter(String.class, false, new SimpleTypeConverter<>(StringValue.class, StringValue::getString, "string"));
@@ -224,7 +218,7 @@ public interface Param
{
boolean shallow = type.getAnnotation(Strict.class).shallow();
Class<?> clazz = (Class<?>) type.getType();
Pair<Class<?>, Boolean> key = Pair.of(clazz, shallow);
var key = new StrictConverterInfo(clazz, shallow);
ValueConverter<?> converter = strictParamsByClassAndShallowness.get(key);
if (converter != null)
return converter;
@@ -245,7 +239,7 @@ public interface Param
*/
public static <T> void registerStrictConverter(Class<T> type, boolean shallow, ValueConverter<T> converter)
{
Pair<Class<?>, Boolean> key = Pair.of(type, shallow);
var key = new StrictConverterInfo(type, shallow);
if (strictParamsByClassAndShallowness.containsKey(key))
throw new IllegalArgumentException(type + " already has a registered " + (shallow ? "" : "non-") + "shallow StrictConverter");
strictParamsByClassAndShallowness.put(key, converter);
@@ -3,7 +3,6 @@ package carpet.script.api;
import carpet.CarpetServer;
import carpet.fakes.MinecraftServerInterface;
import carpet.fakes.ServerWorldInterface;
import carpet.fakes.StatTypeInterface;
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
import carpet.helpers.FeatureGenerator;
import carpet.logging.HUDController;
@@ -38,8 +37,6 @@ import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.utils.Messenger;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import net.minecraft.SharedConstants;
import net.minecraft.block.BlockState;
@@ -104,7 +101,6 @@ import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.level.UnmodifiableLevelProperties;
import net.minecraft.world.level.storage.LevelStorage;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.tuple.Pair;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -334,7 +330,7 @@ public class Auxiliary {
ServerWorld world = cc.s.getWorld();
MinecraftServer server = world.getServer();
Set<ServerPlayerEntity> playerTargets = new HashSet<>();
List<Pair<ShapeDispatcher.ExpiringShape, Map<String,Value>>> shapes = new ArrayList<>();
List<ShapeDispatcher.ShapeWithConfig> shapes = new ArrayList<>();
if (lv.size() == 1) // bulk
{
Value specLoad = lv.get(0);
@@ -1062,10 +1058,10 @@ public class Auxiliary {
{
try {
//Files.createDirectory(packFloder);
try (FileSystem zipfs = FileSystems.newFileSystem(URI.create("jar:" + packFloder.toUri().toString()), ImmutableMap.of("create", "true"))) {
try (FileSystem zipfs = FileSystems.newFileSystem(URI.create("jar:" + packFloder.toUri().toString()), Map.of("create", "true"))) {
Path zipRoot = zipfs.getPath("/");
zipValueToJson(zipRoot.resolve("pack.mcmeta"), MapValue.wrap(
ImmutableMap.of(StringValue.of("pack"), MapValue.wrap(ImmutableMap.of(
Map.of(StringValue.of("pack"), MapValue.wrap(Map.of(
StringValue.of("pack_format"), new NumericValue(SharedConstants.getGameVersion().getPackVersion()),
StringValue.of("description"), StringValue.of(name),
StringValue.of("source"), StringValue.of("scarpet")
@@ -1144,7 +1140,7 @@ public class Auxiliary {
DimensionType dimensionType3 = entry.getValue().getDimensionType();
ChunkGenerator chunkGenerator3 = entry.getValue().getChunkGenerator();
UnmodifiableLevelProperties unmodifiableLevelProperties = new UnmodifiableLevelProperties(saveProperties, ((ServerWorldInterface) server.getOverworld()).getWorldPropertiesCM());
ServerWorld serverWorld2 = new ServerWorld(server, Util.getMainWorkerExecutor(), session, unmodifiableLevelProperties, registryKey2, dimensionType3, WorldTools.NOOP_LISTENER, chunkGenerator3, bl, m, ImmutableList.of(), false);
ServerWorld serverWorld2 = new ServerWorld(server, Util.getMainWorkerExecutor(), session, unmodifiableLevelProperties, registryKey2, dimensionType3, WorldTools.NOOP_LISTENER, chunkGenerator3, bl, m, List.of(), false);
server.getOverworld().getWorldBorder().addListener(new WorldBorderListener.WorldBorderSyncer(serverWorld2.getWorldBorder()));
existing_worlds.put(registryKey2, serverWorld2);
}
@@ -1209,7 +1205,7 @@ public class Auxiliary {
private static <T> Stat<T> getStat(StatType<T> type, Identifier id)
{
T key = type.getRegistry().get(id);
if (key == null || !((StatTypeInterface)type).hasStatCreated(key))
if (key == null || !type.hasStat(key))
return null;
return type.getOrCreateStat(key);
}
@@ -262,7 +262,6 @@ public class Entities {
expression.addContextFunction("entity_load_handler", -1, (c, t, lv) ->
{
if (c.host.isPerUser()) throw new InternalExpressionException("'entity_load_handler' can only be called in apps with global scope");
if (lv.size() < 2) throw new InternalExpressionException("'entity_load_handler' required the entity type, and a function to call");
Value entityValue = lv.get(0);
List<String> descriptors = (entityValue instanceof ListValue)
@@ -181,7 +181,7 @@ public class Inventories {
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null) return Value.NULL;
return new NumericValue(inventoryLocator.inventory.size());
return new NumericValue(inventoryLocator.inventory().size());
});
expression.addContextFunction("inventory_has_items", -1, (c, t, lv) ->
@@ -189,7 +189,7 @@ public class Inventories {
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null) return Value.NULL;
return BooleanValue.of(!inventoryLocator.inventory.isEmpty());
return BooleanValue.of(!inventoryLocator.inventory().isEmpty());
});
//inventory_get(<b, e>, <n>) -> item_triple
@@ -198,17 +198,17 @@ public class Inventories {
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null) return Value.NULL;
if (lv.size() == inventoryLocator.offset)
if (lv.size() == inventoryLocator.offset())
{
List<Value> fullInventory = new ArrayList<>();
for (int i = 0, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
fullInventory.add(ValueConversions.of(inventoryLocator.inventory.getStack(i)));
for (int i = 0, maxi = inventoryLocator.inventory().size(); i < maxi; i++)
fullInventory.add(ValueConversions.of(inventoryLocator.inventory().getStack(i)));
return ListValue.wrap(fullInventory);
}
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset)).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
return ValueConversions.of(inventoryLocator.inventory.getStack(slot));
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset())).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory());
if (slot == inventoryLocator.inventory().size()) return Value.NULL;
return ValueConversions.of(inventoryLocator.inventory().getStack(slot));
});
//inventory_set(<b,e>, <n>, <count>, <item>, <nbt>)
@@ -217,33 +217,33 @@ public class Inventories {
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null) return Value.NULL;
if (lv.size() < inventoryLocator.offset+2)
if (lv.size() < inventoryLocator.offset()+2)
throw new InternalExpressionException("'inventory_set' requires at least slot number and new stack size, and optional new item");
int slot = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+0)).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
int slot = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset()+0)).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory());
if (slot == inventoryLocator.inventory().size()) return Value.NULL;
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset()+1)).getLong();
if (count == 0)
{
// clear slot
ItemStack removedStack = inventoryLocator.inventory.removeStack(slot);
ItemStack removedStack = inventoryLocator.inventory().removeStack(slot);
syncPlayerInventory(inventoryLocator, slot);
//Value res = ListValue.fromItemStack(removedStack); // that tuple will be read only but cheaper if noone cares
return ValueConversions.of(removedStack);
}
if (lv.size() < inventoryLocator.offset+3)
if (lv.size() < inventoryLocator.offset()+3)
{
ItemStack previousStack = inventoryLocator.inventory.getStack(slot);
ItemStack previousStack = inventoryLocator.inventory().getStack(slot);
ItemStack newStack = previousStack.copy();
newStack.setCount(count);
inventoryLocator.inventory.setStack(slot, newStack);
inventoryLocator.inventory().setStack(slot, newStack);
syncPlayerInventory(inventoryLocator, slot);
return ValueConversions.of(previousStack);
}
NbtCompound nbt = null; // skipping one argument
if (lv.size() > inventoryLocator.offset+3)
if (lv.size() > inventoryLocator.offset()+3)
{
Value nbtValue = lv.get(inventoryLocator.offset+3);
Value nbtValue = lv.get(inventoryLocator.offset()+3);
if (nbtValue instanceof NBTSerializableValue)
nbt = ((NBTSerializableValue)nbtValue).getCompoundTag();
else if (nbtValue instanceof NullValue)
@@ -251,11 +251,11 @@ public class Inventories {
else
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
}
ItemStackArgument newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset+2).getString(), nbt);
ItemStack previousStack = inventoryLocator.inventory.getStack(slot);
ItemStackArgument newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset()+2).getString(), nbt);
ItemStack previousStack = inventoryLocator.inventory().getStack(slot);
try
{
inventoryLocator.inventory.setStack(slot, newitem.createStack(count, false));
inventoryLocator.inventory().setStack(slot, newitem.createStack(count, false));
syncPlayerInventory(inventoryLocator, slot);
}
catch (CommandSyntaxException e)
@@ -272,21 +272,21 @@ public class Inventories {
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null) return Value.NULL;
ItemStackArgument itemArg = null;
if (lv.size() > inventoryLocator.offset)
if (lv.size() > inventoryLocator.offset())
{
Value secondArg = lv.get(inventoryLocator.offset+0);
Value secondArg = lv.get(inventoryLocator.offset()+0);
if (!(secondArg instanceof NullValue))
itemArg = NBTSerializableValue.parseItem(secondArg.getString());
}
int startIndex = 0;
if (lv.size() > inventoryLocator.offset+1)
if (lv.size() > inventoryLocator.offset()+1)
{
startIndex = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
startIndex = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset()+1)).getLong();
}
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory);
for (int i = startIndex, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory());
for (int i = startIndex, maxi = inventoryLocator.inventory().size(); i < maxi; i++)
{
ItemStack stack = inventoryLocator.inventory.getStack(i);
ItemStack stack = inventoryLocator.inventory().getStack(i);
if ( (itemArg == null && stack.isEmpty()) || (itemArg != null && itemArg.getItem().equals(stack.getItem())) )
return new NumericValue(i);
}
@@ -299,18 +299,18 @@ public class Inventories {
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null) return Value.NULL;
if (lv.size() <= inventoryLocator.offset)
if (lv.size() <= inventoryLocator.offset())
throw new InternalExpressionException("'inventory_remove' requires at least an item to be removed");
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset).getString());
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset()).getString());
int amount = 1;
if (lv.size() > inventoryLocator.offset+1)
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
if (lv.size() > inventoryLocator.offset()+1)
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset()+1)).getLong();
// not enough
if (((amount == 1) && (!inventoryLocator.inventory.containsAny(Sets.newHashSet(searchItem.getItem()))))
|| (inventoryLocator.inventory.count(searchItem.getItem()) < amount)) return Value.FALSE;
for (int i = 0, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
if (((amount == 1) && (!inventoryLocator.inventory().containsAny(Sets.newHashSet(searchItem.getItem()))))
|| (inventoryLocator.inventory().count(searchItem.getItem()) < amount)) return Value.FALSE;
for (int i = 0, maxi = inventoryLocator.inventory().size(); i < maxi; i++)
{
ItemStack stack = inventoryLocator.inventory.getStack(i);
ItemStack stack = inventoryLocator.inventory().getStack(i);
if (stack.isEmpty())
continue;
if (!stack.getItem().equals(searchItem.getItem()))
@@ -319,13 +319,13 @@ public class Inventories {
if (left > 0)
{
stack.setCount(left);
inventoryLocator.inventory.setStack(i, stack);
inventoryLocator.inventory().setStack(i, stack);
syncPlayerInventory(inventoryLocator, i);
return Value.TRUE;
}
else
{
inventoryLocator.inventory.removeStack(i);
inventoryLocator.inventory().removeStack(i);
syncPlayerInventory(inventoryLocator, i);
amount -= stack.getCount();
}
@@ -341,30 +341,29 @@ public class Inventories {
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null) return Value.NULL;
if (lv.size() == inventoryLocator.offset)
if (lv.size() == inventoryLocator.offset())
throw new InternalExpressionException("Slot number is required for inventory_drop");
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset)).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset())).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory());
if (slot == inventoryLocator.inventory().size()) return Value.NULL;
int amount = 0;
if (lv.size() > inventoryLocator.offset+1)
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
if (lv.size() > inventoryLocator.offset()+1)
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset()+1)).getLong();
if (amount < 0)
throw new InternalExpressionException("Cannot throw negative number of items");
ItemStack stack = inventoryLocator.inventory.getStack(slot);
ItemStack stack = inventoryLocator.inventory().getStack(slot);
if (stack == null || stack.isEmpty()) return Value.ZERO;
if (amount == 0) amount = stack.getCount();
ItemStack droppedStack = inventoryLocator.inventory.removeStack(slot, amount);
ItemStack droppedStack = inventoryLocator.inventory().removeStack(slot, amount);
if (droppedStack.isEmpty()) return Value.ZERO;
Object owner = inventoryLocator.owner;
Object owner = inventoryLocator.owner();
ItemEntity item;
if (owner instanceof PlayerEntity)
{
item = ((PlayerEntity) owner).dropItem(droppedStack, false, true);
}
else if (owner instanceof LivingEntity)
else if (owner instanceof LivingEntity villager)
{
LivingEntity villager = (LivingEntity)owner;
// stolen from LookTargetUtil.give((VillagerEntity)owner, droppedStack, (LivingEntity) owner);
double double_1 = villager.getY() - 0.30000001192092896D + (double)villager.getStandingEyeHeight();
item = new ItemEntity(villager.world, villager.getX(), double_1, villager.getZ(), droppedStack);
@@ -375,7 +374,7 @@ public class Inventories {
}
else
{
Vec3d point = Vec3d.ofCenter(inventoryLocator.position); //pos+0.5v
Vec3d point = Vec3d.ofCenter(inventoryLocator.position()); //pos+0.5v
item = new ItemEntity(cc.s.getWorld(), point.x, point.y, point.z, droppedStack);
item.setToDefaultPickupDelay();
cc.s.getWorld().spawnEntity(item);
@@ -386,13 +385,12 @@ public class Inventories {
private static void syncPlayerInventory(NBTSerializableValue.InventoryLocator inventory, int int_1)
{
if (inventory.owner instanceof ServerPlayerEntity && !inventory.isEnder)
if (inventory.owner() instanceof ServerPlayerEntity player && !inventory.isEnder())
{
ServerPlayerEntity player = (ServerPlayerEntity) inventory.owner;
player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(
-2, 0, // resolve mystery argument
int_1,
inventory.inventory.getStack(int_1)
inventory.inventory().getStack(int_1)
));
}
}
@@ -3,7 +3,6 @@ package carpet.script.api;
import carpet.fakes.SpawnHelperInnerInterface;
import carpet.script.CarpetContext;
import carpet.script.Expression;
import carpet.script.LazyValue;
import carpet.script.exception.InternalExpressionException;
import carpet.script.utils.SystemInfo;
import carpet.script.value.ListValue;
@@ -9,7 +9,6 @@ import carpet.script.exception.Throwables;
import carpet.script.value.MapValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
@@ -523,7 +522,7 @@ public class FileArgument
Throwable exc = e;
if(e.getCause() != null)
exc = e.getCause();
throw new ThrowStatement(MapValue.wrap(ImmutableMap.of(
throw new ThrowStatement(MapValue.wrap(Map.of(
StringValue.of("error"), StringValue.of(exc.getMessage()),
StringValue.of("path"), StringValue.of(filePath.toString())
)), Throwables.JSON_ERROR);
@@ -4,7 +4,6 @@ import carpet.CarpetServer;
import carpet.fakes.BlockStateArgumentInterface;
import carpet.script.CarpetScriptHost;
import carpet.script.argument.FunctionArgument;
import carpet.script.exception.InternalExpressionException;
import carpet.script.value.BlockValue;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
@@ -17,6 +16,9 @@ import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.utils.CarpetProfiler;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType;
@@ -84,7 +86,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec2f;
import net.minecraft.util.registry.Registry;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.Arrays;
@@ -102,7 +103,6 @@ import java.util.stream.Collectors;
import static net.minecraft.server.command.CommandManager.argument;
public abstract class CommandArgument
{
public static CommandSyntaxException error(String text)
@@ -878,49 +878,50 @@ public abstract class CommandArgument
}
private static class SlotArgument extends CommandArgument
{
private static record ContainerIds(IntSet numericalIds, Set<String> commandIds) {}
private String restrict;
private static final Map<String, Pair<Set<Integer>, Set<String>>> RESTRICTED_CONTAINERS = new HashMap<String, Pair<Set<Integer>, Set<String>>>(){{
private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<String, ContainerIds>(){{
int i;
for (String source : Arrays.asList("player", "enderchest", "equipment", "armor", "weapon", "container", "villager", "horse"))
put(source, Pair.of(new HashSet<>(), new HashSet<>()));
for (i = 0; i < 41; i++) get("player").getLeft().add(i);
for(i = 0; i < 41; i++) get("player").getRight().add("container." + i);
for(i = 0; i < 9; i++) get("player").getRight().add("hotbar." + i);
for(i = 0; i < 27; i++) get("player").getRight().add("inventory." + i);
put(source, new ContainerIds(new IntOpenHashSet(), new HashSet<>()));
for (i = 0; i < 41; i++) get("player").numericalIds().add(i);
for(i = 0; i < 41; i++) get("player").commandIds().add("container." + i);
for(i = 0; i < 9; i++) get("player").commandIds().add("hotbar." + i);
for(i = 0; i < 27; i++) get("player").commandIds().add("inventory." + i);
for (String place : Arrays.asList("weapon", "weapon.mainhand", "weapon.offhand"))
{
get("player").getRight().add(place);
get("equipment").getRight().add(place);
get("weapon").getRight().add(place);
get("player").commandIds().add(place);
get("equipment").commandIds().add(place);
get("weapon").commandIds().add(place);
}
for (String place : Arrays.asList("armor.feet","armor.legs", "armor.chest","armor.head"))
{
get("player").getRight().add(place);
get("equipment").getRight().add(place);
get("armor").getRight().add(place);
get("player").commandIds().add(place);
get("equipment").commandIds().add(place);
get("armor").commandIds().add(place);
}
for (i = 0; i < 27; i++) get("enderchest").getLeft().add(200+i);
for(i = 0; i < 27; i++) get("enderchest").getRight().add("enderchest." + i);
for (i = 0; i < 27; i++) get("enderchest").numericalIds().add(200+i);
for(i = 0; i < 27; i++) get("enderchest").commandIds().add("enderchest." + i);
for (i = 0; i < 6; i++) get("equipment").getLeft().add(98+i);
for (i = 0; i < 6; i++) get("equipment").numericalIds().add(98+i);
for (i = 0; i < 4; i++) get("armor").getLeft().add(100+i);
for (i = 0; i < 4; i++) get("armor").numericalIds().add(100+i);
for (i = 0; i < 2; i++) get("weapon").getLeft().add(98+i);
for (i = 0; i < 2; i++) get("weapon").numericalIds().add(98+i);
for (i = 0; i < 54; i++) get("container").getLeft().add(i);
for(i = 0; i < 41; i++) get("container").getRight().add("container." + i);
for (i = 0; i < 54; i++) get("container").numericalIds().add(i);
for(i = 0; i < 41; i++) get("container").commandIds().add("container." + i);
for (i = 0; i < 8; i++) get("villager").getLeft().add(i);
for(i = 0; i < 8; i++) get("villager").getRight().add("villager." + i);
for (i = 0; i < 8; i++) get("villager").numericalIds().add(i);
for(i = 0; i < 8; i++) get("villager").commandIds().add("villager." + i);
for (i = 0; i < 15; i++) get("horse").getLeft().add(500+i);
for(i = 0; i < 15; i++) get("horse").getRight().add("horse." + i);
get("horse").getLeft().add(400);
get("horse").getRight().add("horse.saddle");
get("horse").getLeft().add(401);
get("horse").getRight().add("horse.armor");
for (i = 0; i < 15; i++) get("horse").numericalIds().add(500+i);
for(i = 0; i < 15; i++) get("horse").commandIds().add("horse." + i);
get("horse").numericalIds().add(400);
get("horse").commandIds().add("horse.saddle");
get("horse").numericalIds().add(401);
get("horse").commandIds().add("horse.armor");
}};
protected SlotArgument()
@@ -938,7 +939,7 @@ public abstract class CommandArgument
protected Value getValueFromContext(CommandContext<ServerCommandSource> context, String param) throws CommandSyntaxException
{
int slot = ItemSlotArgumentType.getItemSlot(context, param);
if (restrict != null && !RESTRICTED_CONTAINERS.get(restrict).getLeft().contains(slot))
if (restrict != null && !RESTRICTED_CONTAINERS.get(restrict).numericalIds().contains(slot))
{
throw new SimpleCommandExceptionType(new LiteralText("Incorrect slot restricted to "+restrict+" for custom type "+suffix)).create();
}
@@ -961,7 +962,7 @@ public abstract class CommandArgument
@Override
protected Collection<String> getOptions(CommandContext<ServerCommandSource> context, CarpetScriptHost host) throws CommandSyntaxException
{
return restrict==null?super.getOptions(context, host):RESTRICTED_CONTAINERS.get(restrict).getRight();
return restrict==null?super.getOptions(context, host):RESTRICTED_CONTAINERS.get(restrict).commandIds();
}
@Override
@@ -13,8 +13,8 @@ import carpet.script.value.MapValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import java.util.stream.Collectors;
public class ControlFlow {
@@ -106,7 +106,7 @@ public class ControlFlow {
LazyValue __ = c.getVariable("_");
c.setVariable("_", (__c, __t) -> ret.data.reboundedTo("_"));
LazyValue _trace = c.getVariable("_trace");
c.setVariable("_trace", (__c, __t) -> MapValue.wrap(ImmutableMap.of(
c.setVariable("_trace", (__c, __t) -> MapValue.wrap(Map.of(
StringValue.of("stack"), ListValue.wrap(ret.stack.stream().map(f -> ListValue.of(
StringValue.of(f.getModule().getName()),
StringValue.of(f.getString()),
@@ -123,9 +123,8 @@ public class Functions {
return (cc, tt) -> result;
}
Value v1 = lv1.evalValue(c, Context.SIGNATURE);
if (!(v1 instanceof FunctionSignatureValue))
if (!(v1 instanceof FunctionSignatureValue sign))
throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
FunctionSignatureValue sign = (FunctionSignatureValue) v1;
Value result = expression.createUserDefinedFunction(c, sign.getName(), e, t, sign.getArgs(), sign.getVarArgs(), sign.getGlobals(), lv2);
return (cc, tt) -> result;
});
@@ -51,9 +51,8 @@ public class Sys {
expression.addUnaryFunction("number", v ->
{
if (v instanceof NumericValue)
if (v instanceof NumericValue num)
{
NumericValue num = (NumericValue)v;
if (num.isInteger()) return new NumericValue(num.getLong());
return new NumericValue(num.getDouble());
}
@@ -18,7 +18,6 @@ import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.command.CommandException;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.WorldSavePath;
import org.apache.commons.lang3.tuple.Triple;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@@ -55,6 +54,7 @@ public class AppStoreManager
*/
private static String scarpetRepoLink = "https://api.github.com/repos/gnembon/scarpet/contents/programs/";
private static record AppInfo(String name, String url, StoreNode source) {}
public static class ScarpetAppStoreValidator extends Validator<String>
{
@@ -253,23 +253,23 @@ public class AppStoreManager
public static int downloadScript(ServerCommandSource source, String path)
{
Triple<String, String, StoreNode> nodeInfo = getFileNode(path);
AppInfo nodeInfo = getFileNode(path);
return downloadScript(source, path, nodeInfo, false);
}
private static int downloadScript(ServerCommandSource source, String path, Triple<String, String, StoreNode> nodeInfo, boolean useTrash)
private static int downloadScript(ServerCommandSource source, String path, AppInfo nodeInfo, boolean useTrash)
{
String code;
try
{
code = getStringFromStream(nodeInfo.getMiddle());
code = getStringFromStream(nodeInfo.url());
}
catch (IOException e)
{
throw new CommandException(Messenger.c("rb Failed to obtain app file content: "+e.getMessage()));
}
if (!saveScriptToFile(source, path, nodeInfo.getLeft(), code, false, useTrash)) return 0;
boolean success = CarpetServer.scriptServer.addScriptHost(source, nodeInfo.getLeft().replaceFirst("\\.sc$", ""), null, true, false, false, nodeInfo.getRight());
if (!saveScriptToFile(source, path, nodeInfo.name(), code, false, useTrash)) return 0;
boolean success = CarpetServer.scriptServer.addScriptHost(source, nodeInfo.name().replaceFirst("\\.sc$", ""), null, true, false, false, nodeInfo.source());
return success?1:0;
}
@@ -278,12 +278,12 @@ public class AppStoreManager
* @param appPath The user inputted path to the scarpet script
* @return Pair of app file name and content
*/
public static Triple<String, String, StoreNode> getFileNode(String appPath)
public static AppInfo getFileNode(String appPath)
{
return getFileNodeFrom(APP_STORE_ROOT, appPath);
}
public static Triple<String, String, StoreNode> getFileNodeFrom(StoreNode start, String appPath)
public static AppInfo getFileNodeFrom(StoreNode start, String appPath)
{
String[] path = appPath.split("/");
StoreNode appKiosk = start;
@@ -293,7 +293,7 @@ public class AppStoreManager
appKiosk = appKiosk.drillDown(pathElement);
String appName = path[path.length-1];
appKiosk.getValue(appName);
return Triple.of(appName, appKiosk.getValue(appName), appKiosk);
return new AppInfo(appName, appKiosk.getValue(appName), appKiosk);
}
catch (IOException e)
{
@@ -390,8 +390,8 @@ public class AppStoreManager
if (original.matches("^https?://.*$")) // We've got a full url here: Just use it
return original;
if (original.charAt(0) == '/') // We've got an absolute path: Use app store root
return getFileNode(original.substring(1)).getMiddle();
return getFileNodeFrom(storeSource, original).getMiddle(); // Relative path: Use download location
return getFileNode(original.substring(1)).url();
return getFileNodeFrom(storeSource, original).url(); // Relative path: Use download location
}
public static void addResource(CarpetScriptHost carpetScriptHost, StoreNode storeSource, Value resource)
@@ -461,7 +461,7 @@ public class AppStoreManager
throw new InternalExpressionException("App resource tried to leave script reserved space");
try
{
downloadScript(carpetScriptHost.responsibleSource, target, Triple.of(target, contentUrl, getNewStoreNode(storeSource, source, contentUrl)), true);
downloadScript(carpetScriptHost.responsibleSource, target, new AppInfo(target, contentUrl, getNewStoreNode(storeSource, source, contentUrl)), true);
}
catch (CommandException e)
{
@@ -2,7 +2,6 @@ package carpet.script.utils;
import carpet.CarpetSettings;
import carpet.network.ServerNetworkHandler;
import carpet.script.CarpetContext;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
@@ -16,8 +15,6 @@ import carpet.script.value.MapValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -45,7 +42,6 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.util.registry.RegistryKey;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.Collection;
@@ -60,11 +56,14 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import static java.util.Map.entry;
public class ShapeDispatcher
{
private static final Map<String, ParticleEffect> particleCache = new HashMap<>();
public static record ShapeWithConfig(ExpiringShape shape, Map<String, Value> config) {}
public static Pair<ExpiringShape,Map<String, Value>> fromFunctionArgs(
public static ShapeWithConfig fromFunctionArgs(
MinecraftServer server, ServerWorld world,
List<Value> lv,
Set<ServerPlayerEntity> playerSet
@@ -114,10 +113,10 @@ public class ShapeDispatcher
}
params.remove("player");
}
return Pair.of(ShapeDispatcher.create(server, shapeType, params), params);
return new ShapeWithConfig(ShapeDispatcher.create(server, shapeType, params), params);
}
public static void sendShape(Collection<ServerPlayerEntity> players, List<Pair<ExpiringShape,Map<String, Value>>> shapes)
public static void sendShape(Collection<ServerPlayerEntity> players, List<ShapeWithConfig> shapes)
{
List<ServerPlayerEntity> clientPlayers = new ArrayList<>();
List<ServerPlayerEntity> alternativePlayers = new ArrayList<>();
@@ -137,9 +136,9 @@ public class ShapeDispatcher
NbtList tag = new NbtList();
int tagcount = 0;
for (Pair<ExpiringShape, Map<String, Value>> s : shapes)
for (ShapeWithConfig s : shapes)
{
tag.add(ExpiringShape.toTag(s.getRight())); // 4000 shapes limit boxes
tag.add(ExpiringShape.toTag(s.config())); // 4000 shapes limit boxes
if (tagcount++>1000)
{
tagcount = 0;
@@ -154,7 +153,7 @@ public class ShapeDispatcher
if (!alternativePlayers.isEmpty())
{
List<Consumer<ServerPlayerEntity>> alternatives = new ArrayList<>();
shapes.forEach(s -> alternatives.add(s.getLeft().alternative()));
shapes.forEach(s -> alternatives.add(s.shape().alternative()));
alternativePlayers.forEach(p -> alternatives.forEach( a -> a.accept(p)));
}
}
@@ -405,8 +404,8 @@ public class ShapeDispatcher
}
// list of params that need to be there
private final Set<String> required = ImmutableSet.of("duration", "shape", "dim");
private final Map<String, Value> optional = ImmutableMap.of(
private final Set<String> required = Set.of("duration", "shape", "dim");
private final Map<String, Value> optional = Map.of(
"color", new NumericValue(-1),
"follow", new NumericValue(-1),
"line", new NumericValue(2.0),
@@ -425,20 +424,19 @@ public class ShapeDispatcher
public static class DisplayedText extends ExpiringShape
{
private final Set<String> required = ImmutableSet.of("pos", "text");
private final Map<String, Value> optional = ImmutableMap.<String, Value>builder().
put("facing", new StringValue("player")).
put("raise", new NumericValue(0)).
put("tilt", new NumericValue(0)).
put("lean", new NumericValue(0)).
put("turn", new NumericValue(0)).
put("indent", new NumericValue(0)).
put("height", new NumericValue(0)).
put("align", new StringValue("center")).
put("size", new NumericValue(10)).
put("value", Value.NULL).
put("doublesided", new NumericValue(0)).
build();
private final Set<String> required = Set.of("pos", "text");
private final Map<String, Value> optional = Map.ofEntries(
entry("facing", new StringValue("player")),
entry("raise", new NumericValue(0)),
entry("tilt", new NumericValue(0)),
entry("lean", new NumericValue(0)),
entry("turn", new NumericValue(0)),
entry("indent", new NumericValue(0)),
entry("height", new NumericValue(0)),
entry("align", new StringValue("center")),
entry("size", new NumericValue(10)),
entry("value", Value.NULL),
entry("doublesided", new NumericValue(0)));
@Override
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
@Override
@@ -552,8 +550,8 @@ public class ShapeDispatcher
public static class Box extends ExpiringShape
{
private final Set<String> required = ImmutableSet.of("from", "to");
private final Map<String, Value> optional = ImmutableMap.of();
private final Set<String> required = Set.of("from", "to");
private final Map<String, Value> optional = Map.of();
@Override
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
@Override
@@ -630,8 +628,8 @@ public class ShapeDispatcher
public static class Line extends ExpiringShape
{
private final Set<String> required = ImmutableSet.of("from", "to");
private final Map<String, Value> optional = ImmutableMap.of();
private final Set<String> required = Set.of("from", "to");
private final Map<String, Value> optional = Map.of();
@Override
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
@Override
@@ -683,8 +681,8 @@ public class ShapeDispatcher
public static class Sphere extends ExpiringShape
{
private final Set<String> required = ImmutableSet.of("center", "radius");
private final Map<String, Value> optional = ImmutableMap.of("level", Value.ZERO);
private final Set<String> required = Set.of("center", "radius");
private final Map<String, Value> optional = Map.of("level", Value.ZERO);
@Override
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
@Override
@@ -755,8 +753,8 @@ public class ShapeDispatcher
}
public static class Cylinder extends ExpiringShape
{
private final Set<String> required = ImmutableSet.of("center", "radius");
private final Map<String, Value> optional = ImmutableMap.of(
private final Set<String> required = Set.of("center", "radius");
private final Map<String, Value> optional = Map.of(
"level", Value.ZERO,
"height", Value.ZERO,
"axis", new StringValue("y")
@@ -913,6 +911,7 @@ public class ShapeDispatcher
@Override
public NbtElement toTag(Value value) { return NbtString.of(value.getString()); }
@Override
public Value decode(NbtElement tag) { return new StringValue(tag.asString()); }
}
public static class TextParam extends StringParam
@@ -1149,6 +1148,7 @@ public class ShapeDispatcher
throw new InternalExpressionException("'"+p.id+"' requires a triple, block or entity to indicate position");
}
@Override
public Value decode(NbtElement tag)
{
NbtList ctag = (NbtList)tag;
@@ -1187,6 +1187,7 @@ public class ShapeDispatcher
return ListValue.wrap(points);
}
@Override
public Value decode(NbtElement tag)
{
NbtList ltag = (NbtList)tag;
@@ -1228,6 +1229,7 @@ public class ShapeDispatcher
super(id);
}
@Override
public Value decode(NbtElement tag) { return new NumericValue(((NbtInt)tag).intValue()); }
@Override
public NbtElement toTag(Value value) { return NbtInt.of(NumericValue.asNumber(value, id).getInt()); }
@@ -1254,6 +1256,7 @@ public class ShapeDispatcher
return new NumericValue(player.getId());
}
@Override
public Value decode(NbtElement tag) { return new NumericValue(((NbtInt)tag).intValue()); }
}
@@ -38,6 +38,7 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler {
return g;
}
@Override
public double sample2d(double x, double y) {
x = x/2;
y = y/2;
@@ -75,6 +76,7 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler {
return 35.0D * (aa + ab + ac)+0.5;
}
@Override
public double sample3d(double d, double e, double f) {
d = d/2;
e = e/2;
@@ -122,6 +122,7 @@ public class SnoopyCommandSource extends ServerCommandSource
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, consumer, entityAnchor, error, chatOutput);
}
@Override
public ServerCommandSource mergeConsumers(ResultConsumer<ServerCommandSource> consumer, BinaryOperator<ResultConsumer<ServerCommandSource>> binaryOperator)
{
ResultConsumer<ServerCommandSource> resultConsumer = binaryOperator.apply(this.resultConsumer, consumer);
@@ -133,7 +133,7 @@ public class SystemInfo {
put("java_system_cpu_load", c -> {
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
OperatingSystemMXBean.class);
return new NumericValue(osBean.getSystemCpuLoad());
return new NumericValue(osBean.getCpuLoad());
});
put("java_process_cpu_load", c -> {
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
@@ -1,7 +1,6 @@
package carpet.script.utils;
import carpet.fakes.MinecraftServerInterface;
import com.google.common.collect.ImmutableList;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket;
@@ -93,7 +92,7 @@ public class WorldTools
boolean bl = generatorOptions.isDebugWorld();
long l = generatorOptions.getSeed();
long m = BiomeAccess.hashSeed(l);
List<Spawner> list = ImmutableList.of();
List<Spawner> list = List.of();
SimpleRegistry<DimensionOptions> simpleRegistry = generatorOptions.getDimensions();
DimensionOptions dimensionOptions = simpleRegistry.get(DimensionOptions.OVERWORLD);
ChunkGenerator chunkGenerator2;
@@ -8,7 +8,7 @@ import java.util.List;
public abstract class AbstractListValue extends Value implements Iterable<Value>
{
public abstract Iterator<Value> iterator();
@Override public abstract Iterator<Value> iterator();
public List<Value> unpack() { return Lists.newArrayList(iterator()); }
public void fatality() { }
public void append(Value v)
@@ -12,7 +12,7 @@ public class BooleanValue extends NumericValue
boolean boolValue;
private BooleanValue(boolean boolval) {
super(boolval);
super(boolval ? 1L : 0L);
boolValue = boolval;
}
@@ -6,7 +6,6 @@ import carpet.fakes.ItemEntityInterface;
import carpet.fakes.LivingEntityInterface;
import carpet.fakes.MemoryInterface;
import carpet.fakes.MobEntityInterface;
import carpet.fakes.HungerManagerInterface;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInteractionManagerInterface;
import carpet.helpers.Tracer;
@@ -413,14 +412,14 @@ public class EntityValue extends Value
throw new InternalExpressionException("Cannot fetch '"+what+"' with these arguments");
}
}
private static final Map<String, EquipmentSlot> inventorySlots = new HashMap<String, EquipmentSlot>(){{
put("mainhand", EquipmentSlot.MAINHAND);
put("offhand", EquipmentSlot.OFFHAND);
put("head", EquipmentSlot.HEAD);
put("chest", EquipmentSlot.CHEST);
put("legs", EquipmentSlot.LEGS);
put("feet", EquipmentSlot.FEET);
}};
private static final Map<String, EquipmentSlot> inventorySlots = Map.of(
"mainhand", EquipmentSlot.MAINHAND,
"offhand", EquipmentSlot.OFFHAND,
"head", EquipmentSlot.HEAD,
"chest", EquipmentSlot.CHEST,
"legs", EquipmentSlot.LEGS,
"feet", EquipmentSlot.FEET
);
private static final Map<String, BiFunction<Entity, Value, Value>> featureAccessors = new HashMap<String, BiFunction<Entity, Value, Value>>() {{
//put("test", (e, a) -> a == null ? Value.NULL : new StringValue(a.getString()));
@@ -530,9 +529,8 @@ public class EntityValue extends Value
return Value.NULL;
});
put("spawn_point", (e, a) -> {
if (e instanceof ServerPlayerEntity)
if (e instanceof ServerPlayerEntity spe)
{
ServerPlayerEntity spe = (ServerPlayerEntity)e;
if (spe.getSpawnPointPosition() == null) return Value.FALSE;
return ListValue.of(
ValueConversions.of(spe.getSpawnPointPosition()),
@@ -573,7 +571,7 @@ public class EntityValue extends Value
});
put("exhaustion",(e, a)->{
if(e instanceof PlayerEntity) return new NumericValue(((HungerManagerInterface)((PlayerEntity) e).getHungerManager()).getExhaustionCM());
if(e instanceof PlayerEntity) return new NumericValue(((PlayerEntity) e).getHungerManager().getExhaustion());
return Value.NULL;
});
@@ -631,9 +629,8 @@ public class EntityValue extends Value
String module = a.getString();
MemoryModuleType<?> moduleType = Registry.MEMORY_MODULE_TYPE.get(InputValidator.identifierOf(module));
if (moduleType == MemoryModuleType.DUMMY) return Value.NULL;
if (e instanceof LivingEntity)
if (e instanceof LivingEntity livingEntity)
{
LivingEntity livingEntity = (LivingEntity)e;
Brain<?> brain = livingEntity.getBrain();
Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> memories = ((BrainInterface)brain).getMobMemories();
Optional<? extends Memory<?>> optmemory = memories.get(moduleType);
@@ -652,9 +649,8 @@ public class EntityValue extends Value
});
put("permission_level", (e, a) -> {
if (e instanceof ServerPlayerEntity)
if (e instanceof ServerPlayerEntity spe)
{
ServerPlayerEntity spe = (ServerPlayerEntity) e;
for (int i=4; i>=0; i--)
{
if (spe.hasPermissionLevel(i))
@@ -667,10 +663,9 @@ public class EntityValue extends Value
});
put("player_type", (e, a) -> {
if (e instanceof PlayerEntity)
if (e instanceof PlayerEntity p)
{
if (e instanceof EntityPlayerMPFake) return new StringValue(((EntityPlayerMPFake) e).isAShadow?"shadow":"fake");
PlayerEntity p = (PlayerEntity)e;
MinecraftServer server = p.getEntityWorld().getServer();
if (server.isDedicated()) return new StringValue("multiplayer");
boolean runningLan = server.isRemote();
@@ -927,9 +922,8 @@ public class EntityValue extends Value
e.refreshPositionAndAngles(x, y, z, yaw, pitch);
// we were sending to players for not-living entites, that were untracked. Living entities should be tracked.
//((ServerWorld) e.getEntityWorld()).getChunkManager().sendToNearbyPlayers(e, new EntityS2CPacket.(e));
if (e instanceof LivingEntity)
if (e instanceof LivingEntity le)
{
LivingEntity le = (LivingEntity)e;
le.prevBodyYaw = le.prevYaw = yaw;
le.prevHeadYaw = le.headYaw = yaw;
// seems universal for:
@@ -956,9 +950,8 @@ public class EntityValue extends Value
put("age", (e, v) -> e.age = Math.abs((int)NumericValue.asNumber(v).getLong()) );
put("health", (e, v) -> {
float health = (float) NumericValue.asNumber(v).getDouble();
if (health <= 0f && e instanceof ServerPlayerEntity)
if (health <= 0f && e instanceof ServerPlayerEntity player)
{
ServerPlayerEntity player = (ServerPlayerEntity) e;
if (player.currentScreenHandler != null)
{
// if player dies with open container, then that causes NPE on the client side
@@ -1273,8 +1266,7 @@ public class EntityValue extends Value
}); //requires mixing
put("spawn_point", (e, a) -> {
if (!(e instanceof ServerPlayerEntity)) return;
ServerPlayerEntity spe = (ServerPlayerEntity)e;
if (!(e instanceof ServerPlayerEntity spe)) return;
if (a == null)
{
spe.setSpawnPoint(null, null, 0, false, false);
@@ -1302,9 +1294,8 @@ public class EntityValue extends Value
}
spe.setSpawnPoint(world, pos, angle, forced, false);
}
else if (a instanceof BlockValue)
else if (a instanceof BlockValue bv)
{
BlockValue bv= (BlockValue)a;
if (bv.getPos()==null || bv.getWorld() == null)
throw new InternalExpressionException("block for spawn modification should be localised in the world");
spe.setSpawnPoint(bv.getWorld().getRegistryKey(), bv.getPos(), e.getYaw(), true, false); // yaw
@@ -1367,8 +1358,7 @@ public class EntityValue extends Value
});
put("effect", (e, v) ->
{
if (!(e instanceof LivingEntity)) return;
LivingEntity le = (LivingEntity)e;
if (!(e instanceof LivingEntity le)) return;
if (v == null)
{
le.clearStatusEffects();
@@ -1473,7 +1463,7 @@ public class EntityValue extends Value
});
put("exhaustion", (e, v)-> {
if(e instanceof PlayerEntity) ((HungerManagerInterface) ((PlayerEntity) e).getHungerManager()).setExhaustionCM(NumericValue.asNumber(v).getFloat());
if(e instanceof PlayerEntity) ((PlayerEntity) e).getHungerManager().setExhaustion(NumericValue.asNumber(v).getFloat());
});
put("add_exhaustion", (e, v)-> {
@@ -1506,7 +1496,7 @@ public class EntityValue extends Value
});
put("saturation", (e, v)-> {
if(e instanceof PlayerEntity) ((HungerManagerInterface) ((PlayerEntity) e).getHungerManager()).setSaturationCM(NumericValue.asNumber(v, "saturation").getFloat());
if(e instanceof PlayerEntity) ((PlayerEntity) e).getHungerManager().setSaturationLevel(NumericValue.asNumber(v, "saturation").getFloat());
});
put("air", (e, v) -> e.setAir(NumericValue.asNumber(v, "air").getInt()));
@@ -109,9 +109,9 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
{
return hasNext();
}
public abstract boolean hasNext();
@Override public abstract boolean hasNext();
public abstract Value next();
@Override public abstract Value next();
@Override
public void fatality() {reset();}
@@ -149,6 +149,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
{
items.add(v);
}
@Override
public Value subtract(Value other)
{
ListValue output = new ListValue();
@@ -182,6 +184,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
}
@Override
public Value multiply(Value other)
{
ListValue output = new ListValue();
@@ -209,6 +212,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
}
return output;
}
@Override
public Value divide(Value other)
{
ListValue output = new ListValue();
@@ -272,8 +277,10 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
return items;
}
@Override
public Iterator<Value> iterator() { return new ArrayList<>(items).iterator(); } // should be thread safe
@Override
public List<Value> unpack()
{
return new ArrayList<>(items);
@@ -235,11 +235,11 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
{
Inventory inv = null;
Entity e = ((EntityValue) v1).getEntity();
if (e instanceof PlayerEntity) inv = ((PlayerEntity) e).getInventory();
if (e instanceof PlayerEntity pe) inv = pe.getInventory();
else if (e instanceof Inventory) inv = (Inventory) e;
else if (e instanceof InventoryOwner) inv = ((InventoryOwner) e).getInventory();
else if (e instanceof InventoryBearerInterface) inv = ((InventoryBearerInterface)e).getCMInventory(); // horse only
else if (e instanceof LivingEntity) return new InventoryLocator(e, e.getBlockPos(), new EquipmentInventory((MobEntity) e), offset+1);
else if (e instanceof InventoryOwner io) inv = io.getInventory();
else if (e instanceof InventoryBearerInterface ibi) inv = ibi.getCMInventory(); // horse only
else if (e instanceof LivingEntity le) return new InventoryLocator(e, e.getBlockPos(), new EquipmentInventory(le), offset+1);
if (inv == null)
return null;
@@ -633,26 +633,12 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
return false;
}
public static class InventoryLocator
public static record InventoryLocator(Object owner, BlockPos position, Inventory inventory, int offset, boolean isEnder)
{
public Object owner;
public BlockPos position;
public Inventory inventory;
public int offset;
public boolean isEnder;
InventoryLocator(Object owner, BlockPos pos, Inventory i, int o)
{
this(owner, pos, i, o, false);
}
InventoryLocator(Object owner, BlockPos pos, Inventory i, int o, boolean isEnder)
{
this.owner = owner;
position = pos;
inventory = i;
offset = o;
this.isEnder = isEnder;
}
}
private static Map<String, NbtPathArgumentType.NbtPath> pathCache = new HashMap<>();
@@ -33,7 +33,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
{
return new NullValue();
}
private NullValue() {super(false);}
private NullValue() {super(0);}
@Override
public boolean equals(final Object o)
@@ -110,9 +110,8 @@ public class NumericValue extends Value
@Override
public Value add(Value v)
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
if (v instanceof NumericValue)
if (v instanceof NumericValue nv)
{
NumericValue nv = (NumericValue)v;
if (longValue != null && nv.longValue != null)
{
return new NumericValue(longValue+nv.longValue);
@@ -121,10 +120,11 @@ public class NumericValue extends Value
}
return super.add(v);
}
@Override
public Value subtract(Value v) { // TODO test if definintn add(NumericVlaue) woud solve the casting
if (v instanceof NumericValue)
if (v instanceof NumericValue nv)
{
NumericValue nv = (NumericValue)v;
if (longValue != null && nv.longValue != null)
{
return new NumericValue(longValue-nv.longValue);
@@ -133,11 +133,12 @@ public class NumericValue extends Value
}
return super.subtract(v);
}
@Override
public Value multiply(Value v)
{
if (v instanceof NumericValue)
if (v instanceof NumericValue nv)
{
NumericValue nv = (NumericValue)v;
if (longValue != null && nv.longValue != null)
{
return new NumericValue(longValue*nv.longValue);
@@ -150,6 +151,8 @@ public class NumericValue extends Value
}
return new StringValue(StringUtils.repeat(v.getString(), (int) getLong()));
}
@Override
public Value divide(Value v)
{
//if (1+2==3) throw new ArithmeticException("Booyah");
@@ -173,9 +176,8 @@ public class NumericValue extends Value
{
return -o.compareTo(this);
}
if (o instanceof NumericValue)
if (o instanceof NumericValue no)
{
NumericValue no = (NumericValue)o;
if (longValue != null && no.longValue != null)
return longValue.compareTo(no.longValue);
return Double.compare(value, no.value);
@@ -189,9 +191,8 @@ public class NumericValue extends Value
{
return o.equals(this);
}
if (o instanceof NumericValue)
if (o instanceof NumericValue no)
{
NumericValue no = (NumericValue)o;
if (longValue != null && no.longValue != null)
return longValue.equals(no.longValue);
return !this.subtract(no).getBoolean();
@@ -228,17 +229,6 @@ public class NumericValue extends Value
this.value = (double)value;
}
/**
* Creates a legacy {@link NumericValue} for a {@code boolean}.
* @param boolval The boolean to set 1 or 0 for this {@link NumericValue}
* @deprecated Use {@link BooleanValue#of(boolean)} instead
*/
@Deprecated
public NumericValue(boolean boolval)
{
this(boolval?1L:0L);
}
@Override
public int length()
{
@@ -123,9 +123,8 @@ public class ValueConversions
{
return ((EntityValue)dimensionValue).getEntity().getEntityWorld();
}
else if (dimensionValue instanceof BlockValue)
else if (dimensionValue instanceof BlockValue bv)
{
BlockValue bv = (BlockValue)dimensionValue;
if (bv.getWorld() != null)
{
return bv.getWorld();
@@ -225,9 +224,8 @@ public class ValueConversions
private static Value fromEntityMemory(Entity e, Object v)
{
if (v instanceof GlobalPos)
if (v instanceof GlobalPos pos)
{
GlobalPos pos = (GlobalPos)v;
return of(pos);
}
if (v instanceof Entity)
@@ -250,9 +248,8 @@ public class ValueConversions
{
return ofUUID( (ServerWorld) e.getEntityWorld(), (UUID)v);
}
if (v instanceof DamageSource)
if (v instanceof DamageSource source)
{
DamageSource source = (DamageSource) v;
return ListValue.of(
new StringValue(source.getName()),
source.getAttacker()==null?Value.NULL:new EntityValue(source.getAttacker())
@@ -278,9 +275,8 @@ public class ValueConversions
{
v = new ArrayList(((Set) v));
}
if (v instanceof List)
if (v instanceof List l)
{
List l = (List)v;
if (l.isEmpty()) return ListValue.of();
Object el = l.get(0);
if (el instanceof Entity)