Added RegistryUpdater to broadcast server data to registries.
This commit is contained in:
parent
a808ac1920
commit
e38ae65ff9
|
@ -73,7 +73,6 @@ public class ServerRegistry {
|
|||
|
||||
@Scheduled(fixedRate = 1, timeUnit = TimeUnit.MINUTES, initialDelay = 1)
|
||||
public void purgeOldServers() {
|
||||
log.info("Purging old servers.");
|
||||
Queue<ServerIdentifier> removalQueue = new LinkedList<>();
|
||||
final Instant cutoff = Instant.now().minus(SERVER_TIMEOUT);
|
||||
for (var entry : servers.entrySet()) {
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
<artifactId>jansi</artifactId>
|
||||
<version>2.4.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -107,6 +107,11 @@ public class ClientCommunicationHandler {
|
|||
socket.close();
|
||||
return;
|
||||
}
|
||||
if (server.getPlayerManager().getPlayers().size() >= server.getConfig().maxPlayers) {
|
||||
Net.write(new ConnectRejectMessage("Server is full."), out);
|
||||
socket.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to set the TCP timeout back to 0 now that we've got the correct request.
|
||||
socket.setSoTimeout(0);
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package nl.andrewl.aos2_server;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Component that sends regular updates to any configured server registries.
|
||||
*/
|
||||
public class RegistryUpdater {
|
||||
private final Server server;
|
||||
private final HttpClient httpClient;
|
||||
|
||||
public RegistryUpdater(Server server) {
|
||||
this.server = server;
|
||||
this.httpClient = HttpClient.newBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(3))
|
||||
.build();
|
||||
}
|
||||
|
||||
public void sendUpdates() {
|
||||
var cfg = server.getConfig();
|
||||
if (
|
||||
cfg.registries != null &&
|
||||
cfg.registries.length > 0 &&
|
||||
cfg.name != null && !cfg.name.isBlank()
|
||||
) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("port", cfg.port);
|
||||
data.put("name", cfg.name);
|
||||
data.put("description", cfg.description);
|
||||
data.put("maxPlayers", cfg.maxPlayers);
|
||||
data.put("currentPlayers", server.getPlayerManager().getPlayers().size());
|
||||
String json = new Gson().toJson(data);
|
||||
for (String registryUrl : server.getConfig().registries) {
|
||||
HttpRequest req = HttpRequest.newBuilder(URI.create(registryUrl + "/servers"))
|
||||
.POST(HttpRequest.BodyPublishers.ofString(json))
|
||||
.header("Content-Type", "application/json")
|
||||
.timeout(Duration.ofSeconds(3))
|
||||
.build();
|
||||
try {
|
||||
var resp = httpClient.send(req, HttpResponse.BodyHandlers.ofString());
|
||||
if (resp.statusCode() != 200) {
|
||||
System.err.println("Error response when sending registry update to " + registryUrl + ": " + resp.statusCode() + " " + resp.body());
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
System.err.println("An error occurred while sending registry update to " + registryUrl + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,7 +24,10 @@ import java.net.*;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* The central server, which mainly contains all the different managers and
|
||||
|
@ -83,11 +86,15 @@ public class Server implements Runnable {
|
|||
running = true;
|
||||
new Thread(new UdpReceiver(datagramSocket, this::handleUdpMessage)).start();
|
||||
new Thread(worldUpdater).start();
|
||||
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
||||
var registryUpdater = new RegistryUpdater(this);
|
||||
executorService.scheduleAtFixedRate(registryUpdater::sendUpdates, 0, 90, TimeUnit.SECONDS);
|
||||
System.out.printf("Started AoS2 Server on TCP/UDP port %d; now accepting connections.%n", serverSocket.getLocalPort());
|
||||
while (running) {
|
||||
acceptClientConnection();
|
||||
}
|
||||
System.out.println("Shutting down the server.");
|
||||
executorService.shutdown();
|
||||
playerManager.deregisterAll();
|
||||
worldUpdater.shutdown();
|
||||
datagramSocket.close(); // Shuts down the UdpReceiver.
|
||||
|
|
|
@ -2,6 +2,11 @@ package nl.andrewl.aos2_server.config;
|
|||
|
||||
public class ServerConfig {
|
||||
public int port = 25565;
|
||||
public String name = "My Server";
|
||||
public String description = "My server";
|
||||
public String[] registries = new String[0];
|
||||
|
||||
public int maxPlayers = 32;
|
||||
public int connectionBacklog = 5;
|
||||
public float ticksPerSecond = 20.0f;
|
||||
public String world = "worlds.redfort";
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# Ace of Shades 2 Server Configuration
|
||||
port: 25565
|
||||
name: My Server
|
||||
description: This is my Ace of Shades server.
|
||||
registries:
|
||||
- https://reg.aos2.net
|
||||
maxPlayers: 32
|
||||
connectionBacklog: 5
|
||||
ticksPerSecond: 20.0
|
||||
world: worlds.redfort
|
||||
|
|
Loading…
Reference in New Issue