Server bei Bedarf anfordern
Server-Starts werden über die Groups API eingereiht. Das zurückgegebene Future ist abgeschlossen, sobald die Anfrage angenommen wurde, nicht sobald der neue Server bereit ist.Einzelnen Server anfordern
public CompletableFuture<Void> requestServerStart(String groupName) {
return api.group().getGroupByName(groupName)
.thenCompose(group -> {
if (group == null) {
return CompletableFuture.failedFuture(
new IllegalArgumentException("Gruppe nicht gefunden: " + groupName));
}
return api.group().requestServerStart(group);
});
}
Mehrere Server anfordern
public void ensureMinimumServers(String groupName, int minimum) {
api.server().getServersByGroup(groupName).thenAccept(servers -> {
long running = servers.stream()
.filter(server -> server.getState() != ServerState.STOPPING)
.filter(server -> server.getState() != ServerState.CLEANUP)
.count();
int toStart = Math.max(0, minimum - (int) running);
for (int i = 0; i < toStart; i++) {
requestServerStart(groupName)
.thenRun(() -> System.out.println("Start-Anfrage angenommen: " + groupName));
}
});
}
Server stoppen
Einzelnen Server stoppen
public void stopServer(String serverId) {
api.server().stopServer(serverId)
.thenRun(() -> System.out.println("Stop angefragt: " + serverId));
}
Leere Server stoppen
public void stopEmptyServers(String groupName, int keepMinimum) {
api.server().getServersByGroup(groupName).thenAccept(servers -> {
List<Server> emptyServers = servers.stream()
.filter(server -> server.getState() == ServerState.AVAILABLE)
.filter(server -> server.getPlayerCount() != null && server.getPlayerCount() == 0)
.sorted(Comparator.comparingInt(Server::getNumericalId).reversed())
.toList();
int toStop = Math.max(0, emptyServers.size() - keepMinimum);
emptyServers.stream()
.limit(toStop)
.forEach(server -> api.server().stopServer(server.getServerId()));
});
}
Graceful Shutdown mit Spieler-Evakuierung
public void gracefulStop(String serverId, String fallbackServer) {
api.server().getServerById(serverId).thenAccept(server -> {
if (server == null) return;
api.player().getOnlinePlayers().thenAccept(players -> {
List<CompletableFuture<CloudPlayer.ConnectResult>> transfers = players.stream()
.filter(player -> serverId.equals(player.getConnectedServerName()))
.map(player -> {
player.sendMessage(Component.text("Server fährt herunter...")
.color(NamedTextColor.YELLOW));
return player.connect(fallbackServer);
})
.toList();
CompletableFuture.allOf(transfers.toArray(new CompletableFuture[0]))
.thenRun(() -> api.server().stopServer(serverId));
});
});
}
Server überwachen
Server-Anzahl beobachten
public void monitorServerCount(String groupName) {
api.event().server().onStarted(event -> {
Server server = event.getServer();
if (server.isFromGroup() && groupName.equals(server.getGroup().getName())) {
updateServerCount(groupName);
}
});
api.event().server().onStopped(event -> {
Server server = event.getServer();
if (server.isFromGroup() && groupName.equals(server.getGroup().getName())) {
updateServerCount(groupName);
}
});
}
private void updateServerCount(String groupName) {
api.server().getServersByGroup(groupName).thenAccept(servers -> {
System.out.println(groupName + " Server: " + servers.size());
});
}
Server finden
Server mit niedrigster Spielerzahl finden
public CompletableFuture<Server> findBestServer(String groupName) {
return api.server().getServersByGroup(groupName)
.thenApply(servers -> servers.stream()
.filter(server -> server.getState() == ServerState.AVAILABLE ||
server.getState() == ServerState.INGAME)
.filter(server -> server.getPlayerCount() != null)
.filter(server -> server.getPlayerCount() < server.getMaxPlayers())
.min(Comparator.comparingInt(Server::getPlayerCount))
.orElse(null));
}