From 09cfff5db057bab43a7215f35718ae56ad5b7787 Mon Sep 17 00:00:00 2001 From: Mars <49356012+7003Mars@users.noreply.github.com> Date: Mon, 6 Nov 2023 13:56:55 +0800 Subject: [PATCH 1/6] Anti bot measures? --- .../java/mindustry/plugin/PhoenixMain.java | 3 +- .../mindustry/plugin/minimods/NoBots.java | 126 ++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/main/java/mindustry/plugin/minimods/NoBots.java diff --git a/src/main/java/mindustry/plugin/PhoenixMain.java b/src/main/java/mindustry/plugin/PhoenixMain.java index d65601f..8016dac 100644 --- a/src/main/java/mindustry/plugin/PhoenixMain.java +++ b/src/main/java/mindustry/plugin/PhoenixMain.java @@ -78,7 +78,8 @@ public class PhoenixMain extends Plugin { new mindustry.plugin.minimods.Skipwave(), new mindustry.plugin.minimods.Translate(), new mindustry.plugin.minimods.Weapon(), - new mindustry.plugin.minimods.Sessions() + new mindustry.plugin.minimods.Sessions(), + new mindustry.plugin.minimods.NoBots() ); // register event handlers and create variables in the constructor diff --git a/src/main/java/mindustry/plugin/minimods/NoBots.java b/src/main/java/mindustry/plugin/minimods/NoBots.java new file mode 100644 index 0000000..2970552 --- /dev/null +++ b/src/main/java/mindustry/plugin/minimods/NoBots.java @@ -0,0 +1,126 @@ +package mindustry.plugin.minimods; + +import arc.Events; +import arc.files.Fi; +import arc.struct.IntSet; +import arc.util.Http; +import arc.util.Log; +import arc.util.Strings; +import arc.util.Time; +import arc.util.serialization.Jval; +import mindustry.Vars; +import mindustry.game.EventType.ConnectionEvent; +import mindustry.gen.Call; +import mindustry.gen.Groups; +import mindustry.net.NetConnection; +import mindustry.plugin.MiniMod; +import mindustry.plugin.database.Database; +import mindustry.plugin.discord.Roles; +import mindustry.plugin.discord.discordcommands.DiscordRegistrar; +import org.javacord.api.entity.message.MessageAttachment; + +import java.util.List; + +public class NoBots implements MiniMod { + Fi filePath = Vars.dataDirectory.child("mods").child("asn-ban.csv"); + public NoBots() { + // TODO: File path config + parseBlacklist(filePath); + } + + public static IntSet asnBlacklist = new IntSet(); + static IpChecker[] checkers = { + new IpChecker() { + long cooldownTime = 0; + @Override + public void check(String ip) { + if (Time.millis() < cooldownTime) { + checkers[1].check(ip); + return; + } + Log.info("Sending http://ip-api.com/json/@?fields=18432", ip); + Http.get("http://ip-api.com/json/"+ ip + "?fields=18432").submit(res -> { + if (Strings.parseInt(res.getHeader("X-Rl")) == 0) { + // Untested code above + cooldownTime = Time.millis() + Strings.parseInt(res.getHeader("X-Ttl")) * 1000L; + } + String asnString = Jval.read(res.getResultAsString()).getString("as"); + Log.info("Asn string: @", asnString); + int asn = Strings.parseInt(asnString.substring(2, asnString.indexOf(" "))); + Log.info("@, @", asn, asnBlacklist.contains(asn)); + if (asnBlacklist.contains(asn)) kickAll(ip); + }); + } + }, + ip -> { + Http.get("https://ipapi.co/" + ip + "/json").submit(res -> { + String asnString = Jval.read(res.getResultAsString()).getString("asn"); + int asn = Strings.parseInt(asnString.substring(2)); + if (asnBlacklist.contains(asn)) kickAll(ip); + }); + } + }; + + public static void kickAll(String ip) { + // TODO: Could be possible that player isn't created yet? + Vars.netServer.admins.blacklistDos(ip); + Groups.player.each(p -> { + if (p.con.address.equals(ip)) { + Call.kick(p.con, "This ip is blocked, try disabling any vpn\ndiscord.phoenix-network.dev"); + p.con.close(); + } + }); + } + + public static int parseBlacklist(Fi file) { + if (!file.exists()) { + Log.err("No asn blacklist file specified"); + return -1; + } + String[] asns = file.readString().split("\n"); + for (String line : asns) { + int end = line.indexOf(","); + if (end == -1) end = line.length(); + asnBlacklist.add(Strings.parseInt(line.substring(0, end))); + } + Log.info("Loaded a total of @ asns", asnBlacklist.size); + return asnBlacklist.size; + } + + + @Override + public void registerEvents() { + Events.on(ConnectionEvent.class, connectionEvent -> { + NetConnection con = connectionEvent.connection; + Database.Player pd = Database.getPlayerData(con.uuid); + if (pd != null && pd.verified) return; + checkers[0].check(con.address); + }); + } + + @Override + public void registerDiscordCommands(DiscordRegistrar handler) { + handler.register("update-asn", "", + data -> { + data.usage = ".csv file"; + data.roles = new long[]{Roles.ADMIN, Roles.MOD, Roles.APPRENTICE}; + }, + ctx -> { + List attachments = ctx.event.getMessageAttachments(); + if (attachments.size() != 1 || (!attachments.get(0).getFileName().endsWith("csv"))) { + ctx.error("Provide a csv file", ""); + } + attachments.get(0).downloadAsByteArray().thenAccept(b -> { + filePath.writeBytes(b); + int size = parseBlacklist(filePath); + ctx.success("Updated asn blacklist", "Size: " + size); + }); + }); + } +} + +@FunctionalInterface +interface IpChecker { + void check(String ip); +} + From dd8a7e01879c62402ba900f35c43f86257a4795f Mon Sep 17 00:00:00 2001 From: Mars <49356012+7003Mars@users.noreply.github.com> Date: Tue, 7 Nov 2023 21:25:52 +0800 Subject: [PATCH 2/6] Anti bot measures? v2 --- .../mindustry/plugin/minimods/NoBots.java | 110 +++++++----------- 1 file changed, 40 insertions(+), 70 deletions(-) diff --git a/src/main/java/mindustry/plugin/minimods/NoBots.java b/src/main/java/mindustry/plugin/minimods/NoBots.java index 2970552..92583bd 100644 --- a/src/main/java/mindustry/plugin/minimods/NoBots.java +++ b/src/main/java/mindustry/plugin/minimods/NoBots.java @@ -2,16 +2,13 @@ import arc.Events; import arc.files.Fi; -import arc.struct.IntSet; -import arc.util.Http; import arc.util.Log; +import arc.util.Reflect; import arc.util.Strings; -import arc.util.Time; -import arc.util.serialization.Jval; import mindustry.Vars; import mindustry.game.EventType.ConnectionEvent; import mindustry.gen.Call; -import mindustry.gen.Groups; +import mindustry.net.Net; import mindustry.net.NetConnection; import mindustry.plugin.MiniMod; import mindustry.plugin.database.Database; @@ -22,105 +19,78 @@ import java.util.List; public class NoBots implements MiniMod { - Fi filePath = Vars.dataDirectory.child("mods").child("asn-ban.csv"); + Fi filePath = Vars.dataDirectory.child("mods").child("ipv4.txt"); + static int[] ips; + static short[] masks; public NoBots() { - // TODO: File path config parseBlacklist(filePath); } - public static IntSet asnBlacklist = new IntSet(); - static IpChecker[] checkers = { - new IpChecker() { - long cooldownTime = 0; - @Override - public void check(String ip) { - if (Time.millis() < cooldownTime) { - checkers[1].check(ip); - return; - } - Log.info("Sending http://ip-api.com/json/@?fields=18432", ip); - Http.get("http://ip-api.com/json/"+ ip + "?fields=18432").submit(res -> { - if (Strings.parseInt(res.getHeader("X-Rl")) == 0) { - // Untested code above - cooldownTime = Time.millis() + Strings.parseInt(res.getHeader("X-Ttl")) * 1000L; - } - String asnString = Jval.read(res.getResultAsString()).getString("as"); - Log.info("Asn string: @", asnString); - int asn = Strings.parseInt(asnString.substring(2, asnString.indexOf(" "))); - Log.info("@, @", asn, asnBlacklist.contains(asn)); - if (asnBlacklist.contains(asn)) kickAll(ip); - }); - } - }, - ip -> { - Http.get("https://ipapi.co/" + ip + "/json").submit(res -> { - String asnString = Jval.read(res.getResultAsString()).getString("asn"); - int asn = Strings.parseInt(asnString.substring(2)); - if (asnBlacklist.contains(asn)) kickAll(ip); - }); - } - }; - - public static void kickAll(String ip) { - // TODO: Could be possible that player isn't created yet? - Vars.netServer.admins.blacklistDos(ip); - Groups.player.each(p -> { - if (p.con.address.equals(ip)) { - Call.kick(p.con, "This ip is blocked, try disabling any vpn\ndiscord.phoenix-network.dev"); - p.con.close(); - } - }); - } - public static int parseBlacklist(Fi file) { if (!file.exists()) { - Log.err("No asn blacklist file specified"); + Log.err("No ip blacklist file specified"); return -1; } - String[] asns = file.readString().split("\n"); - for (String line : asns) { - int end = line.indexOf(","); - if (end == -1) end = line.length(); - asnBlacklist.add(Strings.parseInt(line.substring(0, end))); + String[] lines = file.readString().split("\n"); + ips = new int[lines.length]; + masks = new short[lines.length]; + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + int slash = line.indexOf('/'); + String subnet = line.substring(0, slash); + int maskBits = 32-Strings.parseInt(line.substring(slash+1)); + ips[i] = convertIp(subnet) >>> maskBits; + masks[i] = (short) maskBits; } - Log.info("Loaded a total of @ asns", asnBlacklist.size); - return asnBlacklist.size; + + Log.info("Loaded a total of @ ips", ips.length); + return ips.length; } @Override public void registerEvents() { Events.on(ConnectionEvent.class, connectionEvent -> { + // The code is probably blocking and a long db query could tank tps NetConnection con = connectionEvent.connection; Database.Player pd = Database.getPlayerData(con.uuid); if (pd != null && pd.verified) return; - checkers[0].check(con.address); + int ip = convertIp(con.address); + for (int i = 0; i < ips.length; i++) { + if (ips[i] == (ip >>> masks[i])) { + Call.kick(con, "This ip is blocked, try disabling any vpn\ndiscord.phoenix-network.dev"); + con.close(); + return; + } + } }); } @Override public void registerDiscordCommands(DiscordRegistrar handler) { - handler.register("update-asn", "", + handler.register("update-ip-blacklist", "", data -> { - data.usage = ".csv file"; + data.usage = ".txt file"; data.roles = new long[]{Roles.ADMIN, Roles.MOD, Roles.APPRENTICE}; }, ctx -> { List attachments = ctx.event.getMessageAttachments(); - if (attachments.size() != 1 || (!attachments.get(0).getFileName().endsWith("csv"))) { - ctx.error("Provide a csv file", ""); + if (attachments.size() != 1 || (!attachments.get(0).getFileName().endsWith("txt"))) { + ctx.error("Provide a txt file", ""); } attachments.get(0).downloadAsByteArray().thenAccept(b -> { filePath.writeBytes(b); int size = parseBlacklist(filePath); - ctx.success("Updated asn blacklist", "Size: " + size); + ctx.success("Updated ip blacklist", "Size: " + size); }); }); } -} -@FunctionalInterface -interface IpChecker { - void check(String ip); + static int convertIp(String ip) { + int d1 = ip.indexOf('.'), d2 = ip.indexOf('.', d1+1), d3 = ip.indexOf('.', d2+1); + return Strings.parseInt(ip, 10, 0, d3+1, ip.length()) | + Strings.parseInt(ip, 10, 0, d2+1, d3) << 8 | + Strings.parseInt(ip, 10, 0, d1+1, d2) << 16 | + Strings.parseInt(ip, 10, 0, 0, d1) << 24; + } } - From 36a8e0458c7995fe5c57a8e9fba063369ddde33f Mon Sep 17 00:00:00 2001 From: Mars <49356012+7003Mars@users.noreply.github.com> Date: Sun, 19 Nov 2023 16:55:46 +0800 Subject: [PATCH 3/6] Better parsing --- src/main/java/mindustry/plugin/minimods/NoBots.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/mindustry/plugin/minimods/NoBots.java b/src/main/java/mindustry/plugin/minimods/NoBots.java index 92583bd..5b0e2bc 100644 --- a/src/main/java/mindustry/plugin/minimods/NoBots.java +++ b/src/main/java/mindustry/plugin/minimods/NoBots.java @@ -31,12 +31,18 @@ public static int parseBlacklist(Fi file) { Log.err("No ip blacklist file specified"); return -1; } + Log.info("Parsing blacklist file..."); String[] lines = file.readString().split("\n"); ips = new int[lines.length]; masks = new short[lines.length]; for (int i = 0; i < lines.length; i++) { String line = lines[i]; + if (line.startsWith("#")) continue; int slash = line.indexOf('/'); + if (slash == -1) { + Log.warn("Line at @ has no mask: @\n Consider adding a /0 if you wish to block that specific ip", i, line); + continue; + } String subnet = line.substring(0, slash); int maskBits = 32-Strings.parseInt(line.substring(slash+1)); ips[i] = convertIp(subnet) >>> maskBits; From ddcb2e4b8d74c03926bb3e91b791e8fc1cab3c2d Mon Sep 17 00:00:00 2001 From: Mars <49356012+7003Mars@users.noreply.github.com> Date: Sun, 19 Nov 2023 17:06:16 +0800 Subject: [PATCH 4/6] Wrong event oops --- src/main/java/mindustry/plugin/minimods/NoBots.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/mindustry/plugin/minimods/NoBots.java b/src/main/java/mindustry/plugin/minimods/NoBots.java index 5b0e2bc..0789624 100644 --- a/src/main/java/mindustry/plugin/minimods/NoBots.java +++ b/src/main/java/mindustry/plugin/minimods/NoBots.java @@ -3,12 +3,10 @@ import arc.Events; import arc.files.Fi; import arc.util.Log; -import arc.util.Reflect; import arc.util.Strings; import mindustry.Vars; -import mindustry.game.EventType.ConnectionEvent; +import mindustry.game.EventType.ConnectPacketEvent; import mindustry.gen.Call; -import mindustry.net.Net; import mindustry.net.NetConnection; import mindustry.plugin.MiniMod; import mindustry.plugin.database.Database; @@ -56,7 +54,7 @@ public static int parseBlacklist(Fi file) { @Override public void registerEvents() { - Events.on(ConnectionEvent.class, connectionEvent -> { + Events.on(ConnectPacketEvent.class, connectionEvent -> { // The code is probably blocking and a long db query could tank tps NetConnection con = connectionEvent.connection; Database.Player pd = Database.getPlayerData(con.uuid); From b82414c73767f93fd2840cab61ee5c1a8ede7496 Mon Sep 17 00:00:00 2001 From: Mars <49356012+7003Mars@users.noreply.github.com> Date: Sun, 19 Nov 2023 17:23:40 +0800 Subject: [PATCH 5/6] idior --- src/main/java/mindustry/plugin/minimods/NoBots.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/mindustry/plugin/minimods/NoBots.java b/src/main/java/mindustry/plugin/minimods/NoBots.java index 0789624..a0f26f0 100644 --- a/src/main/java/mindustry/plugin/minimods/NoBots.java +++ b/src/main/java/mindustry/plugin/minimods/NoBots.java @@ -63,6 +63,7 @@ public void registerEvents() { for (int i = 0; i < ips.length; i++) { if (ips[i] == (ip >>> masks[i])) { Call.kick(con, "This ip is blocked, try disabling any vpn\ndiscord.phoenix-network.dev"); + con.kicked = true; con.close(); return; } From ed731ed80c2ae4e43fb0e3adf9104e754c03247a Mon Sep 17 00:00:00 2001 From: Mars <49356012+7003Mars@users.noreply.github.com> Date: Sun, 19 Nov 2023 18:29:00 +0800 Subject: [PATCH 6/6] idior --- src/main/java/mindustry/plugin/minimods/NoBots.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/mindustry/plugin/minimods/NoBots.java b/src/main/java/mindustry/plugin/minimods/NoBots.java index a0f26f0..dd16d46 100644 --- a/src/main/java/mindustry/plugin/minimods/NoBots.java +++ b/src/main/java/mindustry/plugin/minimods/NoBots.java @@ -62,12 +62,16 @@ public void registerEvents() { int ip = convertIp(con.address); for (int i = 0; i < ips.length; i++) { if (ips[i] == (ip >>> masks[i])) { +// REMOVEME +// Log.err("Block @", con.address); Call.kick(con, "This ip is blocked, try disabling any vpn\ndiscord.phoenix-network.dev"); + con.kick(); con.kicked = true; con.close(); return; } } + Log.info("Ip not blocked: @",con.address); }); }