Better-Whitelist/src/main/java/io/gitlab/jfronny/betterwhitelist/server/ServerScope.java

63 lines
2.9 KiB
Java
Raw Normal View History

package io.gitlab.jfronny.betterwhitelist.server;
import io.gitlab.jfronny.betterwhitelist.BetterWhitelist;
import io.gitlab.jfronny.muscript.data.Scope;
import io.gitlab.jfronny.muscript.data.Script;
import io.gitlab.jfronny.muscript.data.dynamic.DNull;
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal;
import io.gitlab.jfronny.muscript.error.LocationalException;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.minecraft.network.PacketByteBuf;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ServerScope {
public static Dynamic<?> run(Script script, Challenge challenge) {
try {
return script.run(fork(challenge));
} catch (LocationalException le) {
for (Throwable t = le; t != null; t = t.getCause()) {
if (t instanceof ServerScope.AssertFail af) throw af;
}
throw le;
}
}
private static Scope fork(Challenge challenge) {
return BetterWhitelist.SCOPE.fork().set("assert", args -> {
if (args.size() != 1 && args.size() != 2) throw new IllegalArgumentException("Invalid number of arguments for assert: expected 1 or 2 but got " + args.size());
if (!args.get(0).asBool().getValue()) throw new AssertFail(args.size() > 1 ? args.get(1).asString().getValue() : "Failed Whitelist Check");
return new DNull();
}).set("challenge", args -> {
if (args.size() == 0) throw new IllegalArgumentException("Invalid number of arguments for challenge: expected 1 or more but got 0");
PacketByteBuf buf = PacketByteBufs.create();
String challengeString = Dynamic.serialize(args.get(0).asCallable());
BetterWhitelist.LOG.info("Sending challenge to " + challenge.profile.getName() + ": " + challengeString);
buf.writeString(challengeString);
List<Dynamic<?>> params = args.getValue().subList(1, args.size());
buf.writeInt(params.size());
params.forEach(p -> buf.writeString(Dynamic.serialize(p)));
challenge.response.reset();
challenge.sender.sendPacket(BetterWhitelist.CHALLENGE_CHANNEL, buf);
try {
return challenge.response.get(1, TimeUnit.SECONDS);
} catch (TimeoutException e) {
throw new AssertFail("Took too long to respond");
}
}).set("user", Map.of(
"id", challenge.profile.getId() == null ? new DNull() : DFinal.of(challenge.profile.getId().toString()),
"name", DFinal.of(challenge.profile.getName())
));
}
public static class AssertFail extends RuntimeException {
public AssertFail(String message) {
super(message);
}
}
}