diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java index 102b51cd47..bfbf394722 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java @@ -2,6 +2,7 @@ import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.command.commands.*; +import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.locale.Locale; import com.djrapitops.plan.system.settings.locale.Msg; @@ -50,7 +51,8 @@ public void addCommands() { registerCommand, new WebUserCommand(plugin, registerCommand), new NetworkCommand(), - new ListServersCommand(plugin) + new ListServersCommand(plugin), + new ManageConDebugCommand() ); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java index d0a5c86dd8..521a09220f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java @@ -37,7 +37,8 @@ public void addCommands() { new ManageRemoveCommand(), new ManageClearCommand(plugin), new ManageSetupCommand(), - new ManageDisableCommand() + new ManageDisableCommand(), + new ManageConDebugCommand() ); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java new file mode 100644 index 0000000000..6872f4316a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java @@ -0,0 +1,127 @@ +package com.djrapitops.plan.command.commands.manage; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.api.exceptions.connection.*; +import com.djrapitops.plan.api.exceptions.database.DBException; +import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.request.CheckConnectionRequest; +import com.djrapitops.plan.system.info.server.Server; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.processing.Processor; +import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plan.system.settings.locale.Locale; +import com.djrapitops.plan.system.settings.locale.Msg; +import com.djrapitops.plan.system.webserver.WebServerSystem; +import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.command.CommandType; +import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.SubCommand; +import com.djrapitops.plugin.settings.ColorScheme; + +import java.util.List; +import java.util.UUID; + +/** + * This manage SubCommand is used to request settings from Bungee so that connection can be established. + * + * @author Rsl1122 + * @since 2.3.0 + */ +public class ManageConDebugCommand extends SubCommand { + + private final ColorScheme cs; + + public ManageConDebugCommand() { + super("con", + CommandType.ALL, + Permissions.MANAGE.getPermission(), + "Debug Bukkit-Bungee Connections", + ""); + + cs = PlanPlugin.getInstance().getColorScheme(); + } + + @Override + public String[] addHelp() { + return Locale.get(Msg.CMD_HELP_MANAGE_HOTSWAP).toArray(); + } + + @Override + public boolean onCommand(ISender sender, String commandLabel, String[] args) { + if (!WebServerSystem.isWebServerEnabled()) { + sender.sendMessage("§cWebServer is not enabled on this server."); + return true; + } + + Processor.queue(() -> { + testServers(sender); + }); + + return true; + } + + private void testServers(ISender sender) { + try { + List servers = Database.getActive().fetch().getServers(); + + String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); + UUID thisServer = ServerInfo.getServerUUID(); + for (Server server : servers) { + if (thisServer.equals(server.getUuid())) { + continue; + } + testServer(sender, accessAddress, server); + } + + } catch (DBException e) { + Log.toLog(this.getClass().getName(), e); + } + } + + private void testServer(ISender sender, String accessAddress, Server server) { + String address = server.getWebAddress().toLowerCase(); + boolean usingHttps = address.startsWith("https"); + boolean local = address.contains("localhost") + || address.startsWith("https://:") + || address.startsWith("http://:") + || address.contains("127.0.0.1"); + + try { + + InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(accessAddress), server); + sender.sendMessage(getMsgFor(address, usingHttps, local, true, true)); + + } catch (ForbiddenException | BadRequestException | InternalErrorException e) { + sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); + sender.sendMessage("§eOdd Exception: " + e.getClass().getSimpleName()); + } catch (UnauthorizedServerException e) { + sender.sendMessage(getMsgFor(address, usingHttps, local, true, false)); + sender.sendMessage("§eFail reason: Unauthorized. Server might be using different database."); + } catch (ConnectionFailException e) { + sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); + sender.sendMessage("§eFail reason: " + e.getCause().getClass().getSimpleName() + " " + e.getCause().getMessage()); + if (!local) { + sender.sendMessage("§eNon-local address, check that port is open"); + } + } catch (GatewayException e) { + sender.sendMessage(getMsgFor(address, usingHttps, local, true, false)); + } catch (NotFoundException e) { + sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); + sender.sendMessage("§eFail reason: Older Plan version on receiving server"); + } catch (WebException e) { + sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); + sender.sendMessage("§eOdd Exception: " + e.getClass().getSimpleName()); + } + } + + private String getMsgFor(String address, boolean usingHttps, boolean local, boolean successTo, boolean successFrom) { + String tCol = cs.getTertiaryColor(); + String sCol = cs.getSecondaryColor(); + return tCol + address + sCol + ": " + + (usingHttps ? "HTTPS" : "HTTP") + " : " + + (local ? "Local" : "External") + " : " + + "To:" + (successTo ? "§aOK" : "§cFail") + sCol + " : " + + "From:" + (successFrom ? "§aOK" : "§cFail"); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java index 040da3c061..0e556df65a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java @@ -148,7 +148,7 @@ public void sendRequest() throws WebException { Log.toLog(this.getClass(), e); } ConnectionLog.logConnectionTo(toServer, infoRequest, -1); - throw new ConnectionFailException("Connection failed to address: " + address + "
Make sure the server is online.", e); + throw new ConnectionFailException("Connection failed to address: " + address + " - Make sure the server is online.", e); } finally { if (connection != null) { connection.disconnect(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java index 0cdf675899..546c8a8847 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java @@ -124,6 +124,7 @@ private Map loadDataRequests() { putRequest(requests, SaveDBSettingsRequest.createHandler()); putRequest(requests, SendDBSettingsRequest.createHandler()); + putRequest(requests, CheckConnectionRequest.createHandler()); return requests; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java new file mode 100644 index 0000000000..d7806842f5 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java @@ -0,0 +1,82 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.info.request; + +import com.djrapitops.plan.api.exceptions.connection.BadRequestException; +import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; +import com.djrapitops.plan.api.exceptions.connection.GatewayException; +import com.djrapitops.plan.api.exceptions.connection.WebException; +import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.server.Server; +import com.djrapitops.plan.system.webserver.response.DefaultResponses; +import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plugin.api.Check; +import com.djrapitops.plugin.utilities.Verify; + +import java.util.Map; +import java.util.UUID; + +/** + * InfoRequest used for Checking Bukkit-Bungee connections. + * + * @author Rsl1122 + */ +public class CheckConnectionRequest extends InfoRequestWithVariables { + + public CheckConnectionRequest(String webServerAddress) { + Verify.nullCheck(webServerAddress, () -> new IllegalArgumentException("webServerAddress can not be null.")); + + variables.put("address", webServerAddress); + variables.put("continue", "yes"); + } + + public CheckConnectionRequest() { + } + + public static CheckConnectionRequest createHandler() { + return new CheckConnectionRequest(); + } + + @Override + public void placeDataToDatabase() { + /* Not necessary */ + } + + @Override + public void runLocally() { + /* Won't be run */ + } + + @Override + public Response handleRequest(Map variables) throws WebException { + // Available variables: sender, address + + if (Check.isBungeeAvailable()) { + attemptConnection(variables); + } + + return DefaultResponses.SUCCESS.get(); + } + + private void attemptConnection(Map variables) throws WebException { + boolean shouldNotContinue = variables.get("continue") == null; + if (shouldNotContinue) { + return; + } + + String address = variables.get("address"); + Verify.nullCheck(address, () -> new BadRequestException("WebServer Address ('address') not specified in the request.")); + + UUID serverUUID = UUID.fromString(variables.get("sender")); + + Server bukkit = new Server(-1, serverUUID, "", address, -1); + + try { + InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(), bukkit); + } catch (ConnectionFailException e) { + throw new GatewayException(e.getMessage()); + } + } +} \ No newline at end of file