feat: code
This commit is contained in:
@@ -11,6 +11,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation("net.kyori:adventure-api:4.25.0")
|
implementation("net.kyori:adventure-api:4.25.0")
|
||||||
implementation("net.kyori:adventure-text-minimessage:4.25.0")
|
implementation("net.kyori:adventure-text-minimessage:4.25.0")
|
||||||
|
implementation("org.slf4j:slf4j-api:2.0.17")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
|||||||
153
common/src/main/java/online/mineroo/common/BindRequest.java
Normal file
153
common/src/main/java/online/mineroo/common/BindRequest.java
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
package online.mineroo.common;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import online.mineroo.common.NetworkServiceInterface;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BindRequest handles server binding and verification with the Mineroo API.
|
||||||
|
* <p>
|
||||||
|
* This class operates asynchronously and relies on the injected
|
||||||
|
* {@link NetworkService}
|
||||||
|
* to handle the actual HTTP transport and authentication.
|
||||||
|
*/
|
||||||
|
public class BindRequest {
|
||||||
|
|
||||||
|
private final Logger logger;
|
||||||
|
private final NetworkServiceInterface networkService;
|
||||||
|
|
||||||
|
// State cache
|
||||||
|
private String motdToken = "";
|
||||||
|
private String sessionToken = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a BindRequest instance.
|
||||||
|
*
|
||||||
|
* @param logger Logger for logging errors and information
|
||||||
|
* @param networkService The network service instance (Local or Proxy) that
|
||||||
|
* handles transport and auth
|
||||||
|
*/
|
||||||
|
public BindRequest(Logger logger, NetworkServiceInterface networkService) {
|
||||||
|
this.logger = logger;
|
||||||
|
this.networkService = networkService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the bind status asynchronously.
|
||||||
|
*
|
||||||
|
* @return A future that completes with true if status is 'bound', false
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Boolean> checkBindStatus() {
|
||||||
|
// NetworkService is already configured with BaseURL, only need the path here
|
||||||
|
String path = "/server/server-bind-status";
|
||||||
|
|
||||||
|
return networkService.getData(path, null)
|
||||||
|
.thenApply(responseBody -> {
|
||||||
|
try {
|
||||||
|
JsonObject responseData = JsonParser.parseString(responseBody).getAsJsonObject();
|
||||||
|
boolean bound = responseData.has("bound") && responseData.get("bound").getAsBoolean();
|
||||||
|
|
||||||
|
if (!bound) {
|
||||||
|
logger.warn("Mineroo Bind: Server not bound. 'bound' field is false.");
|
||||||
|
}
|
||||||
|
return bound;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Mineroo Bind: Failed to parse bind status response", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.exceptionally(e -> {
|
||||||
|
logger.error("Mineroo Bind: Network error while checking status", e);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates a MOTD verification request asynchronously.
|
||||||
|
*
|
||||||
|
* @param hostname The server hostname
|
||||||
|
* @param port The server port
|
||||||
|
* @return A future that completes with true if tokens are received
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Boolean> initialMotdVerifyRequest(String hostname, Integer port) {
|
||||||
|
String path = "/server/motd-verify";
|
||||||
|
|
||||||
|
JsonObject json = new JsonObject();
|
||||||
|
json.addProperty("server_address", hostname);
|
||||||
|
json.addProperty("server_port", port);
|
||||||
|
|
||||||
|
return networkService.postData(path, json)
|
||||||
|
.thenApply(responseBody -> {
|
||||||
|
try {
|
||||||
|
JsonObject responseData = JsonParser.parseString(responseBody).getAsJsonObject();
|
||||||
|
|
||||||
|
if (responseData.has("motd_token")) {
|
||||||
|
this.motdToken = responseData.get("motd_token").getAsString();
|
||||||
|
} else {
|
||||||
|
logger.error("Mineroo Bind: MOTD Token not received.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseData.has("session_token")) {
|
||||||
|
this.sessionToken = responseData.get("session_token").getAsString();
|
||||||
|
} else {
|
||||||
|
logger.error("Mineroo Bind: Session Token not received.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Mineroo Bind: Failed to parse MOTD verify response: " + responseBody, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.exceptionally(e -> {
|
||||||
|
logger.error("Mineroo Bind: Network error during MOTD verify", e);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalizes the server binding asynchronously.
|
||||||
|
*
|
||||||
|
* @param name The server name (nullable)
|
||||||
|
* @param description The server description (nullable)
|
||||||
|
* @return A future that completes with true if the binding is successful
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Boolean> finalizeServerBinding(@Nullable String name, @Nullable String description) {
|
||||||
|
String path = "/server/server-bind";
|
||||||
|
|
||||||
|
JsonObject json = new JsonObject();
|
||||||
|
json.addProperty("session_token", this.sessionToken);
|
||||||
|
json.addProperty("name", name);
|
||||||
|
json.addProperty("description", description);
|
||||||
|
|
||||||
|
return networkService.postData(path, json)
|
||||||
|
.thenApply(responseBody -> {
|
||||||
|
// Assume as long as the request returns successfully and no exception is
|
||||||
|
// thrown, it is considered successful (HTTP 200)
|
||||||
|
// If the API returns a specific {"success": false}, you need to parse the JSON
|
||||||
|
// and check here
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.exceptionally(e -> {
|
||||||
|
logger.error("Mineroo Bind: Failed to finalize binding", e);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MOTD token received from the API.
|
||||||
|
*
|
||||||
|
* @return the motdToken string
|
||||||
|
*/
|
||||||
|
public String getMotdToken() {
|
||||||
|
return motdToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package online.mineroo.common;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class HttpNetworkService implements NetworkServiceInterface {
|
||||||
|
|
||||||
|
private final HttpClient client;
|
||||||
|
private final String baseUrl;
|
||||||
|
private final String authHeaderValue; // Precomputed Authorization header value
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseUrl Base URL of the API (e.g., "https://oapi.mineroo.online")
|
||||||
|
* @param username Username for Basic Auth (usually "mbind" in your case)
|
||||||
|
* @param password Password for Basic Auth (the token)
|
||||||
|
*/
|
||||||
|
public HttpNetworkService(String baseUrl, String username, String password) {
|
||||||
|
this.baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
|
||||||
|
|
||||||
|
// It is recommended to configure connectTimeout
|
||||||
|
this.client = HttpClient.newBuilder()
|
||||||
|
.connectTimeout(Duration.ofSeconds(10))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Pre-generate Basic Auth string
|
||||||
|
String auth = username + ":" + password;
|
||||||
|
this.authHeaderValue = "Basic " + Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<String> getData(String endpoint, Map<String, String> params) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
try {
|
||||||
|
// 1. Build URL and query parameters
|
||||||
|
StringBuilder urlBuilder = new StringBuilder(baseUrl + endpoint);
|
||||||
|
if (params != null && !params.isEmpty()) {
|
||||||
|
urlBuilder.append("?");
|
||||||
|
params.forEach((k, v) -> urlBuilder.append(k).append("=").append(v).append("&"));
|
||||||
|
// Simple trailing '&' removal (usually harmless, but cleaner)
|
||||||
|
urlBuilder.setLength(urlBuilder.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Build the request
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(urlBuilder.toString()))
|
||||||
|
.header("Authorization", authHeaderValue) // Inject Auth
|
||||||
|
.header("User-Agent", "Mineroo-Plugin/1.0") // Recommended to add User-Agent
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 3. Send the request
|
||||||
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
|
||||||
|
// You can do a simple status code check here, or leave it to the upper layer
|
||||||
|
// To keep the interface pure, we just return the body
|
||||||
|
return response.body();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Wrap checked exceptions as runtime exceptions, Future will catch them
|
||||||
|
throw new RuntimeException("HTTP GET failed: " + endpoint, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<String> postData(String endpoint, JsonObject body) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
try {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(baseUrl + endpoint))
|
||||||
|
.header("Authorization", authHeaderValue) // Inject Auth
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("User-Agent", "Mineroo-Plugin/1.0")
|
||||||
|
.POST(HttpRequest.BodyPublishers.ofString(body.toString(), StandardCharsets.UTF_8))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
return response.body();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("HTTP POST failed: " + endpoint, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package online.mineroo.common;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
public interface NetworkServiceInterface {
|
||||||
|
CompletableFuture<String> getData(String endpoint, Map<String, String> params);
|
||||||
|
|
||||||
|
CompletableFuture<String> postData(String endpoint, JsonObject body);
|
||||||
|
}
|
||||||
BIN
kls_database.db
BIN
kls_database.db
Binary file not shown.
@@ -1,6 +1,7 @@
|
|||||||
package online.mineroo.velocity.commands;
|
package online.mineroo.velocity.commands;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -12,9 +13,11 @@ import com.velocitypowered.api.command.SimpleCommand;
|
|||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import online.mineroo.common.MessageManager;
|
import online.mineroo.common.MessageManager;
|
||||||
|
import online.mineroo.common.NetworkServiceInterface;
|
||||||
import online.mineroo.velocity.Config;
|
import online.mineroo.velocity.Config;
|
||||||
import online.mineroo.velocity.MinerooCore;
|
import online.mineroo.velocity.MinerooCore;
|
||||||
import online.mineroo.velocity.utils.BindRequest;
|
import online.mineroo.common.BindRequest;
|
||||||
|
import online.mineroo.common.HttpNetworkService;
|
||||||
|
|
||||||
public class MainCommand implements SimpleCommand {
|
public class MainCommand implements SimpleCommand {
|
||||||
|
|
||||||
@@ -94,43 +97,64 @@ public class MainCommand implements SimpleCommand {
|
|||||||
|
|
||||||
Logger logger = plugin.getLogger();
|
Logger logger = plugin.getLogger();
|
||||||
|
|
||||||
|
// Run in a separate worker thread to allow blocking (Thread.sleep)
|
||||||
plugin.getServer().getScheduler().buildTask(plugin, () -> {
|
plugin.getServer().getScheduler().buildTask(plugin, () -> {
|
||||||
|
|
||||||
BindRequest request = new BindRequest(logger, bind_token);
|
// 1. Initialize the Network Service locally (Velocity connects directly)
|
||||||
|
NetworkServiceInterface networkService = new HttpNetworkService(
|
||||||
|
"https://oapi.mineroo.online",
|
||||||
|
"mbind",
|
||||||
|
bind_token);
|
||||||
|
|
||||||
|
BindRequest request = new BindRequest(logger, networkService);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Status check before initial bind
|
// 2. Check Status
|
||||||
if (request.checkBindStatus()) {
|
// We use .join() to block the thread until the Future completes.
|
||||||
|
if (request.checkBindStatus().join()) {
|
||||||
source.sendMessage(msg.get("command.bind.server.already-bound"));
|
source.sendMessage(msg.get("command.bind.server.already-bound"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean inital_bind = request.initalMotdVerifyRequest(bind_address, bind_port);
|
// 3. Initial Verification
|
||||||
|
boolean inital_bind = request.initialMotdVerifyRequest(bind_address, bind_port).join();
|
||||||
|
|
||||||
if (inital_bind) {
|
if (inital_bind) {
|
||||||
String motdToken = request.getMotdToken();
|
String motdToken = request.getMotdToken();
|
||||||
plugin.getBindListener().setVerificationToken(motdToken);
|
plugin.getBindListener().setVerificationToken(motdToken);
|
||||||
|
|
||||||
source.sendMessage(msg.get("command.bind.server.wait"));
|
source.sendMessage(msg.get("command.bind.server.wait"));
|
||||||
|
|
||||||
Thread.sleep(2 * 60 * 1000 + 5000);
|
// 4. Wait for external refresh (Blocking this worker thread is intended)
|
||||||
|
try {
|
||||||
|
Thread.sleep(2 * 60 * 1000 + 5000); // 2m 5s
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("Bind thread interrupted", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Final Bind
|
// 5. Final Bind & Retry Loop
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
int maxRetries = 3;
|
int maxRetries = 3;
|
||||||
|
|
||||||
for (int i = 1; i <= maxRetries; i++) {
|
for (int i = 1; i <= maxRetries; i++) {
|
||||||
if (request.finalizeServerBinding(bind_name, bind_description)) {
|
// Check final status synchronously using join()
|
||||||
|
if (request.finalizeServerBinding(bind_name, bind_description).join()) {
|
||||||
success = true;
|
success = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < maxRetries) {
|
if (i < maxRetries) {
|
||||||
|
|
||||||
source.sendMessage(msg.get("command.bind.server.retry",
|
source.sendMessage(msg.get("command.bind.server.retry",
|
||||||
"current", String.valueOf(i),
|
"current", String.valueOf(i),
|
||||||
"max", String.valueOf(maxRetries)));
|
"max", String.valueOf(maxRetries)));
|
||||||
Thread.sleep(10000);
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(10000); // Wait 10s before retry
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,14 +169,16 @@ public class MainCommand implements SimpleCommand {
|
|||||||
Component.text("Initial handshake failed. Check your token or network.", NamedTextColor.RED));
|
Component.text("Initial handshake failed. Check your token or network.", NamedTextColor.RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (CompletionException e) {
|
||||||
|
// Unpack the wrapper exception from join() to see the real network error
|
||||||
|
logger.error("Mineroo Bind Network Error: " + e.getCause().getMessage());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Mineroo Bind: " + e.toString());
|
logger.error("Mineroo Bind Error: " + e.toString());
|
||||||
} finally {
|
} finally {
|
||||||
plugin.getBindListener().clearVerificationToken();
|
plugin.getBindListener().clearVerificationToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
}).schedule();
|
}).schedule();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendHelp(CommandSource source) {
|
public void sendHelp(CommandSource source) {
|
||||||
|
|||||||
@@ -1,205 +0,0 @@
|
|||||||
package online.mineroo.velocity.utils;
|
|
||||||
|
|
||||||
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.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BindRequest handles server binding and verification with the Mineroo API.
|
|
||||||
* <p>
|
|
||||||
* This class provides methods to:
|
|
||||||
* <ul>
|
|
||||||
* <li>Check if the server is bound using the bind token</li>
|
|
||||||
* <li>Initiate a MOTD verification request</li>
|
|
||||||
* <li>Finalize the server binding with additional server details</li>
|
|
||||||
* </ul>
|
|
||||||
* It manages authentication, HTTP requests, and response parsing for the binding process.
|
|
||||||
*/
|
|
||||||
public class BindRequest {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The base endpoint for Mineroo API requests.
|
|
||||||
*/
|
|
||||||
private static final String endpoint = "https://oapi.mineroo.online";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logger instance for logging errors and information.
|
|
||||||
*/
|
|
||||||
private final Logger logger;
|
|
||||||
/**
|
|
||||||
* HTTP client used for sending requests to the Mineroo API.
|
|
||||||
*/
|
|
||||||
private final HttpClient httpClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The bind token used for authenticating API requests.
|
|
||||||
*/
|
|
||||||
private final String bindToken;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The MOTD token received from the API after verification.
|
|
||||||
*/
|
|
||||||
private String motdToken = "";
|
|
||||||
/**
|
|
||||||
* The session token received from the API after verification.
|
|
||||||
*/
|
|
||||||
private String sessionToken = "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a BindRequest instance.
|
|
||||||
*
|
|
||||||
* @param logger Logger for logging errors and information
|
|
||||||
* @param bindToken The bind token for API authentication
|
|
||||||
*/
|
|
||||||
public BindRequest(Logger logger, String bindToken) {
|
|
||||||
|
|
||||||
this.logger = logger;
|
|
||||||
this.bindToken = bindToken;
|
|
||||||
|
|
||||||
this.httpClient = HttpClient.newHttpClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the bind status from the oapi.mineroo.online API.
|
|
||||||
*
|
|
||||||
* @return true if status is 'bound', false otherwise
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Checks the bind status from the oapi.mineroo.online API.
|
|
||||||
*
|
|
||||||
* @return true if status is 'bound', false otherwise
|
|
||||||
*/
|
|
||||||
public boolean checkBindStatus() {
|
|
||||||
String uri = endpoint + "/server/server-bind-status";
|
|
||||||
String basicAuth = "mbind:" + bindToken;
|
|
||||||
String encodedAuth = Base64.getEncoder().encodeToString(basicAuth.getBytes(StandardCharsets.UTF_8));
|
|
||||||
try {
|
|
||||||
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
|
|
||||||
.header("Authorization", "Basic " + encodedAuth)
|
|
||||||
.GET().build();
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
if (response.statusCode() == 200) {
|
|
||||||
JsonObject responseData = JsonParser.parseString(response.body()).getAsJsonObject();
|
|
||||||
boolean bound = responseData.has("bound") && responseData.get("bound").getAsBoolean();
|
|
||||||
if (bound) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
logger.error("Mineroo Bind: Server not bound. 'bound' field is false.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.error("Mineroo Bind: Failed to check bind status. Response: " + response.body());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Mineroo Bind: Exception while checking bind status", e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiates a MOTD verification request to the Mineroo API.
|
|
||||||
*
|
|
||||||
* @param hostname The server hostname
|
|
||||||
* @param port The server port
|
|
||||||
* @return true if both motd_token and session_token are received, false otherwise
|
|
||||||
* @throws IOException, InterruptedException, JsonParseException on request or parsing failure
|
|
||||||
*/
|
|
||||||
public boolean initalMotdVerifyRequest(String hostname, Integer port)
|
|
||||||
throws IOException, InterruptedException, JsonParseException {
|
|
||||||
|
|
||||||
// generate uri
|
|
||||||
String uri = endpoint + "/server/motd-verify";
|
|
||||||
|
|
||||||
// build jsonBody
|
|
||||||
JsonObject json = new JsonObject();
|
|
||||||
json.addProperty("server_address", hostname);
|
|
||||||
json.addProperty("server_port", port);
|
|
||||||
|
|
||||||
String basicAuth = "mbind:" + bindToken;
|
|
||||||
String encodedAuth = Base64.getEncoder().encodeToString(basicAuth.getBytes(StandardCharsets.UTF_8));
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.header("Authorization", "Basic " + encodedAuth)
|
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(json.toString())).build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
if (response.statusCode() == 200) {
|
|
||||||
String body = response.body();
|
|
||||||
JsonObject responseData = JsonParser.parseString(body).getAsJsonObject();
|
|
||||||
|
|
||||||
if (responseData.has("motd_token")) {
|
|
||||||
motdToken = responseData.get("motd_token").getAsString();
|
|
||||||
} else {
|
|
||||||
logger.error("Mineroo Bind: MOTD Token not received.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responseData.has("session_token")) {
|
|
||||||
sessionToken = responseData.get("session_token").getAsString();
|
|
||||||
} else {
|
|
||||||
logger.error("Mineroo Bind: Session Token not received.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
logger.error("Mineroo Bind: " + response.body().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finalizes the server binding by sending server details to the Mineroo API.
|
|
||||||
*
|
|
||||||
* @param name The server name (nullable)
|
|
||||||
* @param description The server description (nullable)
|
|
||||||
* @return true if the binding is successful (HTTP 200), false otherwise
|
|
||||||
* @throws IOException, InterruptedException, JsonParseException on request or parsing failure
|
|
||||||
*/
|
|
||||||
public boolean finalizeServerBinding(@Nullable String name, @Nullable String description)
|
|
||||||
throws IOException, InterruptedException, JsonParseException {
|
|
||||||
|
|
||||||
String uri = endpoint + "/server/server-bind";
|
|
||||||
|
|
||||||
JsonObject json = new JsonObject();
|
|
||||||
json.addProperty("session_token", sessionToken);
|
|
||||||
json.addProperty("name", name);
|
|
||||||
json.addProperty("description", description);
|
|
||||||
|
|
||||||
String basicAuth = "mbind:" + bindToken;
|
|
||||||
String encodedAuth = Base64.getEncoder().encodeToString(basicAuth.getBytes(StandardCharsets.UTF_8));
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.header("Authorization", "Basic " + encodedAuth)
|
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(json.toString())).build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
return response.statusCode() == 200;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MOTD token received from the API.
|
|
||||||
*
|
|
||||||
* @return the motdToken string
|
|
||||||
*/
|
|
||||||
public String getMotdToken() {
|
|
||||||
return motdToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user