Skip to content

Commit

Permalink
v0.9.2.3
Browse files Browse the repository at this point in the history
- isServerOnline() now uses built in RegisteredServer.ping() instead of the panel API to check if the server is online
- added config how long till a ping, to check if a server is online, times out
- Plugin now checks every 16 Seconds (instead of 5) if a server is Online to avoid to much useless pings
- version bump

Took 2 hours 45 minutes
  • Loading branch information
TubYoub committed Oct 5, 2024
1 parent 6aeac47 commit 316f954
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 108 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>de.tubyoub</groupId>
<artifactId>VelocityPteroPower</artifactId>
<version>0.9.2.2</version>
<version>0.9.2.3</version>
<packaging>jar</packaging>

<name>VelocityPteroPower</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class ConfigurationManager {
private boolean printRateLimit;
private int startupJoinDelay;
private int apiThreads;
private int pingTimeout;
private final VelocityPteroPower plugin;
private final Logger logger;
private Map<String, PteroServerInfo> serverInfoMap;
Expand Down Expand Up @@ -95,6 +96,7 @@ public void loadConfig(){

checkUpdate = (boolean) config.get("checkUpdate");
printRateLimit = (boolean) config.get("printRateLimit");
pingTimeout = (int) config.get("pingTimeout");
apiThreads = (int) config.get("apiThreads", 10);
Section startupJoinSection = config.getSection("startupJoin");
Map<String, Object> startupJoin = new HashMap<>();
Expand Down Expand Up @@ -243,4 +245,8 @@ public int getApiThreads() {
public boolean isPrintRateLimit() {
return printRateLimit;
}

public int getPingTimeout() {
return pingTimeout;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
* Main class for the VelocityPteroPower plugin.
* This class handles the initialization of the plugin and the registration of commands and events.
*/
@Plugin(id = "velocity-ptero-power", name = "VelocityPteroPower", version = "0.9.2.2", authors = {"TubYoub"}, description = "A plugin for Velocity that allows you to manage your Pterodactyl/Pelican servers from the Velocity console.", url = "https://github.com/TubYoub/VelocityPteroPower")
@Plugin(id = "velocity-ptero-power", name = "VelocityPteroPower", version = "0.9.2.3", authors = {"TubYoub"}, description = "A plugin for Velocity that allows you to manage your Pterodactyl/Pelican servers from the Velocity console.", url = "https://github.com/TubYoub/VelocityPteroPower")
public class VelocityPteroPower {
private final String version = "0.9.2.2";
private final String version = "0.9.2.3";
private final String modrinthID = "";
private final int pluginId = 21465;
private final ProxyServer proxyServer;
Expand All @@ -80,7 +80,6 @@ public class VelocityPteroPower {
private final AtomicInteger remainingRequests = new AtomicInteger(60); // Default value, will be updated
private final ReentrantLock rateLimitLock = new ReentrantLock();


/**
* Constructor for the VelocityPteroPower class.
*
Expand Down Expand Up @@ -181,7 +180,7 @@ public void onServerPreConnect(ServerPreConnectEvent event) {
.append(Component.text("] Server not found in configuration: " + serverName, NamedTextColor.WHITE)));
return;
}
if (apiClient.isServerOnline(serverInfo.getServerId()) && this.canMakeRequest()) {
if (apiClient.isServerOnline(serverName) && this.canMakeRequest()) {
if (startingServers.contains(serverName)){
startingServers.remove(serverName);
}
Expand All @@ -205,17 +204,17 @@ public void onServerPreConnect(ServerPreConnectEvent event) {
event.setResult(ServerPreConnectEvent.ServerResult.denied());

proxyServer.getScheduler().buildTask(this, () -> {
if (apiClient.isServerOnline(serverInfo.getServerId()) && this.canMakeRequest()) {
if (apiClient.isServerOnline(serverName) && this.canMakeRequest()) {
connectPlayer(player, serverName);
} else {
proxyServer.getScheduler().buildTask(this, () -> checkServerAndConnectPlayer(player, serverName)).schedule();
}
}).delay(5, TimeUnit.SECONDS).schedule();
}).delay(16, TimeUnit.SECONDS).schedule();
}

private void checkServerAndConnectPlayer(Player player, String serverName) {
PteroServerInfo serverInfo = serverInfoMap.get(serverName);
if (apiClient.isServerOnline(serverInfo.getServerId()) && this.canMakeRequest()) {
if (apiClient.isServerOnline(serverName) && this.canMakeRequest()) {
connectPlayer(player, serverName);
} else {
proxyServer.getScheduler().buildTask(this, () -> checkServerAndConnectPlayer(player, serverName)).delay(configurationManager.getStartupJoinDelay(), TimeUnit.SECONDS).schedule();
Expand Down Expand Up @@ -246,7 +245,7 @@ private void connectPlayer(Player player, String serverName) {
return;
}

if (apiClient.isServerOnline(serverInfoMap.get(serverName).getServerId()) && this.canMakeRequest()) {
if (apiClient.isServerOnline(serverName) && this.canMakeRequest()) {
player.createConnectionRequest(server).fireAndForget();
startingServers.remove(serverName);
}
Expand Down Expand Up @@ -280,8 +279,6 @@ public void updateRateLimitInfo(HttpResponse<String> response) {
}
}



/**
* This method reloads the configuration for the VelocityPteroPower plugin.
* It calls the loadConfig method of the ConfigurationManager instance to reload the configuration.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.tubyoub.velocitypteropower.api;

import java.util.concurrent.CompletableFuture;

public interface PanelAPIClient {
void powerServer(String serverId, String signal);
boolean isServerOnline(String serverId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package de.tubyoub.velocitypteropower.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerPing;
import de.tubyoub.velocitypteropower.ConfigurationManager;
import de.tubyoub.velocitypteropower.VelocityPteroPower;
import org.slf4j.Logger;
Expand All @@ -15,6 +14,7 @@
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -46,11 +46,11 @@ public void powerServer(String serverId, String signal) {
try {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(configurationManager.getPterodactylUrl() + "api/client/servers/" + serverId + "/power"))
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + configurationManager.getPterodactylApiKey())
.POST(HttpRequest.BodyPublishers.ofString("{\"signal\": \"" + signal + "\"}"))
.build();
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + configurationManager.getPterodactylApiKey())
.POST(HttpRequest.BodyPublishers.ofString("{\"signal\": \"" + signal + "\"}"))
.build();

plugin.updateRateLimitInfo(httpClient.send(request, HttpResponse.BodyHandlers.ofString()));
} catch (Exception e) {
Expand All @@ -59,56 +59,34 @@ public void powerServer(String serverId, String signal) {
}

@Override
public boolean isServerOnline(String serverId) {
int retryCount = 3;
while (retryCount > 0) {
public boolean isServerOnline(String serverName) {
Optional<RegisteredServer> serverOptional = proxyServer.getServer(serverName);
if (serverOptional.isPresent()) {
RegisteredServer server = serverOptional.get();
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(configurationManager.getPterodactylUrl() + "api/client/servers/" + serverId + "/resources"))
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + configurationManager.getPterodactylApiKey())
.GET()
.build();

HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
plugin.updateRateLimitInfo(response);
String responseBody = response.body();
if (response.statusCode() == 200) {
return responseBody.contains("{\"object\":\"stats\",\"attributes\":{\"current_state\":\"running\"");
} else {
return false;
}
} catch (IOException | InterruptedException e) {
if (e.getMessage().contains("GOAWAY")) {
retryCount--;
if (retryCount == 0) {
logger.error("Failed to check server status after retries: " + e.getMessage());
return false;
}
logger.warn("GOAWAY received, retrying... (" + retryCount + " retries left)");
try {
Thread.sleep(1000); // Wait before retrying
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return false;
}
} else {
logger.error("Error checking server status: " + e.getMessage());
return false;
CompletableFuture<ServerPing> pingFuture = server.ping();
ServerPing pingResult = pingFuture.get(configurationManager.getPingTimeout(), TimeUnit.MILLISECONDS);
return pingResult != null;
} catch (Exception e) {
if (!(e.getCause() instanceof NullPointerException)) {
logger.debug("Error pinging server {}: {}", serverName, e.getMessage());
}
return false;
}
} else {
logger.error("Server not found: {} Check if the server name match in the configs", serverName);
return false;
}
return false;
}

@Override
public boolean isServerEmpty(String serverName) {
Optional<RegisteredServer> server = proxyServer.getServer(serverName);
return server.map(value -> value.getPlayersConnected().isEmpty()).orElse(true);
}
@Override
public boolean isServerEmpty (String serverName){
Optional<RegisteredServer> server = proxyServer.getServer(serverName);
return server.map(value -> value.getPlayersConnected().isEmpty()).orElse(true);
}

public void shutdown() {
executorService.shutdownNow();
public void shutdown () {
executorService.shutdownNow();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,19 @@

package de.tubyoub.velocitypteropower.api;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerPing;
import de.tubyoub.velocitypteropower.ConfigurationManager;
import de.tubyoub.velocitypteropower.VelocityPteroPower;
import org.slf4j.Logger;

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.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -106,51 +102,28 @@ public void powerServer(String serverId, String signal) {
/**
* This method checks if a server is online.
*
* @param serverId the ID of the server
* @param serverName the ID of the server
* @return true if the server is online, false otherwise
*/
@Override
public boolean isServerOnline(String serverId) {
int retryCount = 3;
while (retryCount > 0) {
public boolean isServerOnline(String serverName) {
Optional<RegisteredServer> serverOptional = proxyServer.getServer(serverName);
if (serverOptional.isPresent()) {
RegisteredServer server = serverOptional.get();
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(configurationManager.getPterodactylUrl() + "api/client/servers/" + serverId + "/resources"))
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + configurationManager.getPterodactylApiKey())
.GET()
.build();

HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
plugin.updateRateLimitInfo(response);
String responseBody = response.body();
if (response.statusCode() == 200) {
return responseBody.contains("{\"object\":\"stats\",\"attributes\":{\"current_state\":\"running\"");
} else {
return false;
}
} catch (IOException | InterruptedException e) {
if (e.getMessage().contains("GOAWAY")) {
retryCount--;
if (retryCount == 0) {
logger.error("Failed to check server status after retries: " + e.getMessage());
return false;
}
logger.warn("GOAWAY received, retrying... (" + retryCount + " retries left)");
try {
Thread.sleep(1000); // Wait before retrying
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return false;
}
} else {
logger.error("Error checking server status: " + e.getMessage());
return false;
CompletableFuture<ServerPing> pingFuture = server.ping();
ServerPing pingResult = pingFuture.get(configurationManager.getPingTimeout(), TimeUnit.MILLISECONDS);
return pingResult != null;
} catch (Exception e) {
if (!(e.getCause() instanceof NullPointerException)) {
logger.debug("Error pinging server {}: {}", serverName, e.getMessage());
}
return false;
}
} else {
logger.error("Server not found: {} Check if the server name match in the configs", serverName);
return false;
}
return false;
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
################################

# Version of the configuration file
fileversion: 4
fileversion: 5

# Check for updates
# If true, the plugin will check for updates on startup.
Expand All @@ -22,6 +22,10 @@ apiThreads: 10
# default: false
printRateLimit: false

# How long the ping to the server lasts, to check if its is online, until it times out (in milliseconds)
# default: 1000
pingTimeout: 1000

# This is used to check the server status to transfer players after the server starts
startupJoin:
# Once the server is pingable, wait the specified amount of seconds before sending the player to the server
Expand Down

0 comments on commit 316f954

Please sign in to comment.