.
This commit is contained in:
parent
46978ae799
commit
ce56c6e105
53 changed files with 776 additions and 891 deletions
|
|
@ -43,4 +43,12 @@ genrule(
|
|||
outs = ["plugin.jar"],
|
||||
cmd = "cp $< $@",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
load("//rules:publish_plugin.bzl", "publish_plugin")
|
||||
publish_plugin(
|
||||
name = "plugin-publish",
|
||||
package = "core-bukkit",
|
||||
filename = "CoreBukkit.jar",
|
||||
src = ":plugin",
|
||||
)
|
||||
|
|
@ -2,10 +2,6 @@ package de.kentoj.scrow.bukkit;
|
|||
|
||||
import de.kentoj.scrow.bukkit.command.economy.CoinsCommand;
|
||||
import de.kentoj.scrow.bukkit.command.friends.FriendCommand;
|
||||
import de.kentoj.scrow.bukkit.command.instance.InstanceCache;
|
||||
import de.kentoj.scrow.bukkit.command.instance.InstanceCommand;
|
||||
import de.kentoj.scrow.bukkit.command.instance.LobbyCommand;
|
||||
import de.kentoj.scrow.bukkit.command.instance.PlayCommand;
|
||||
import de.kentoj.scrow.bukkit.internal.player.prefix.CachedPrefixProvider;
|
||||
import de.kentoj.scrow.bukkit.internal.player.prefix.LuckPermsPrefixSetter;
|
||||
import de.kentoj.scrow.bukkit.style.ChatStyleListener;
|
||||
|
|
@ -27,10 +23,6 @@ public final class CoreImplPlugin extends JavaPlugin {
|
|||
|
||||
ScrowAPI.playerCommands().register(new CoinsCommand().rootLiteral());
|
||||
ScrowAPI.playerCommands().register(new FriendCommand().rootLiteral());
|
||||
var instanceCache = new InstanceCache();
|
||||
ScrowAPI.commands().register(new InstanceCommand(instanceCache).rootLiteral());
|
||||
ScrowAPI.playerCommands().register(new PlayCommand().rootLiteral());
|
||||
ScrowAPI.playerCommands().register(new LobbyCommand().rootLiteral());
|
||||
|
||||
var luckperms = LuckPermsProvider.get();
|
||||
new LuckPermsPrefixSetter(luckperms, cachedPrefixProvider).init(this);
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command.instance;
|
||||
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrowlib.instancemanager.ServerInstance;
|
||||
import org.bson.Document;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class InstanceCache {
|
||||
|
||||
private final ConcurrentMap<String, ServerInstance> cache = new ConcurrentHashMap<>();
|
||||
|
||||
public InstanceCache() {
|
||||
ScrowAPI.messageBroker().subscribe("event.instance.up", doc -> {
|
||||
var inst = toInstance(doc);
|
||||
cache.put(inst.handle(), inst);
|
||||
});
|
||||
ScrowAPI.messageBroker().subscribe("event.instance.down", doc ->
|
||||
cache.remove(doc.getString("handle")));
|
||||
}
|
||||
|
||||
public Collection<ServerInstance> getInstances() {
|
||||
return cache.values();
|
||||
}
|
||||
|
||||
public @Nullable ServerInstance getInstance(String handle) {
|
||||
return cache.get(handle);
|
||||
}
|
||||
|
||||
private ServerInstance toInstance(Document doc) {
|
||||
return new ServerInstance(
|
||||
doc.getString("handle"),
|
||||
doc.getString("template"),
|
||||
doc.getInteger("port")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command.instance;
|
||||
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public final class InstanceCommand {
|
||||
|
||||
private final RootLiteral<CommandSender> rootLiteral;
|
||||
|
||||
public InstanceCommand(InstanceCache instanceCache) {
|
||||
rootLiteral = Literal.<CommandSender>builder("instance", "server-manager")
|
||||
.withLiteral(new InstanceListLiteral().literal())
|
||||
.withLiteral(new InstanceDeployLiteral().literal())
|
||||
.withLiteral(new InstanceDestroyLiteral(instanceCache).literal())
|
||||
.asRootLiteral(new ScrowMessageStyle("server-manager", NamedTextColor.RED));
|
||||
}
|
||||
|
||||
public RootLiteral<CommandSender> rootLiteral() {
|
||||
return rootLiteral;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command.instance;
|
||||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.scheduler.Tasks;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public final class InstanceDeployLiteral {
|
||||
|
||||
private final Literal<CommandSender> literal;
|
||||
private final CommandArgumentSpec<CommandSender, String> templateArg;
|
||||
|
||||
InstanceDeployLiteral() {
|
||||
templateArg = CommandArgumentSpec.builder("template", new StringArgumentType<CommandSender>())
|
||||
.build();
|
||||
literal = Literal.<CommandSender>builder("deploy")
|
||||
.withArgument(templateArg)
|
||||
.withExecutor(this::deployInstance)
|
||||
.build();
|
||||
}
|
||||
|
||||
private CompletableFuture<?> deployInstance(CommandContext<CommandSender> ctx) {
|
||||
var template = ctx.getArg(templateArg);
|
||||
ctx.sender().sendMessage(ctx.style().ok("Deploying instance... this may take a while."));
|
||||
return Tasks.supplyAsync(() ->
|
||||
ScrowAPI.instanceManager().deployInstance(template))
|
||||
.thenSync(instance -> {
|
||||
ctx.sender().sendMessage(ctx.style().ok("Deployed instance of " + template + " with handle " + instance.handle() + "."));
|
||||
// FIXME handle unknown server
|
||||
}).toFuture();
|
||||
}
|
||||
|
||||
public Literal<CommandSender> literal() {
|
||||
return literal;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command.instance;
|
||||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.scheduler.Tasks;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import de.kentoj.scrowlib.instancemanager.ServerInstance;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public final class InstanceDestroyLiteral {
|
||||
|
||||
private final Literal<CommandSender> literal;
|
||||
private final CommandArgumentSpec<CommandSender, String> handleArg;
|
||||
|
||||
InstanceDestroyLiteral(InstanceCache cache) {
|
||||
handleArg = CommandArgumentSpec.builder("handle", new StringArgumentType<CommandSender>())
|
||||
.withSuggestionProvider((_, _) ->
|
||||
cache.getInstances().stream()
|
||||
.map(ServerInstance::handle)
|
||||
.toList())
|
||||
.build();
|
||||
literal = Literal.<CommandSender>builder("destroy")
|
||||
.withArgument(handleArg)
|
||||
.withExecutor(this::destroyInstance)
|
||||
.build();
|
||||
}
|
||||
|
||||
private CompletableFuture<?> destroyInstance(CommandContext<CommandSender> ctx) {
|
||||
var handle = ctx.getArg(handleArg);
|
||||
return Tasks.supplyAsync(() -> ScrowAPI.instanceManager().destroyInstance(handle))
|
||||
.thenSync(found -> {
|
||||
if (!found) {
|
||||
ctx.sender().sendMessage(ctx.style().err("No instance with that handle found."));
|
||||
return;
|
||||
}
|
||||
ctx.sender().sendMessage(ctx.style().ok("Destroyed server with handle " + handle + "."));
|
||||
}).toFuture();
|
||||
}
|
||||
|
||||
public Literal<CommandSender> literal() {
|
||||
return literal;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command.instance;
|
||||
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.scheduler.Tasks;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public final class InstanceListLiteral {
|
||||
|
||||
private final Literal<CommandSender> literal;
|
||||
|
||||
InstanceListLiteral() {
|
||||
this.literal = Literal.<CommandSender>builder("list")
|
||||
.withExecutor(this::displayInstanceList)
|
||||
.build();
|
||||
}
|
||||
|
||||
private CompletableFuture<?> displayInstanceList(CommandContext<CommandSender> ctx) {
|
||||
return Tasks.supplyAsync(() ->
|
||||
ScrowAPI.instanceManager().instances())
|
||||
.thenSync(instances -> {
|
||||
var msg = Component.text("Running instances:");
|
||||
for (var inst : instances) {
|
||||
msg = msg.appendNewline()
|
||||
.append(Component.text(" - " + inst.handle() + " on port " + inst.port()));
|
||||
}
|
||||
ctx.sender().sendMessage(ctx.style().ok(msg));
|
||||
}).toFuture();
|
||||
}
|
||||
|
||||
public Literal<CommandSender> literal() {
|
||||
return literal;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command.instance;
|
||||
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.core.Results;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class LobbyCommand {
|
||||
|
||||
private final RootLiteral<Player> rootLiteral;
|
||||
|
||||
public LobbyCommand() {
|
||||
rootLiteral = Literal.<Player>builder("lobby", "l", "hub")
|
||||
.withSyncExecutor(this::sendToLobby)
|
||||
.asRootLiteral(ScrowMessageStyle.GENERIC);
|
||||
}
|
||||
|
||||
private void sendToLobby(CommandContext<Player> ctx) {
|
||||
Bukkit.dispatchCommand(ctx.sender(), "play lobby");
|
||||
}
|
||||
|
||||
public RootLiteral<Player> rootLiteral() {
|
||||
return rootLiteral;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command.instance;
|
||||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.scheduler.Tasks;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public final class PlayCommand {
|
||||
|
||||
private final RootLiteral<Player> rootLiteral;
|
||||
private final CommandArgumentSpec<Player, String> gamemodeArg;
|
||||
|
||||
public PlayCommand() {
|
||||
var style = ScrowMessageStyle.GENERIC;
|
||||
gamemodeArg = CommandArgumentSpec.builder("gamemode", new StringArgumentType<Player>()).build();
|
||||
rootLiteral = Literal.<Player>builder("play", "queue")
|
||||
.withArgument(gamemodeArg)
|
||||
.withExecutor(this::execute)
|
||||
.asRootLiteral(style);
|
||||
}
|
||||
|
||||
private CompletableFuture<?> execute(CommandContext<Player> ctx) {
|
||||
var gamemode = ctx.getArg(gamemodeArg);
|
||||
return Tasks.supplyAsync(() -> ScrowAPI.instanceManager().instances())
|
||||
.mapSync(instances -> {
|
||||
var instance = instances.stream()
|
||||
.filter(inst -> inst.template().equals(gamemode))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (instance == null) {
|
||||
ctx.sender().sendMessage(ctx.style().err("No instance for " + gamemode + " found."));
|
||||
return null;
|
||||
}
|
||||
|
||||
return instance.handle();
|
||||
})
|
||||
.yieldIf(Objects::isNull)
|
||||
.thenAsync(handle ->
|
||||
ScrowAPI.getPlayer(ctx.sender()).sendToInstance(handle)
|
||||
).toFuture();
|
||||
}
|
||||
|
||||
public RootLiteral<Player> rootLiteral() {
|
||||
return rootLiteral;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
name: "CoreBukkit"
|
||||
version: "${version}"
|
||||
version: "UNVERSIONED"
|
||||
depend: [ "LuckPerms" ]
|
||||
main: "de.kentoj.scrow.bukkit.CoreImplPlugin"
|
||||
api-version: "1.21"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
load("@rules_jvm_external//:defs.bzl", "artifact")
|
||||
load("@rules_java//java:java_library.bzl", "java_library")
|
||||
load("@rules_java//java:java_binary.bzl", "java_binary")
|
||||
load("@rules_jvm_external//:defs.bzl", "artifact", "java_plugin_artifact")
|
||||
|
||||
java_library(
|
||||
name = "api",
|
||||
|
|
@ -20,7 +21,7 @@ java_library(
|
|||
)
|
||||
|
||||
java_binary(
|
||||
name = "plugin",
|
||||
name = "_plugin",
|
||||
srcs = glob(["plugin/main/java/**/*.java", "api/main/java/**/*.java"]),
|
||||
create_executable = False,
|
||||
deps = [
|
||||
|
|
@ -30,5 +31,29 @@ java_binary(
|
|||
artifact("io.nats:jnats"),
|
||||
artifact("de.kentoj.scrow:kencommandapi-velocity"),
|
||||
artifact("org.mongodb:bson"),
|
||||
artifact("org.postgresql:postgresql"),
|
||||
artifact("com.google.code.gson:gson"),
|
||||
],
|
||||
plugins = [
|
||||
java_plugin_artifact(
|
||||
"com.velocitypowered:velocity-api",
|
||||
"com.velocitypowered.api.plugin.ap.PluginAnnotationProcessor",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "plugin",
|
||||
srcs = [":_plugin_deploy.jar"],
|
||||
outs = ["plugin.jar"],
|
||||
cmd = "cp $< $@",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
load("//rules:publish_plugin.bzl", "publish_plugin")
|
||||
publish_plugin(
|
||||
name = "plugin-publish",
|
||||
package = "core-velocity",
|
||||
filename = "CoreVelocity.jar",
|
||||
src = ":plugin",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,17 +6,21 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
|||
import com.velocitypowered.api.plugin.Plugin;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import de.kentoj.scrow.corevelocity.misc.OnlineCommand;
|
||||
import de.kentoj.scrow.corevelocity.network.FriendNotifications;
|
||||
import de.kentoj.scrow.corevelocity.network.SendPlayerWatchdog;
|
||||
import de.kentoj.scrow.corevelocity.network.ServerRegisterWatchdog;
|
||||
import de.kentoj.scrow.corevelocity.privmsg.LastTargetCache;
|
||||
import de.kentoj.scrow.corevelocity.privmsg.MsgCommand;
|
||||
import de.kentoj.scrow.corevelocity.privmsg.PrivMsgHandler;
|
||||
import de.kentoj.scrow.corevelocity.privmsg.ReplyCommand;
|
||||
import de.kentoj.scrow.corevelocity.serverregistration.ConsulV1ServerInstanceScanner;
|
||||
import de.kentoj.scrow.corevelocity.serverregistration.RegistrationTask;
|
||||
import de.kentoj.scrow.corevelocity.serverregistration.ServerInstanceScanner;
|
||||
import de.kentoj.scrow.velocity.ScrowAPI;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import de.kentoj.scrowlib.utils.EnvUtils;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Plugin(
|
||||
id = "corevelocity",
|
||||
name = "CoreVelocity",
|
||||
|
|
@ -39,11 +43,11 @@ public final class CoreVelocityPlugin {
|
|||
ScrowAPI.playerCommands().register(new MsgCommand(server, lastTargetCache, privmsgHelper, style).rootLiteral());
|
||||
ScrowAPI.commands().register(new OnlineCommand(server).rootLiteral());
|
||||
|
||||
var registerWatchdog = new ServerRegisterWatchdog(server);
|
||||
var sendPlayerWatchdog = new SendPlayerWatchdog(server);
|
||||
registerWatchdog.listen();
|
||||
sendPlayerWatchdog.listen();
|
||||
|
||||
server.getEventManager().register(this, new FriendNotifications());
|
||||
ServerInstanceScanner instanceScanner = new ConsulV1ServerInstanceScanner(EnvUtils.envOrThrow("HOST_CONSUL"));
|
||||
server.getScheduler().buildTask(this, new RegistrationTask(server, instanceScanner))
|
||||
.repeat(Duration.ofSeconds(3))
|
||||
.schedule();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
package de.kentoj.scrow.corevelocity.network;
|
||||
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||
import de.kentoj.scrow.velocity.ScrowAPI;
|
||||
import de.kentoj.scrowlib.messaging.MessageBroker;
|
||||
import org.bson.Document;
|
||||
|
||||
public class FriendNotifications {
|
||||
|
||||
private final MessageBroker messageBroker = ScrowAPI.messageBroker();
|
||||
|
||||
@Subscribe
|
||||
private void onConnect(PostLoginEvent ev) {
|
||||
messageBroker.publish("event.player.connect", new Document("playerId", ev.getPlayer().getUniqueId()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onDisconnect(DisconnectEvent ev) {
|
||||
messageBroker.publish("event.player.disconnect", new Document("playerId", ev.getPlayer().getUniqueId()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package de.kentoj.scrow.corevelocity.network;
|
||||
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
import de.kentoj.scrow.velocity.ScrowAPI;
|
||||
import de.kentoj.scrowlib.messaging.MessageBroker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class ServerRegisterWatchdog {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ServerRegisterWatchdog.class);
|
||||
|
||||
private final MessageBroker messageBroker = ScrowAPI.messageBroker();
|
||||
private final ProxyServer server;
|
||||
|
||||
public ServerRegisterWatchdog(ProxyServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public void listen() {
|
||||
messageBroker.subscribe("event.instance.up", doc -> {
|
||||
var handle = doc.getString("handle");
|
||||
var port = doc.getInteger("port");
|
||||
server.unregisterServer(new ServerInfo(handle, new InetSocketAddress(port)));
|
||||
log.info("registered server {}", handle);
|
||||
});
|
||||
|
||||
messageBroker.subscribe("event.instance.down", doc -> {
|
||||
var handle = doc.getString("handle");
|
||||
var port = doc.getInteger("port");
|
||||
server.unregisterServer(new ServerInfo(handle, new InetSocketAddress(port)));
|
||||
log.info("unregistered server {}", handle);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package de.kentoj.scrow.corevelocity.serverregistration;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ConsulV1ServerInstanceScanner implements ServerInstanceScanner, Closeable {
|
||||
|
||||
private final String consulUrl;
|
||||
private final HttpClient client;
|
||||
|
||||
public ConsulV1ServerInstanceScanner(String consulUrl) {
|
||||
this.consulUrl = consulUrl;
|
||||
this.client = HttpClient.newHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
// FIXME query cluster-wide
|
||||
public Stream<ServerInfo> queryMinecraftServers() throws IOException, InterruptedException {
|
||||
var url = consulUrl + "/v1/agent/services/?filter=" + URLEncoder.encode("\"minecraft\" in Tags", StandardCharsets.UTF_8);
|
||||
var request = HttpRequest.newBuilder(URI.create(url))
|
||||
.GET()
|
||||
.build();
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
var jsonResponse = JsonParser.parseString(response.body()).getAsJsonObject();
|
||||
return jsonResponse.entrySet().stream()
|
||||
.map(Map.Entry::getValue)
|
||||
.map(JsonElement::getAsJsonObject)
|
||||
.map(service -> {
|
||||
var name = toServerName(service.get("Service").getAsString(), service.get("ID").getAsString());
|
||||
var host = InetSocketAddress.createUnresolved(service.get("Address").getAsString(),
|
||||
service.get("Port").getAsInt());
|
||||
return new ServerInfo(name, host);
|
||||
});
|
||||
}
|
||||
|
||||
private String toServerName(String serviceName, String id) {
|
||||
return serviceName + "-" + Integer.toUnsignedString(Hashing.murmur3_32_fixed()
|
||||
.hashString(id, StandardCharsets.UTF_8)
|
||||
.asInt(), 32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package de.kentoj.scrow.corevelocity.serverregistration;
|
||||
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class RegistrationTask implements Runnable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RegistrationTask.class);
|
||||
|
||||
private final ProxyServer server;
|
||||
private final ServerInstanceScanner watcher;
|
||||
|
||||
public RegistrationTask(ProxyServer server, ServerInstanceScanner watcher) {
|
||||
this.server = server;
|
||||
this.watcher = watcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
watcher.queryMinecraftServers().forEach(server::registerServer);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new RuntimeException("Failed querying available servers", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package de.kentoj.scrow.corevelocity.serverregistration;
|
||||
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public interface ServerInstanceScanner {
|
||||
|
||||
Stream<ServerInfo> queryMinecraftServers() throws IOException, InterruptedException;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue