From 6e1d5d132ca57ef54a8854e890336abae12e466a Mon Sep 17 00:00:00 2001 From: Colbster937 <96893162+colbychittenden@users.noreply.github.com> Date: Fri, 13 Jun 2025 13:21:32 -0400 Subject: [PATCH] add ip blacklisting & blacklist cmd --- README.md | 7 +- build.gradle | 4 +- .../originblacklist/base/Base.java | 43 ++++-- .../originblacklist/base/Command.java | 142 +++++++++++++++++- .../originblacklist/base/ConfigManager.java | 67 +++++++-- .../originblacklist/base/IPBlacklist.java | 38 +++++ .../originblacklist/bukkit/CommandBukkit.java | 25 ++- .../bukkit/OriginBlacklistBukkit.java | 17 ++- .../originblacklist/bungee/CommandBungee.java | 17 ++- .../bungee/OriginBlacklistBungee.java | 18 ++- .../velocity/CommandVelocity.java | 61 +++++--- .../velocity/OriginBlacklistVelocity.java | 19 ++- src/main/resources/config.yml | 16 +- 13 files changed, 394 insertions(+), 80 deletions(-) create mode 100644 src/main/java/dev/colbster937/originblacklist/base/IPBlacklist.java diff --git a/README.md b/README.md index fa047fc..4d9eff9 100644 --- a/README.md +++ b/README.md @@ -9,16 +9,15 @@ basically just a reimplementation of originblacklist but for eaglerxserver - [x] Origin Blacklisting - [x] Brand Blacklisting - [x] Username blacklisting +- [x] IP blacklisting - [x] Custom kick message - [x] Custom blacklist MOTD - [x] MiniMessage formatting for messages -- [x] Velocity, *Bungee, and *Bukkit support -
_Bungee and Bukkit are should work, but have bugs._ +- [x] Velocity, Bungee, and Bukkit support - [x] Send blacklists to a discord webhook +- [x] Simple blacklist command - [ ] Blacklist subscription URLs -- [ ] Simple blacklist command - [ ] Blacklist -> Whitelist -- [ ] IP blacklisting - [ ] Update system ### Download diff --git a/build.gradle b/build.gradle index 63cad31..59004a9 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { group = 'dev.colbster937' -version = '1.0.6' +version = '1.1.0' description = 'A reimplementation of OriginBlacklist for EaglerXServer' def targetJavaVersion = 17 @@ -51,6 +51,7 @@ dependencies { implementation("org.yaml:snakeyaml:2.2") implementation("net.kyori:adventure-text-serializer-legacy:4.20.0") implementation("net.kyori:adventure-text-minimessage:4.20.0") + implementation("com.github.seancfoley:ipaddress:5.3.4") } tasks { @@ -74,6 +75,7 @@ processResources { shadowJar { relocate 'org.yaml.snakeyaml', 'dev.colbster937.shaded.snakeyaml' + relocate 'inet.ipaddr', 'dev.colbster937.shaded.ipaddr' archiveVersion.set('') archiveClassifier.set('') } diff --git a/src/main/java/dev/colbster937/originblacklist/base/Base.java b/src/main/java/dev/colbster937/originblacklist/base/Base.java index 2acde18..d40b2fd 100644 --- a/src/main/java/dev/colbster937/originblacklist/base/Base.java +++ b/src/main/java/dev/colbster937/originblacklist/base/Base.java @@ -22,7 +22,7 @@ import java.util.stream.Collectors; public class Base { private static LoggerAdapter adapter; private static IEaglerXServerAPI api; - private static ConfigManager config; + private static IPBlacklist ipblacklist; public static void setLogger(LoggerAdapter log) { adapter = log; @@ -32,7 +32,9 @@ public class Base { api = api1; } - public static String apiVer = "1.0.2"; + public static ConfigManager config; + + public static String pluginVer = "1.0.2"; public static boolean checkVer(String v1, String v2) { String[] c = v1.split("\\."); @@ -67,11 +69,13 @@ public class Base { String origin = conn.getWebSocketHeader(EnumWebSocketHeader.HEADER_ORIGIN); String brand = conn.getEaglerBrandString(); String name = conn.getUsername(); + String notAllowed1 = "not allowed on the server"; + String notAllowed2 = "not allowed"; if (origin != null && !origin.equals("null")) { for (String origin1 : config.blacklist.origins) { if (matches(origin, origin1)) { - setKick(e, formatKickMessage("origin", "website", origin, conn.getWebSocketHost())); + setKick(e, formatKickMessage("origin", "website", notAllowed1, notAllowed2, origin, conn.getWebSocketHost())); webhook(conn, origin, brand, "origin"); return; } @@ -81,7 +85,7 @@ public class Base { if (brand != null && !brand.equals("null")) { for (String brand1 : config.blacklist.brands) { if (matches(brand, brand1)) { - setKick(e, formatKickMessage("brand", "client", brand, conn.getWebSocketHost())); + setKick(e, formatKickMessage("brand", "client", notAllowed1, notAllowed2, brand, conn.getWebSocketHost())); webhook(conn, origin, brand, "brand"); return; } @@ -91,7 +95,7 @@ public class Base { if (name != null && !name.equals("null")) { for (String name1 : config.blacklist.players) { if (matches(name, name1) || (name.length() > 16 || name.length() < 3)) { - setKick(e, formatKickMessage("player", "username", name, conn.getWebSocketHost())); + setKick(e, formatKickMessage("player", "username", notAllowed1, notAllowed2, name, conn.getWebSocketHost())); webhook(conn, origin, name, "player"); return; } @@ -117,6 +121,8 @@ public class Base { .map(line -> line .replaceAll("%blocktype%", "origin") .replaceAll("%easyblocktype%", "website") + .replaceAll("%notallowed1%", "blacklisted") + .replaceAll("%notallowed2%", "blacklisted") .replaceAll("%blocked%", origin) .replaceAll("%host%", conn.getWebSocketHost())) .map(line -> LegacyComponentSerializer.legacySection().serialize( @@ -130,8 +136,6 @@ public class Base { return; } } - } else if (origin != null && !origin.equals("null")) { - setMOTD(conn, m); } } } @@ -168,14 +172,28 @@ public class Base { } } + public static String handlePre(String ip, String name) { + if (ip != null && !ip.equalsIgnoreCase("null")) { + for (String ip1 : Base.config.blacklist.ips) { + if (ipblacklist.check(ip)) { + Component kick = formatKickMessage("ip address", "ip", "blacklisted", "blacklisted", ip, ""); + return LegacyComponentSerializer.legacySection().serialize(kick); + } + } + } + return "false"; + } + public static boolean matches(String text1, String text2) { return text1.toLowerCase().matches(text2.replace(".", "\\.").replaceAll("\\*", ".*").toLowerCase()); } - public static Component formatKickMessage(String type, String easytype, String value, String host) { + public static Component formatKickMessage(String type, String easytype, String notAllowed1, String notAllowed2, String value, String host) { String help = ""; if (type != "player") { help = config.messages.help.generic; + } else if (type == "ip") { + help = config.messages.help.ip; } else { help = config.messages.help.player; } @@ -184,6 +202,8 @@ public class Base { .replaceAll("%help%", help) .replaceAll("%blocktype%", type) .replaceAll("%easyblocktype%", easytype) + .replaceAll("%notallowed1%", notAllowed1) + .replaceAll("%notallowed2%", notAllowed2) .replaceAll("%blocked%", value) .replaceAll("%host%", host)); } @@ -194,7 +214,7 @@ public class Base { return; CompletableFuture.runAsync(() -> { - String addr = (plr.getPlayerAddress() != null ? plr.getPlayerAddress().toString().substring(1) : "undefined:undefined").split(":")[0]; + String addr = getAddr(plr); int protocol = !plr.isEaglerXRewindPlayer() ? plr.getMinecraftProtocol() : plr.getRewindProtocolVersion(); String host = plr.getWebSocketHost(); String userAgent = plr.getWebSocketHeader(EnumWebSocketHeader.HEADER_USER_AGENT); @@ -235,6 +255,10 @@ public class Base { }); } + public static String getAddr(IEaglerLoginConnection plr) { + return (plr.getPlayerAddress() != null ? plr.getPlayerAddress().toString().substring(1) : "undefined:undefined").split(":")[0]; + } + public static void init() { File motdIcon = new File(config.messages.motd.icon); if (!motdIcon.exists()) { @@ -246,6 +270,7 @@ public class Base { getLogger().warn(e.toString()); } } + ipblacklist = new IPBlacklist(); } public static void reloadConfig() { diff --git a/src/main/java/dev/colbster937/originblacklist/base/Command.java b/src/main/java/dev/colbster937/originblacklist/base/Command.java index 9c0e020..f275ce0 100644 --- a/src/main/java/dev/colbster937/originblacklist/base/Command.java +++ b/src/main/java/dev/colbster937/originblacklist/base/Command.java @@ -1,6 +1,16 @@ package dev.colbster937.originblacklist.base; +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static dev.colbster937.originblacklist.base.Base.config; + public class Command { + private static final String permission = "You do not have permission to use this command."; public interface CommandContext { String getName(); @@ -9,16 +19,18 @@ public class Command { String[] getArgs(); } - public static void usage(CommandContext ctx) { ctx.reply("Commands:"); ctx.reply(" - /originblacklist reload"); + ctx.reply(" - /originblacklist add "); + ctx.reply(" - /originblacklist remove "); + ctx.reply(" - /originblacklist list"); } public static void handle(CommandContext ctx) { String[] args = ctx.getArgs(); - if (!ctx.hasPermission("originblacklist.reload")) { - ctx.reply("You do not have permission to use this command."); + if (!ctx.hasPermission("originblacklist.command")) { + ctx.reply(permission); return; } else if (args.length == 0) { usage(ctx); @@ -26,14 +38,136 @@ public class Command { } String sub = args[0].toLowerCase(); + String sub1 = args.length > 1 ? args[1].toLowerCase() : ""; + String sub2 = args.length > 2 ? args[2].toLowerCase() : ""; switch (sub) { case "reload" -> { + if (ctx.hasPermission("originblacklist.reload")) { + Base.reloadConfig(); + ctx.reply("Reloaded."); + } else { + ctx.reply(permission); + return; + } + } + + case "add" -> { + if (!ctx.hasPermission("originblacklist.add")) { + ctx.reply(permission); + return; + } + + if (sub1.isEmpty() || sub2.isEmpty()) { + usage(ctx); + return; + } + + List list = switch (sub1) { + case "brand" -> Base.config.blacklist.brands; + case "origin" -> Base.config.blacklist.origins; + case "player" -> Base.config.blacklist.players; + case "ip" -> Base.config.blacklist.ips; + default -> null; + }; + + if (list == null) { + usage(ctx); + return; + } + + if (!list.contains(sub2)) { + list.add(sub2); + ctx.reply("Added " + sub2 + " to " + sub1 + " blacklist."); + } else { + ctx.reply("Already blacklisted."); + } + try { + config.saveConfig(Base.config.toMap(), new File("plugins/originblacklist/config.yml")); + } catch (IOException e) { + throw new RuntimeException(e); + } Base.reloadConfig(); - ctx.reply("Reloaded."); + } + + case "remove" -> { + if (!ctx.hasPermission("originblacklist.remove")) { + ctx.reply(permission); + return; + } + + if (sub1.isEmpty() || sub2.isEmpty()) { + usage(ctx); + return; + } + + List list = switch (sub1) { + case "brand" -> Base.config.blacklist.brands; + case "origin" -> Base.config.blacklist.origins; + case "player" -> Base.config.blacklist.players; + case "ip" -> Base.config.blacklist.ips; + default -> null; + }; + + if (list == null) { + usage(ctx); + return; + } + + if (list.remove(sub2)) { + ctx.reply("Removed " + sub2 + " from " + sub1 + " blacklist."); + } else { + ctx.reply("Entry not found in " + sub1 + "."); + } + try { + config.saveConfig(Base.config.toMap(), new File("plugins/originblacklist/config.yml")); + } catch (IOException e) { + throw new RuntimeException(e); + } + Base.reloadConfig(); + } + + case "list" -> { + if (!ctx.hasPermission("originblacklist.view")) { + ctx.reply(permission); + return; + } + + ctx.reply("Blacklist:"); + + ctx.reply(" Brands:"); + for (String s : Base.config.blacklist.brands) ctx.reply(" - " + s + ""); + + ctx.reply(" Origins:"); + for (String s : Base.config.blacklist.origins) ctx.reply(" - " + s + ""); + + ctx.reply(" Players:"); + for (String s : Base.config.blacklist.players) ctx.reply(" - " + s + ""); + + ctx.reply(" IPs:"); + for (String s : Base.config.blacklist.ips) ctx.reply(" - " + s + ""); } default -> usage(ctx); } } + + public static List suggest(CommandContext ctx) { + String[] args = ctx.getArgs(); + + if (args.length == 1) { + return List.of("reload", "add", "remove", "list"); + } + + if (args.length == 2 && args[0].equalsIgnoreCase("add")) { + return List.of("brand", "origin", "player", "ip"); + } + + return List.of(); + } + + public Map toMap() { + Yaml yaml = new Yaml(); + return yaml.load(yaml.dump(this)); + } } diff --git a/src/main/java/dev/colbster937/originblacklist/base/ConfigManager.java b/src/main/java/dev/colbster937/originblacklist/base/ConfigManager.java index 63138d8..f9d548d 100644 --- a/src/main/java/dev/colbster937/originblacklist/base/ConfigManager.java +++ b/src/main/java/dev/colbster937/originblacklist/base/ConfigManager.java @@ -9,10 +9,13 @@ import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; +import inet.ipaddr.IPAddress; public class ConfigManager { public Messages messages = new Messages(); - public List subscriptions = List.of(); + //public List subscriptions = List.of(); public Blacklist blacklist = new Blacklist(); public Discord discord = new Discord(); @@ -27,16 +30,33 @@ public class ConfigManager { } } - Yaml y = new Yaml(new Constructor(ConfigManager.class, new LoaderOptions())); - ConfigManager l; - try (InputStream in = new FileInputStream(f)) { l = y.load(in); } + Constructor constructor = new Constructor(ConfigManager.class, new LoaderOptions()); + constructor.setPropertyUtils(new org.yaml.snakeyaml.introspector.PropertyUtils() {{ + setSkipMissingProperties(true); + }}); + Yaml y = new Yaml(constructor); + ConfigManager l = null; - if (l == null) l = new ConfigManager(); + try (InputStream in = new FileInputStream(f)) { + l = y.load(in); + } catch (Exception ex) { + logger.warn("Error loading config: " + ex.getMessage()); + } - Yaml raw = new Yaml(); - Map u = raw.load(new FileInputStream(f)); - Map d = raw.load(ConfigManager.class.getResourceAsStream("/config.yml")); - if (mergeConfig(u, d)) saveConfig(u, f); + if (l == null) { + l = new ConfigManager(); + } + + try { + Yaml raw = new Yaml(); + Map u = raw.load(new FileInputStream(f)); + Map d = raw.load(ConfigManager.class.getResourceAsStream("/config.yml")); + if (mergeConfig(u, d)) saveConfig(u, f); + } catch (Exception ex) { + logger.warn("YAML merge error: " + ex.getMessage()); + } + + l.blacklist.resolveIPS(logger); return l; } catch (IOException e) { @@ -57,19 +77,43 @@ public class ConfigManager { return c; } - private static void saveConfig(Map m, File f) throws IOException { + public static void saveConfig(Map m, File f) throws IOException { DumperOptions o = new DumperOptions(); o.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); o.setPrettyFlow(true); new Yaml(o).dump(m, new FileWriter(f)); } + public Map toMap() { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setPrettyFlow(true); + options.setAllowReadOnlyProperties(true); + + Yaml yaml = new Yaml(options); + String yaml1 = yaml.dumpAsMap(this); + Yaml parser = new Yaml(); + Object yaml2 = parser.load(yaml1); + + return (Map) yaml2; + } + public static class Blacklist { public List origins; public List brands; public List players; + public List ips = List.of(); + public transient Set ips1 = new CopyOnWriteArraySet<>(); public boolean missing_origin; - public String blacklist_redirect; + //public String blacklist_redirect; + + public void resolveIPS(Base.LoggerAdapter logger) { + for (String line : ips) { + try { + ips1.add(new inet.ipaddr.IPAddressString(line).toAddress()); + } catch (Throwable ignored) {} + } + } } public static class Discord { @@ -91,5 +135,6 @@ public class ConfigManager { public static class Help { public String generic; public String player; + public String ip; } } diff --git a/src/main/java/dev/colbster937/originblacklist/base/IPBlacklist.java b/src/main/java/dev/colbster937/originblacklist/base/IPBlacklist.java new file mode 100644 index 0000000..20a9de6 --- /dev/null +++ b/src/main/java/dev/colbster937/originblacklist/base/IPBlacklist.java @@ -0,0 +1,38 @@ +package dev.colbster937.originblacklist.base; + +import java.util.logging.Logger; + +import inet.ipaddr.AddressStringException; +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; + +import static dev.colbster937.originblacklist.base.Base.config; + +public class IPBlacklist { + private Logger logger = null; + + public IPBlacklist() { + this.logger = logger; + } + + public boolean check(String addr) { + IPAddress ip; + String addr1 = addr; + try { + if (addr.startsWith("/")) { + addr1 = addr.substring(1); + } + ip = new IPAddressString(addr1).toAddress(); + } catch (AddressStringException e) { + throw new RuntimeException("Invalid IP address: " + addr, e); + } + + return config.blacklist.ips1.stream().anyMatch(s -> { + try { + return s.contains(ip); + } catch (Exception e) { + return false; + } + }); + } +} diff --git a/src/main/java/dev/colbster937/originblacklist/bukkit/CommandBukkit.java b/src/main/java/dev/colbster937/originblacklist/bukkit/CommandBukkit.java index 1d874f3..6af3221 100644 --- a/src/main/java/dev/colbster937/originblacklist/bukkit/CommandBukkit.java +++ b/src/main/java/dev/colbster937/originblacklist/bukkit/CommandBukkit.java @@ -1,24 +1,37 @@ package dev.colbster937.originblacklist.bukkit; -import dev.colbster937.originblacklist.base.Command; import dev.colbster937.originblacklist.base.Command.CommandContext; -import org.bukkit.command.CommandSender; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; public class CommandBukkit implements CommandExecutor { @Override public boolean onCommand(CommandSender sender, org.bukkit.command.Command command, String label, String[] args) { - Command.handle(new CommandContext() { - public String getName() { return sender.getName(); } - public void reply(String msg) { sender.sendMessage(msg); } + dev.colbster937.originblacklist.base.Command.handle(new CommandContext() { + @Override + public String getName() { + return sender.getName(); + } + + @Override + public void reply(String msg) { + sender.sendMessage(LegacyComponentSerializer.legacySection() + .serialize(MiniMessage.miniMessage().deserialize(msg))); + } + + @Override public boolean hasPermission(String permission) { return sender.hasPermission(permission); } + + @Override public String[] getArgs() { return args; } }); return true; } -} +} \ No newline at end of file diff --git a/src/main/java/dev/colbster937/originblacklist/bukkit/OriginBlacklistBukkit.java b/src/main/java/dev/colbster937/originblacklist/bukkit/OriginBlacklistBukkit.java index 4735e1a..1c11d70 100644 --- a/src/main/java/dev/colbster937/originblacklist/bukkit/OriginBlacklistBukkit.java +++ b/src/main/java/dev/colbster937/originblacklist/bukkit/OriginBlacklistBukkit.java @@ -6,6 +6,7 @@ import net.lax1dude.eaglercraft.backend.server.api.bukkit.event.EaglercraftLogin import net.lax1dude.eaglercraft.backend.server.api.bukkit.event.EaglercraftMOTDEvent; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.Plugin; @@ -16,9 +17,9 @@ public class OriginBlacklistBukkit extends JavaPlugin implements Listener { Plugin plugin = getServer().getPluginManager().getPlugin("EaglercraftXServer"); if (plugin != null) { String version = plugin.getDescription().getVersion(); - if (!Base.checkVer(version, Base.apiVer)) { - getLogger().severe("EaglerXServer " + Base.apiVer + " is required!"); - throw new RuntimeException("Incompatible API version"); + if (!Base.checkVer(version, Base.pluginVer)) { + getLogger().severe("EaglerXServer " + Base.pluginVer + " is required!"); + throw new RuntimeException("Incompatible plugin version"); } } else { throw new RuntimeException("Missing EaglerXServer"); @@ -50,4 +51,14 @@ public class OriginBlacklistBukkit extends JavaPlugin implements Listener { public void onMOTD(EaglercraftMOTDEvent event) { Base.handleMOTD(event); } + + @EventHandler + public void onPreLogin(AsyncPlayerPreLoginEvent event) { + String ip = event.getAddress().getHostAddress(); + String name = event.getName(); + String blacklisted = Base.handlePre(ip, name); + if (!blacklisted.equals("false")) { + event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, blacklisted); + } + } } diff --git a/src/main/java/dev/colbster937/originblacklist/bungee/CommandBungee.java b/src/main/java/dev/colbster937/originblacklist/bungee/CommandBungee.java index d3432d3..05da43e 100644 --- a/src/main/java/dev/colbster937/originblacklist/bungee/CommandBungee.java +++ b/src/main/java/dev/colbster937/originblacklist/bungee/CommandBungee.java @@ -1,8 +1,8 @@ package dev.colbster937.originblacklist.bungee; -import dev.colbster937.originblacklist.base.Command; import dev.colbster937.originblacklist.base.Command.CommandContext; import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.chat.TextComponent; public class CommandBungee extends net.md_5.bungee.api.plugin.Command { @@ -12,15 +12,22 @@ public class CommandBungee extends net.md_5.bungee.api.plugin.Command { @Override public void execute(CommandSender sender, String[] args) { - Command.handle(new CommandContext() { - public String getName() { return sender.getName(); } - public void reply(String msg) { sender.sendMessage(msg); } + dev.colbster937.originblacklist.base.Command.handle(new CommandContext() { + public String getName() { + return sender.getName(); + } + + public void reply(String msg) { + sender.sendMessage(TextComponent.fromLegacyText(msg)); + } + public boolean hasPermission(String permission) { return sender.hasPermission(permission); } + public String[] getArgs() { return args; } }); } -} +} \ No newline at end of file diff --git a/src/main/java/dev/colbster937/originblacklist/bungee/OriginBlacklistBungee.java b/src/main/java/dev/colbster937/originblacklist/bungee/OriginBlacklistBungee.java index aea4236..2cf056f 100644 --- a/src/main/java/dev/colbster937/originblacklist/bungee/OriginBlacklistBungee.java +++ b/src/main/java/dev/colbster937/originblacklist/bungee/OriginBlacklistBungee.java @@ -4,6 +4,7 @@ import dev.colbster937.originblacklist.base.Base; import net.lax1dude.eaglercraft.backend.server.api.bungee.EaglerXServerAPI; import net.lax1dude.eaglercraft.backend.server.api.bungee.event.EaglercraftLoginEvent; import net.lax1dude.eaglercraft.backend.server.api.bungee.event.EaglercraftMOTDEvent; +import net.md_5.bungee.api.event.PreLoginEvent; import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; @@ -15,9 +16,9 @@ public class OriginBlacklistBungee extends Plugin implements Listener { Plugin plugin = getProxy().getPluginManager().getPlugin("EaglercraftXServer"); if (plugin != null) { String version = plugin.getDescription().getVersion(); - if (!Base.checkVer(version, Base.apiVer)) { - getLogger().severe("EaglerXServer " + Base.apiVer + " is required!"); - throw new RuntimeException("Incompatible API version"); + if (!Base.checkVer(version, Base.pluginVer)) { + getLogger().severe("EaglerXServer " + Base.pluginVer + " is required!"); + throw new RuntimeException("Incompatible plugin version"); } } else { throw new RuntimeException("Missing EaglerXServer"); @@ -49,4 +50,15 @@ public class OriginBlacklistBungee extends Plugin implements Listener { public void onMOTD(EaglercraftMOTDEvent event) { Base.handleMOTD(event); } + + @EventHandler + public void onPreLogin(PreLoginEvent event) { + String ip = event.getConnection().getAddress().getAddress().getHostAddress(); + String name = event.getConnection().getName(); + String blacklisted = Base.handlePre(ip, name); + if (!blacklisted.equals("false")) { + event.setCancelReason(blacklisted); + event.setCancelled(true); + } + } } diff --git a/src/main/java/dev/colbster937/originblacklist/velocity/CommandVelocity.java b/src/main/java/dev/colbster937/originblacklist/velocity/CommandVelocity.java index f60562a..a6a29b6 100644 --- a/src/main/java/dev/colbster937/originblacklist/velocity/CommandVelocity.java +++ b/src/main/java/dev/colbster937/originblacklist/velocity/CommandVelocity.java @@ -1,34 +1,49 @@ package dev.colbster937.originblacklist.velocity; import com.velocitypowered.api.command.SimpleCommand; +import dev.colbster937.originblacklist.base.Command; import dev.colbster937.originblacklist.base.Command.CommandContext; import net.kyori.adventure.text.minimessage.MiniMessage; -import com.velocitypowered.api.command.CommandSource; + +import java.util.List; public class CommandVelocity implements SimpleCommand { @Override public void execute(Invocation invocation) { - CommandSource source = invocation.source(); - dev.colbster937.originblacklist.base.Command.handle(new CommandContext() { - @Override - public String getName() { - return source.toString(); - } - - @Override - public void reply(String msg) { - source.sendMessage(MiniMessage.miniMessage().deserialize(msg)); - } - - @Override - public boolean hasPermission(String permission) { - return source.hasPermission(permission); - } - - public String[] getArgs() { - return invocation.arguments(); - } - }); + Command.handle(new VelocityCommandContext(invocation)); } -} + + @Override + public List suggest(Invocation invocation) { + return Command.suggest(new VelocityCommandContext(invocation)); + } + + public static class VelocityCommandContext implements CommandContext { + private final Invocation invocation; + + public VelocityCommandContext(Invocation invocation) { + this.invocation = invocation; + } + + @Override + public String getName() { + return invocation.source().toString(); + } + + @Override + public void reply(String message) { + invocation.source().sendMessage(MiniMessage.miniMessage().deserialize(message)); + } + + @Override + public boolean hasPermission(String permission) { + return invocation.source().hasPermission(permission); + } + + @Override + public String[] getArgs() { + return invocation.arguments(); + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/colbster937/originblacklist/velocity/OriginBlacklistVelocity.java b/src/main/java/dev/colbster937/originblacklist/velocity/OriginBlacklistVelocity.java index ed6f89a..9ccf592 100644 --- a/src/main/java/dev/colbster937/originblacklist/velocity/OriginBlacklistVelocity.java +++ b/src/main/java/dev/colbster937/originblacklist/velocity/OriginBlacklistVelocity.java @@ -1,13 +1,16 @@ package dev.colbster937.originblacklist.velocity; import com.google.inject.Inject; +import com.velocitypowered.api.event.connection.PreLoginEvent; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.proxy.ProxyServer; import dev.colbster937.originblacklist.base.Base; +import net.kyori.adventure.text.Component; import net.lax1dude.eaglercraft.backend.server.api.velocity.EaglerXServerAPI; import net.lax1dude.eaglercraft.backend.server.api.velocity.event.EaglercraftLoginEvent; import net.lax1dude.eaglercraft.backend.server.api.velocity.event.EaglercraftMOTDEvent; +import java.net.InetAddress; import org.slf4j.Logger; public class OriginBlacklistVelocity { @@ -29,9 +32,9 @@ public class OriginBlacklistVelocity { @Subscribe public void onProxyInitialization(ProxyInitializeEvent event) { proxy.getPluginManager().getPlugin("eaglerxserver").ifPresentOrElse(plugin -> { - if (!Base.checkVer(plugin.getDescription().getVersion().orElse("1.0.0"), Base.apiVer)) { - logger.error("EaglerXServer " + Base.apiVer + " is required!"); - throw new RuntimeException("Incompatible api version"); + if (!Base.checkVer(plugin.getDescription().getVersion().orElse("1.0.0"), Base.pluginVer)) { + logger.error("EaglerXServer " + Base.pluginVer + " is required!"); + throw new RuntimeException("Incompatible plugin version"); } }, () -> { throw new RuntimeException("Missing EaglerXServer"); @@ -52,4 +55,14 @@ public class OriginBlacklistVelocity { public void onMOTD(EaglercraftMOTDEvent event) { Base.handleMOTD(event); } + + @Subscribe + public void onPreLogin(PreLoginEvent event) { + String ip = event.getConnection().getRemoteAddress().getAddress().toString(); + String name = event.getUsername(); + String blacklisted = Base.handlePre(ip, name); + if (!blacklisted.equals("false")) { + event.setResult(PreLoginEvent.PreLoginComponentResult.denied(Component.text(blacklisted))); + } + } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 7cbab23..9614249 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -3,11 +3,13 @@ messages: # - %blocked% - The player's origin/brand that was blocked # - %blocktype% - Shows what the player was blocked for # - %easyblocktype% - Shows what the player was blocked for in an eagler-kid readable form + # - %notallowed1% - Longer "not allowed" message + # - %notallowed2% - Shorter "not allowed" message # - %host% - The IP the player pinged # - %help% - The configured help message for the block type kick: | - This %easyblocktype% is not allowed on the server! + This %easyblocktype% is %notallowed1%! » %blocked% « %help% @@ -19,11 +21,12 @@ messages: help: generic: "Please switch to a different %easyblocktype%." player: "Please change your %easyblocktype%." + ip: "Please contact staff for assistance." motd: enabled: true text: | - This %easyblocktype% is not allowed! + This %easyblocktype% is %notallowed2%! » %blocked% « icon: "blacklisted.png" @@ -39,6 +42,8 @@ blacklist: - "*piclient*" players: - "Admin" + ips: + - "192.0.2.0/24" discord: webhook: "" @@ -61,9 +66,4 @@ discord: - - - - - -# :> +# :> \ No newline at end of file