From 4dc100a25f93a8d4681aba8643ce4478f719ac0a Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 17 Jan 2021 17:04:11 +0000 Subject: [PATCH] Add categories for servers (Official, Geyser and Custom) --- .../org/geysermc/connect/MasterServer.java | 13 +- .../org/geysermc/connect/PacketHandler.java | 10 +- .../ProxyConnectorServerEventHandler.java | 2 +- .../storage/AbstractStorageManager.java | 4 +- .../connect/storage/JsonStorageManager.java | 4 +- .../connect/storage/MySQLStorageManager.java | 6 +- .../connect/storage/SQLiteStorageManager.java | 7 +- .../java/org/geysermc/connect/ui/FormID.java | 3 +- .../org/geysermc/connect/ui/UIHandler.java | 115 +++++++++++++----- .../org/geysermc/connect/utils/Logger.java | 2 +- .../geysermc/connect/utils/PaletteManger.java | 2 - .../org/geysermc/connect/utils/Player.java | 21 +++- .../org/geysermc/connect/utils/Server.java | 5 + .../connect/utils/ServerCategory.java | 41 +++++++ .../org/geysermc/connect/utils/WebUtils.java | 6 +- src/main/resources/config.yml | 2 + 16 files changed, 181 insertions(+), 62 deletions(-) create mode 100644 src/main/java/org/geysermc/connect/utils/ServerCategory.java diff --git a/src/main/java/org/geysermc/connect/MasterServer.java b/src/main/java/org/geysermc/connect/MasterServer.java index 0e2f407..51c2eff 100644 --- a/src/main/java/org/geysermc/connect/MasterServer.java +++ b/src/main/java/org/geysermc/connect/MasterServer.java @@ -26,10 +26,11 @@ package org.geysermc.connect; import com.nukkitx.protocol.bedrock.*; -import com.nukkitx.protocol.bedrock.v408.Bedrock_v408; import lombok.Getter; import lombok.Setter; import org.geysermc.connect.storage.DisabledStorageManager; +import org.geysermc.connect.utils.Server; +import org.geysermc.connect.utils.ServerCategory; import org.geysermc.connector.network.BedrockProtocol; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connect.proxy.GeyserProxyBootstrap; @@ -40,12 +41,10 @@ import org.geysermc.connect.utils.Player; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; +import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.stream.Collectors; public class MasterServer { @@ -191,4 +190,8 @@ public class MasterServer { geyserProxy = null; } } + + public List getServers(ServerCategory serverCategory) { + return getGeyserConnectConfig().getServers().stream().filter(server -> server.getCategory() == serverCategory).collect(Collectors.toList()); + } } diff --git a/src/main/java/org/geysermc/connect/PacketHandler.java b/src/main/java/org/geysermc/connect/PacketHandler.java index 39e527b..23272e6 100644 --- a/src/main/java/org/geysermc/connect/PacketHandler.java +++ b/src/main/java/org/geysermc/connect/PacketHandler.java @@ -64,7 +64,7 @@ public class PacketHandler implements BedrockPacketHandler { private Player player; - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);; + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); public PacketHandler(BedrockServerSession session, MasterServer masterServer) { this.session = session; @@ -213,7 +213,7 @@ public class PacketHandler implements BedrockPacketHandler { if (!message.trim().isEmpty()) { player.sendWindow(FormID.WELCOME, UIHandler.getMessageWindow(message)); } else { - player.sendWindow(FormID.MAIN, UIHandler.getServerList(player.getServers())); + player.sendWindow(FormID.MAIN, UIHandler.getMainMenu()); } return false; @@ -237,10 +237,14 @@ public class PacketHandler implements BedrockPacketHandler { // Send the response to the correct response function switch (id) { case WELCOME: - player.sendWindow(FormID.MAIN, UIHandler.getServerList(player.getServers())); + player.sendWindow(FormID.MAIN, UIHandler.getMainMenu()); break; case MAIN: + UIHandler.handleMainMenuResponse(player, (SimpleFormResponse) window.getResponse()); + break; + + case LIST_SERVERS: UIHandler.handleServerListResponse(player, (SimpleFormResponse) window.getResponse()); break; diff --git a/src/main/java/org/geysermc/connect/proxy/ProxyConnectorServerEventHandler.java b/src/main/java/org/geysermc/connect/proxy/ProxyConnectorServerEventHandler.java index a70c2a1..de48828 100644 --- a/src/main/java/org/geysermc/connect/proxy/ProxyConnectorServerEventHandler.java +++ b/src/main/java/org/geysermc/connect/proxy/ProxyConnectorServerEventHandler.java @@ -73,7 +73,7 @@ public class ProxyConnectorServerEventHandler extends ConnectorServerEventHandle if (shutdownTime != -1) { MasterServer.getInstance().getGeneralThreadPool().schedule(() -> { - if (System.currentTimeMillis() - MasterServer.getInstance().getLastDisconnectTime() > shutdownTime * 1000 + if (System.currentTimeMillis() - MasterServer.getInstance().getLastDisconnectTime() > shutdownTime * 1000L && connector != null && connector.getPlayers().size() <= 0) { MasterServer.getInstance().shutdownGeyserProxy(); diff --git a/src/main/java/org/geysermc/connect/storage/AbstractStorageManager.java b/src/main/java/org/geysermc/connect/storage/AbstractStorageManager.java index 354ee7d..28ee1a5 100644 --- a/src/main/java/org/geysermc/connect/storage/AbstractStorageManager.java +++ b/src/main/java/org/geysermc/connect/storage/AbstractStorageManager.java @@ -52,9 +52,9 @@ public class AbstractStorageManager { MYSQL("mysql", MySQLStorageManager.class); @JsonValue - private String name; + private final String name; - private Class storageManager; + private final Class storageManager; StorageType(String name, Class storageManager) { this.name = name; diff --git a/src/main/java/org/geysermc/connect/storage/JsonStorageManager.java b/src/main/java/org/geysermc/connect/storage/JsonStorageManager.java index 0bdbd22..d51e560 100644 --- a/src/main/java/org/geysermc/connect/storage/JsonStorageManager.java +++ b/src/main/java/org/geysermc/connect/storage/JsonStorageManager.java @@ -52,7 +52,7 @@ public class JsonStorageManager extends AbstractStorageManager { public void saveServers(Player player) { try { mapper.writeValue(dataFolder.resolve(player.getXuid() + ".json").toFile(), player.getServers()); - } catch (IOException e) { } + } catch (IOException ignored) { } } @Override @@ -62,7 +62,7 @@ public class JsonStorageManager extends AbstractStorageManager { try { List loadedServers = mapper.readValue(dataFolder.resolve(player.getXuid() + ".json").toFile(), new TypeReference>(){}); servers.addAll(loadedServers); - } catch (IOException e) { } + } catch (IOException ignored) { } return servers; } diff --git a/src/main/java/org/geysermc/connect/storage/MySQLStorageManager.java b/src/main/java/org/geysermc/connect/storage/MySQLStorageManager.java index 68175b7..68f3bb7 100644 --- a/src/main/java/org/geysermc/connect/storage/MySQLStorageManager.java +++ b/src/main/java/org/geysermc/connect/storage/MySQLStorageManager.java @@ -62,7 +62,7 @@ public class MySQLStorageManager extends AbstractStorageManager { public void closeStorage() { try { connection.close(); - } catch (SQLException e) { } + } catch (SQLException ignored) { } } @Override @@ -71,7 +71,7 @@ public class MySQLStorageManager extends AbstractStorageManager { Statement updatePlayersServers = connection.createStatement(); updatePlayersServers.executeUpdate("REPLACE INTO players(xuid, servers) VALUES('" + player.getXuid() + "', '" + mapper.writeValueAsString(player.getServers()) + "');"); updatePlayersServers.close(); - } catch (IOException | SQLException e) { } + } catch (IOException | SQLException ignored) { } } @Override @@ -88,7 +88,7 @@ public class MySQLStorageManager extends AbstractStorageManager { } getPlayersServers.close(); - } catch (IOException | SQLException e) { } + } catch (IOException | SQLException ignored) { } return servers; } diff --git a/src/main/java/org/geysermc/connect/storage/SQLiteStorageManager.java b/src/main/java/org/geysermc/connect/storage/SQLiteStorageManager.java index e0c662e..b20aca5 100644 --- a/src/main/java/org/geysermc/connect/storage/SQLiteStorageManager.java +++ b/src/main/java/org/geysermc/connect/storage/SQLiteStorageManager.java @@ -31,7 +31,6 @@ import org.geysermc.connect.MasterServer; import org.geysermc.connect.utils.Player; import org.geysermc.connect.utils.Server; -import java.io.File; import java.io.IOException; import java.sql.*; import java.util.ArrayList; @@ -61,7 +60,7 @@ public class SQLiteStorageManager extends AbstractStorageManager { public void closeStorage() { try { connection.close(); - } catch (SQLException e) { } + } catch (SQLException ignored) { } } @Override @@ -70,7 +69,7 @@ public class SQLiteStorageManager extends AbstractStorageManager { Statement updatePlayersServers = connection.createStatement(); updatePlayersServers.executeUpdate("INSERT OR REPLACE INTO players(xuid, servers) VALUES('" + player.getXuid() + "', '" + mapper.writeValueAsString(player.getServers()) + "');"); updatePlayersServers.close(); - } catch (IOException | SQLException e) { } + } catch (IOException | SQLException ignored) { } } @Override @@ -87,7 +86,7 @@ public class SQLiteStorageManager extends AbstractStorageManager { } getPlayersServers.close(); - } catch (IOException | SQLException e) { } + } catch (IOException | SQLException ignored) { } return servers; } diff --git a/src/main/java/org/geysermc/connect/ui/FormID.java b/src/main/java/org/geysermc/connect/ui/FormID.java index daf9fd2..2cef258 100644 --- a/src/main/java/org/geysermc/connect/ui/FormID.java +++ b/src/main/java/org/geysermc/connect/ui/FormID.java @@ -33,6 +33,7 @@ public enum FormID { WELCOME, MAIN, DIRECT_CONNECT(true), + LIST_SERVERS(true), EDIT_SERVERS(true), SERVER_OPTIONS(true), ADD_SERVER(true), @@ -41,7 +42,7 @@ public enum FormID { CONNECTING, ERROR; - private boolean handlesNull; + private final boolean handlesNull; private static final FormID[] VALUES = values(); diff --git a/src/main/java/org/geysermc/connect/ui/UIHandler.java b/src/main/java/org/geysermc/connect/ui/UIHandler.java index a142055..100d35f 100644 --- a/src/main/java/org/geysermc/connect/ui/UIHandler.java +++ b/src/main/java/org/geysermc/connect/ui/UIHandler.java @@ -39,39 +39,53 @@ import org.geysermc.common.window.response.SimpleFormResponse; import org.geysermc.connect.MasterServer; import org.geysermc.connect.utils.Player; import org.geysermc.connect.utils.Server; +import org.geysermc.connect.utils.ServerCategory; import java.util.ArrayList; import java.util.List; public class UIHandler { + public static FormWindow getMainMenu() { + SimpleFormWindow window = new SimpleFormWindow("Main Menu", ""); + + window.getButtons().add(new FormButton("Official Servers")); + window.getButtons().add(new FormButton("Geyser Servers")); + + // Add a buttons for custom servers + if (MasterServer.getInstance().getGeyserConnectConfig().getCustomServers().isEnabled()) { + window.getButtons().add(new FormButton("Custom Servers")); + window.getButtons().add(new FormButton("Direct connect")); + } + + window.getButtons().add(new FormButton("Disconnect")); + + return window; + } + /** * Create a list of servers for the client based on the passed servers list * * @param servers A list of {@link Server} objects + * @param category The category of the current list * @return A {@link SimpleFormWindow} object */ - public static FormWindow getServerList(List servers) { - SimpleFormWindow window = new SimpleFormWindow("Servers", ""); + public static FormWindow getServerList(List servers, ServerCategory category) { + SimpleFormWindow window = new SimpleFormWindow(category.getTitle() + " Servers", ""); // Add a button for each global server - for (Server server : MasterServer.getInstance().getGeyserConnectConfig().getServers()) { + for (Server server : servers) { // These images would be better if there was a default to fall back on // But that would require a web api as bedrock doesn't support doing that window.getButtons().add(new FormButton(server.toString(), server.getFormImage())); } - // Add a button for each personal server - if (MasterServer.getInstance().getGeyserConnectConfig().getCustomServers().isEnabled()) { - for (Server server : servers) { - window.getButtons().add(new FormButton(server.toString(), server.getFormImage())); - } - + // Add a button for editing + if (category == ServerCategory.CUSTOM) { window.getButtons().add(new FormButton("Edit servers")); - window.getButtons().add(new FormButton("Direct connect")); } - window.getButtons().add(new FormButton("Disconnect")); + window.getButtons().add(new FormButton("Back")); return window; } @@ -183,10 +197,44 @@ public class UIHandler { } public static FormWindow getMessageWindow(String message) { - CustomFormWindow window = new CustomFormBuilder("Notice") + return new CustomFormBuilder("Notice") .addComponent(new LabelComponent(message)) .build(); - return window; + } + + + public static void handleMainMenuResponse(Player player, SimpleFormResponse data) { + switch (data.getClickedButtonId()) { + case 0: + player.setServerCategory(ServerCategory.OFFICIAL); + break; + + case 1: + player.setServerCategory(ServerCategory.GEYSER); + break; + + default: + if (MasterServer.getInstance().getGeyserConnectConfig().getCustomServers().isEnabled()) { + switch (data.getClickedButtonId()) { + case 2: + player.setServerCategory(ServerCategory.CUSTOM); + break; + case 3: + player.sendWindow(FormID.DIRECT_CONNECT, getDirectConnect()); + return; + + default: + player.getSession().disconnect("disconnectionScreen.disconnected"); + break; + } + } else { + player.getSession().disconnect("disconnectionScreen.disconnected"); + return; + } + break; + } + + player.sendWindow(FormID.LIST_SERVERS, getServerList(player.getCurrentServers(), player.getServerCategory())); } /** @@ -196,22 +244,28 @@ public class UIHandler { * @param data The form response data */ public static void handleServerListResponse(Player player, SimpleFormResponse data) { - List servers = new ArrayList<>(MasterServer.getInstance().getGeyserConnectConfig().getServers()); - servers.addAll(player.getServers()); + List servers = player.getCurrentServers(); - // Cant be done in a switch as we need to calculate the last 2 buttons + if (player.getServerCategory() == ServerCategory.CUSTOM) { + if (data == null || data.getClickedButtonId() == servers.size() + 1) { + player.sendWindow(FormID.MAIN, UIHandler.getMainMenu()); + } else if (data.getClickedButtonId() == servers.size()) { + player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getCurrentServers())); + } else { + // Get the server + Server server = servers.get(data.getClickedButtonId()); - if ((!MasterServer.getInstance().getGeyserConnectConfig().getCustomServers().isEnabled() && data.getClickedButtonId() == servers.size()) || data.getClickedButtonId() == servers.size() + 2) { - player.getSession().disconnect("disconnectionScreen.disconnected"); - } else if (data.getClickedButtonId() == servers.size()) { - player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers())); - } else if (data.getClickedButtonId() == servers.size() + 1) { - player.sendWindow(FormID.DIRECT_CONNECT, getDirectConnect()); + player.sendToServer(server); + } } else { - // Get the server - Server server = servers.get(data.getClickedButtonId()); + if (data == null || data.getClickedButtonId() == servers.size()) { + player.sendWindow(FormID.MAIN, UIHandler.getMainMenu()); + } else { + // Get the server + Server server = servers.get(data.getClickedButtonId()); - player.sendToServer(server); + player.sendToServer(server); + } } } @@ -224,7 +278,7 @@ public class UIHandler { public static void handleDirectConnectResponse(Player player, CustomFormResponse data) { // Take them back to the main menu if they close the direct connect window if (data == null) { - player.sendWindow(FormID.MAIN, getServerList(player.getServers())); + player.sendWindow(FormID.MAIN, getMainMenu()); return; } @@ -236,7 +290,7 @@ public class UIHandler { // Make sure we got an address if (address == null || "".equals(address)) { - player.sendWindow(FormID.MAIN, getServerList(player.getServers())); + player.sendWindow(FormID.MAIN, getMainMenu()); return; } @@ -259,17 +313,18 @@ public class UIHandler { * @param data The form response data */ public static void handleEditServerListResponse(Player player, SimpleFormResponse data) { + List servers = player.getCurrentServers(); + // Take them back to the main menu if they close the edit server list window if (data == null) { - player.sendWindow(FormID.MAIN, getServerList(player.getServers())); + player.sendWindow(FormID.LIST_SERVERS, getServerList(servers, player.getServerCategory())); return; } - List servers = player.getServers(); if (data.getClickedButtonId() == servers.size()) { player.sendWindow(FormID.ADD_SERVER, getAddServer()); } else if (data.getClickedButtonId() == servers.size() + 1) { - player.sendWindow(FormID.MAIN, getServerList(player.getServers())); + player.sendWindow(FormID.LIST_SERVERS, getServerList(servers, player.getServerCategory())); } else { Server server = player.getServers().get(data.getClickedButtonId()); player.sendWindow(FormID.SERVER_OPTIONS, getServerOptions(server)); diff --git a/src/main/java/org/geysermc/connect/utils/Logger.java b/src/main/java/org/geysermc/connect/utils/Logger.java index e8531ef..d015c05 100644 --- a/src/main/java/org/geysermc/connect/utils/Logger.java +++ b/src/main/java/org/geysermc/connect/utils/Logger.java @@ -35,7 +35,7 @@ import org.geysermc.connector.common.ChatColor; @Log4j2 public class Logger extends SimpleTerminalConsole implements GeyserLogger { - private boolean colored = true; + private final boolean colored = true; @Override protected boolean isRunning() { diff --git a/src/main/java/org/geysermc/connect/utils/PaletteManger.java b/src/main/java/org/geysermc/connect/utils/PaletteManger.java index 26360d4..528fbc6 100644 --- a/src/main/java/org/geysermc/connect/utils/PaletteManger.java +++ b/src/main/java/org/geysermc/connect/utils/PaletteManger.java @@ -26,11 +26,9 @@ package org.geysermc.connect.utils; import com.nukkitx.nbt.*; -import org.geysermc.connector.utils.FileUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/geysermc/connect/utils/Player.java b/src/main/java/org/geysermc/connect/utils/Player.java index ad406d5..10a8bd9 100644 --- a/src/main/java/org/geysermc/connect/utils/Player.java +++ b/src/main/java/org/geysermc/connect/utils/Player.java @@ -51,11 +51,11 @@ import java.util.UUID; @Getter public class Player { - private String xuid; - private UUID identity; - private String displayName; + private final String xuid; + private final UUID identity; + private final String displayName; - private BedrockServerSession session; + private final BedrockServerSession session; private final List servers = new ArrayList<>(); private final Long2ObjectMap forms = new Long2ObjectOpenHashMap<>(); @@ -69,6 +69,9 @@ public class Player { @Setter private BedrockClientData clientData; + @Setter + private ServerCategory serverCategory; + public Player(JsonNode extraData, BedrockServerSession session) { this.xuid = extraData.get("XUID").asText(); this.identity = UUID.fromString(extraData.get("identity").asText()); @@ -222,7 +225,7 @@ public class Player { public void sendToServer(Server server) { // Tell the user we are connecting them - // this wont show up in alot of cases as the client connects quite quickly + // This wont show up in a lot of cases as the client connects quite quickly sendWindow(FormID.CONNECTING, UIHandler.getWaitingScreen(server)); if (!server.isBedrock()) { @@ -234,4 +237,12 @@ public class Player { setCurrentServer(server); connectToProxy(); } + + public List getCurrentServers() { + if (serverCategory == ServerCategory.CUSTOM) { + return servers; + } + + return MasterServer.getInstance().getServers(serverCategory); + } } diff --git a/src/main/java/org/geysermc/connect/utils/Server.java b/src/main/java/org/geysermc/connect/utils/Server.java index 164d024..04488f4 100644 --- a/src/main/java/org/geysermc/connect/utils/Server.java +++ b/src/main/java/org/geysermc/connect/utils/Server.java @@ -42,6 +42,7 @@ public class Server { private boolean bedrock = false; private String name = null; private String imageUrl = null; + private ServerCategory category = null; public Server(String address) { this(address, -1); @@ -63,6 +64,10 @@ public class Server { this(address, port, online, bedrock, name, null); } + public Server(String address, int port, boolean online, boolean bedrock, String name, String imageUrl) { + this(address, port, online, bedrock, name, imageUrl, ServerCategory.CUSTOM); + } + private int defaultPort() { return bedrock ? 19132 : 25565; } public int getPort() { return port < 0 ? defaultPort() : port; } diff --git a/src/main/java/org/geysermc/connect/utils/ServerCategory.java b/src/main/java/org/geysermc/connect/utils/ServerCategory.java new file mode 100644 index 0000000..a7ade38 --- /dev/null +++ b/src/main/java/org/geysermc/connect/utils/ServerCategory.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019-2021 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/GeyserConnect + */ + +package org.geysermc.connect.utils; + +import lombok.Getter; + +@Getter +public enum ServerCategory { + OFFICIAL("Official"), + GEYSER("Geyser"), + CUSTOM("Custom"); + + private final String title; + + ServerCategory(String title) { + this.title = title; + } +} diff --git a/src/main/java/org/geysermc/connect/utils/WebUtils.java b/src/main/java/org/geysermc/connect/utils/WebUtils.java index cd39ea7..98e4616 100644 --- a/src/main/java/org/geysermc/connect/utils/WebUtils.java +++ b/src/main/java/org/geysermc/connect/utils/WebUtils.java @@ -42,7 +42,7 @@ public class WebUtils extends org.geysermc.connector.utils.WebUtils { * @return Body contents or error message if the request fails */ public static String getBody(String reqURL) { - URL url = null; + URL url; try { url = new URL(reqURL); HttpURLConnection con = (HttpURLConnection) url.openConnection(); @@ -60,7 +60,7 @@ public class WebUtils extends org.geysermc.connector.utils.WebUtils { * * @param con The connection to get the string from * @return The body of the returned page - * @throws IOException + * @throws IOException If the request fails */ private static String connectionToString(HttpURLConnection con) throws IOException { // Send the request (we dont use this but its required for getErrorStream() to work) @@ -74,7 +74,7 @@ public class WebUtils extends org.geysermc.connector.utils.WebUtils { BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); String inputLine; - StringBuffer content = new StringBuffer(); + StringBuilder content = new StringBuilder(); while ((inputLine = in.readLine()) != null) { content.append(inputLine); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0bc2be7..7943646 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -49,9 +49,11 @@ servers: bedrock: true name: Official Geyser Test Server imageUrl: https://geysermc.org/android-chrome-192x192.png + category: OFFICIAL - address: "play.cubecraft.net" - address: "127.0.0.1" port: 25565 + category: GEYSER custom-servers: # Should custom servers be enabled for users