Merge pull request #57 from tadhunt/allowlist

player allow/deny via addition of support for allowlist.json
This commit is contained in:
LOOHP 2022-12-07 18:56:12 +00:00 committed by GitHub
commit f8bad7fa14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 131 additions and 3 deletions

View File

@ -433,6 +433,29 @@ public class Limbo {
return properties;
}
public void reloadAllowlist() {
properties.reloadAllowlist();
}
public boolean uuidIsAllowed(UUID requestedUuid) {
if (!properties.isEnforceAllowlist()) {
return true;
}
if (properties.uuidIsAllowed(requestedUuid)) {
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;
}

View File

@ -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

View File

@ -22,20 +22,32 @@ 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.HashMap;
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 +84,8 @@ public class ServerProperties {
private int viewDistance;
private double ticksPerSecond;
private boolean handshakeVerbose;
private boolean enforceAllowlist;
private HashMap<UUID, Boolean> allowlist;
private String resourcePackSHA1;
private String resourcePackLink;
@ -184,9 +198,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 HashMap<UUID, Boolean>();
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.put(allowedUuid, true);
}
} 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;
}
@ -295,6 +365,17 @@ public class ServerProperties {
return handshakeVerbose;
}
public boolean isEnforceAllowlist() {
return enforceAllowlist;
}
public boolean uuidIsAllowed(UUID requestedUuid) {
if (allowlist.containsKey(requestedUuid)) {
return true;
}
return false;
}
public String getResourcePackLink() {
return resourcePackLink;
}

View File

@ -88,6 +88,7 @@ import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse;
import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.BlockPosition;
import com.loohp.limbo.world.World;
import net.kyori.adventure.text.Component;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
@ -360,9 +361,9 @@ public class ClientConnection extends Thread {
break;
case LOGIN:
state = ClientState.LOGIN;
ServerProperties properties = Limbo.getInstance().getServerProperties();
if (isBungeecord || isBungeeGuard) {
ServerProperties properties = Limbo.getInstance().getServerProperties();
try {
String[] data = bungeeForwarding.split("\\x00");
String host = "";
@ -469,6 +470,11 @@ public class ClientConnection extends Thread {
UUID uuid = isBungeecord || isBungeeGuard ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
if (!Limbo.getInstance().uuidIsAllowed(uuid)) {
disconnectDuringLogin(TextComponent.fromLegacyText("You are not invited to this server"));
break;
}
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username);
sendPacket(success);

View File

@ -80,3 +80,7 @@ required-resource-pack=false
#JSON formatted text to show when prompting the player to install the resource pack (May be left blank)
resource-pack-prompt={"text":"","extra":[{"text":"Install server resource pack!","color":"yellow"}]}
#Whether to enforce the player allowlist. If true, loads and enforces the allowlist from 'allowlist.json'
#in the same format as vanilla minecraft servers
enforce-allowlist=false