diff --git a/src/main/java/com/loohp/limbo/Limbo.java b/src/main/java/com/loohp/limbo/Limbo.java index c2f0d6e..52fad0f 100644 --- a/src/main/java/com/loohp/limbo/Limbo.java +++ b/src/main/java/com/loohp/limbo/Limbo.java @@ -432,6 +432,31 @@ public class Limbo { public ServerProperties getServerProperties() { return properties; } + + public void reloadAllowlist() { + properties.reloadAllowlist(); + } + + public boolean uuidIsAllowed(UUID requestedUuid) { + if (!properties.isEnforceAllowlist()) { + return true; + } + + for (UUID allowedUuid : properties.getAllowlist()) { + if (requestedUuid.equals(allowedUuid)) { + if(!properties.isReducedDebugInfo()) { + Limbo.getInstance().getConsole().sendMessage(String.format("allowlist: %s allowed", requestedUuid.toString())); + } + return true; + } + } + + if(!properties.isReducedDebugInfo()) { + Limbo.getInstance().getConsole().sendMessage(String.format("allowlist: %s not allowed", requestedUuid.toString())); + } + + return false; + } public ServerConnection getServerConnection() { return server; diff --git a/src/main/java/com/loohp/limbo/commands/DefaultCommands.java b/src/main/java/com/loohp/limbo/commands/DefaultCommands.java index ec6f170..c7def11 100644 --- a/src/main/java/com/loohp/limbo/commands/DefaultCommands.java +++ b/src/main/java/com/loohp/limbo/commands/DefaultCommands.java @@ -165,6 +165,20 @@ public class DefaultCommands implements CommandExecutor, TabCompletor { } return; } + if (args[0].equalsIgnoreCase("allowlist")) { + if (sender.hasPermission("limboserver.allowlist")) { + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Invalid usage!"); + } else if (!args[1].equalsIgnoreCase("reload")) { + sender.sendMessage(ChatColor.RED + "Invalid usage!"); + } else { + Limbo.getInstance().reloadAllowlist(); + } + } else { + sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); + } + return; + } } @Override diff --git a/src/main/java/com/loohp/limbo/file/ServerProperties.java b/src/main/java/com/loohp/limbo/file/ServerProperties.java index 8f10271..7da1b91 100644 --- a/src/main/java/com/loohp/limbo/file/ServerProperties.java +++ b/src/main/java/com/loohp/limbo/file/ServerProperties.java @@ -22,20 +22,31 @@ package com.loohp.limbo.file; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.Optional; import java.util.Properties; +import java.util.UUID; import javax.imageio.ImageIO; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + import com.google.common.collect.Lists; +import com.loohp.limbo.Console; import com.loohp.limbo.Limbo; import com.loohp.limbo.location.Location; import com.loohp.limbo.utils.GameMode; @@ -72,6 +83,8 @@ public class ServerProperties { private int viewDistance; private double ticksPerSecond; private boolean handshakeVerbose; + private boolean enforceAllowlist; + private ArrayList allowlist; private String resourcePackSHA1; private String resourcePackLink; @@ -184,9 +197,65 @@ public class ServerProperties { favicon = Optional.empty(); } + enforceAllowlist = Boolean.parseBoolean(prop.getProperty("enforce-allowlist")); + if (enforceAllowlist) { + reloadAllowlist(); + } + Limbo.getInstance().getConsole().sendMessage("Loaded server.properties"); } - + + public void reloadAllowlist() { + Console console = Limbo.getInstance().getConsole(); + + allowlist = new ArrayList(); + try { + JSONParser parser = new JSONParser(); + Object obj = parser.parse(new FileReader("allowlist.json")); + + if (!(obj instanceof JSONArray)) { + console.sendMessage("allowlist: expected [] got {}"); + return; + } + + JSONArray array = (JSONArray) obj; + + Iterator iter = array.iterator(); + while (iter.hasNext()) { + Object o = iter.next(); + if (!(o instanceof JSONObject)) { + console.sendMessage("allowlist: array element is not an object"); + continue; + } + + JSONObject element = (JSONObject) o; + o = element.get("uuid"); + if (o == null) { + console.sendMessage("allowlist: missing uuid attribute"); + continue; + } + if (!(o instanceof String)) { + console.sendMessage("allowlist: uuid is not a string"); + continue; + } + + String uuidStr = (String) o; + UUID allowedUuid = UUID.fromString(uuidStr); + allowlist.add(allowedUuid); + } + } catch (IllegalArgumentException e) { + console.sendMessage(e.toString()); + } catch (FileNotFoundException e) { + console.sendMessage(String.format("allowlist: %s", e.toString())); + } catch (IOException e) { + console.sendMessage(String.format("allowlist: %s", e.toString())); + } catch (ParseException e) { + console.sendMessage(String.format(" allowlist: parse: %s", e.toString())); + } + + console.sendMessage("allowlist: reloaded"); + } + public String getServerImplementationVersion() { return Limbo.getInstance().SERVER_IMPLEMENTATION_VERSION; } @@ -294,6 +363,14 @@ public class ServerProperties { public boolean handshakeVerboseEnabled() { return handshakeVerbose; } + + public boolean isEnforceAllowlist() { + return enforceAllowlist; + } + + public ArrayList getAllowlist() { + return allowlist; + } public String getResourcePackLink() { return resourcePackLink; diff --git a/src/main/java/com/loohp/limbo/network/ClientConnection.java b/src/main/java/com/loohp/limbo/network/ClientConnection.java index df9309a..95d56b6 100644 --- a/src/main/java/com/loohp/limbo/network/ClientConnection.java +++ b/src/main/java/com/loohp/limbo/network/ClientConnection.java @@ -19,7 +19,6 @@ package com.loohp.limbo.network; -import com.loohp.limbo.Console; import com.loohp.limbo.Limbo; import com.loohp.limbo.events.player.PlayerJoinEvent; import com.loohp.limbo.events.player.PlayerSpawnEvent; @@ -98,14 +97,11 @@ import net.md_5.bungee.api.chat.TranslatableComponent; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; import java.io.ByteArrayOutputStream; import java.io.DataInput; import java.io.DataInputStream; import java.io.DataOutputStream; -import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Constructor; import java.net.InetAddress; @@ -113,7 +109,6 @@ import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Random; @@ -300,84 +295,6 @@ public class ClientConnection extends Thread { }); } - public boolean uuidAllowed(UUID uuid, boolean verbose) { - Console console = Limbo.getInstance().getConsole(); - - try { - JSONParser parser = new JSONParser(); - Object obj = parser.parse(new FileReader("allowlist.json")); - - if (!(obj instanceof JSONArray)) { - if (verbose) { - console.sendMessage("allowlist: expected [] got {}"); - } - return false; - } - - JSONArray array = (JSONArray) obj; - - Iterator iter = array.iterator(); - while (iter.hasNext()) { - Object o = iter.next(); - if (!(o instanceof JSONObject)) { - if (verbose) { - console.sendMessage("allowlist: array element is not an object"); - } - continue; - } - - JSONObject element = (JSONObject) o; - o = element.get("uuid"); - if (o == null) { - if (verbose) { - console.sendMessage("allowlist: missing uuid attribute"); - } - continue; - } - if (!(o instanceof String)) { - if (verbose) { - console.sendMessage("allowlist: uuid is not a string"); - } - continue; - } - String uuidStr = (String) o; - - UUID allowedUuid = UUID.fromString(uuidStr); - if (uuid.equals(allowedUuid)) { - if(verbose) { - console.sendMessage(String.format("allowlist: %s allowed", uuid.toString())); - } - return true; - } - } - } catch (IllegalArgumentException e) { - if (verbose) { - console.sendMessage(e.toString()); - } - return false; - } catch (FileNotFoundException e) { - if (verbose) { - console.sendMessage(String.format("allowlist: no allowlist: %s allowed", uuid.toString())); - } - return true; - } catch (IOException e) { - if (verbose) { - console.sendMessage(String.format("allowlist: %s", e.toString())); - } - return false; - } catch (ParseException e) { - if (verbose) { - console.sendMessage(String.format(" allowlist: parse: %s", e.toString())); - } - return false; - } - - if (verbose) { - console.sendMessage(String.format("allowlist: %s is not allowed", uuid.toString())); - } - return false; - } - @SuppressWarnings("deprecation") @Override public void run() { @@ -553,7 +470,7 @@ public class ClientConnection extends Thread { UUID uuid = isBungeecord || isBungeeGuard ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); - if (!uuidAllowed(uuid, !properties.isReducedDebugInfo())) { + if (!Limbo.getInstance().uuidIsAllowed(uuid)) { disconnectDuringLogin(TextComponent.fromLegacyText("You are not invited to this server")); break; }