63 lines
2.9 KiB
Java
63 lines
2.9 KiB
Java
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);
|
|
}
|
|
}
|
|
}
|