From d0f7cb0d8aaf443ee1138e21e3fec741955a4a99 Mon Sep 17 00:00:00 2001 From: Cloudburst Date: Thu, 3 Jun 2021 19:24:12 +0200 Subject: [PATCH] added .server ports --- .../rejects/MeteorRejectsAddon.java | 1 + .../rejects/commands/ServerCommand.java | 149 ++++++++++++++++++ .../utils/portscanner/PScanRunner.java | 66 ++++++++ .../utils/portscanner/PortScannerManager.java | 45 ++++++ 4 files changed, 261 insertions(+) create mode 100644 src/main/java/cloudburst/rejects/commands/ServerCommand.java create mode 100644 src/main/java/cloudburst/rejects/utils/portscanner/PScanRunner.java create mode 100644 src/main/java/cloudburst/rejects/utils/portscanner/PortScannerManager.java diff --git a/src/main/java/cloudburst/rejects/MeteorRejectsAddon.java b/src/main/java/cloudburst/rejects/MeteorRejectsAddon.java index 7ca18fc..b258cec 100644 --- a/src/main/java/cloudburst/rejects/MeteorRejectsAddon.java +++ b/src/main/java/cloudburst/rejects/MeteorRejectsAddon.java @@ -48,6 +48,7 @@ public class MeteorRejectsAddon extends MeteorAddon { commands.add(new BookDupeCommand()); commands.add(new GiveCommand()); commands.add(new SaveSkinCommand()); + commands.add(new ServerCommand()); commands.add(new SetBlockCommand()); commands.add(new TeleportCommand()); commands.add(new TerrainExport()); diff --git a/src/main/java/cloudburst/rejects/commands/ServerCommand.java b/src/main/java/cloudburst/rejects/commands/ServerCommand.java new file mode 100644 index 0000000..ff77d11 --- /dev/null +++ b/src/main/java/cloudburst/rejects/commands/ServerCommand.java @@ -0,0 +1,149 @@ +package cloudburst.rejects.commands; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; + +import net.minecraft.client.network.ServerInfo; +import net.minecraft.command.CommandSource; +import net.minecraft.text.BaseText; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.HoverEvent; +import net.minecraft.text.LiteralText; +import net.minecraft.text.ClickEvent.Action; +import net.minecraft.util.Formatting; + +import cloudburst.rejects.utils.portscanner.PScanRunner; +import cloudburst.rejects.utils.portscanner.PortScannerManager; +import minegame159.meteorclient.systems.commands.Command; + +import static com.mojang.brigadier.Command.SINGLE_SUCCESS; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import com.mojang.brigadier.arguments.IntegerArgumentType; + +public class ServerCommand extends Command { + + private final static SimpleCommandExceptionType ADDRESS_ERROR = new SimpleCommandExceptionType(new LiteralText("Couldn't obtain server address")); + private final static SimpleCommandExceptionType INVALID_RANGE = new SimpleCommandExceptionType(new LiteralText("Invalid range")); + + private final static HashMap ports = new HashMap(); + + public ServerCommand() { + super("server", "Prints server information"); + + ports.put(20, "FTP"); + ports.put(22, "SSH"); + ports.put(80, "HTTP"); + ports.put(443, "HTTPS"); + ports.put(25565, "Java Server"); + ports.put(25575, "Java Server RCON"); + ports.put(19132, "Bedrock Server"); + ports.put(19133, "Bedrock Server IPv6"); + ports.put(8123, "DynMap"); + ports.put(25566, "Minequery"); + ports.put(3306, "MySQL"); + } + + @Override + public void build(LiteralArgumentBuilder builder) { + builder.then(literal("ports").executes(ctx -> { + scanKnownPorts(getAddress()); + return SINGLE_SUCCESS; + })); + builder.then(literal("ports").then(literal("known").executes(ctx -> { + scanKnownPorts(getAddress()); + return SINGLE_SUCCESS; + }))); + builder.then(literal("ports").then(argument("from", IntegerArgumentType.integer(0)).then(argument("to", IntegerArgumentType.integer(1)).executes(ctx -> { + scanRange(getAddress(), IntegerArgumentType.getInteger(ctx, "from"), + IntegerArgumentType.getInteger(ctx, "to")); + return SINGLE_SUCCESS; + })))); + } + + private InetAddress getAddress() throws CommandSyntaxException { + if (mc.isIntegratedServerRunning()) { + try { + return InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + throw ADDRESS_ERROR.create(); + } + } + else { + ServerInfo server = mc.getCurrentServerEntry(); + if (server == null) throw ADDRESS_ERROR.create(); + try { + return InetAddress.getByName(server.address); + } catch (UnknownHostException e) { + throw ADDRESS_ERROR.create(); + } + } + } + + private void scanPorts(InetAddress address, Collection port_list){ + info("Started scanning %d ports", port_list.size()); + PScanRunner pScanRunner = new PScanRunner(address, 5, 3, 200, port_list, scanResults -> { + int open_ports = 0; + info("Open ports:"); + for (PortScannerManager.ScanResult result : scanResults) { + if (result.isOpen()) { + info(formatPort(result.getPort(), address)); + open_ports++; + } + } + info("Open count: %d/%d", open_ports, scanResults.size()); + }); + PortScannerManager.scans.add(pScanRunner); + } + + private void scanKnownPorts(InetAddress address) { + scanPorts(address, ports.keySet()); + } + + private void scanRange(InetAddress address, int min, int max) throws CommandSyntaxException { + if (max port_list = new LinkedList<>(); + for (int i = min; i <= max; i++) port_list.add(i); + scanPorts(address, port_list); + } + + private BaseText formatPort(int port, InetAddress address) { + BaseText text = new LiteralText(String.format("- %s%d%s ", Formatting.GREEN, port, Formatting.GRAY)); + if (ports.containsKey(port)) { + text.append(ports.get(port)); + if (ports.get(port).startsWith("HTTP")) { + text.setStyle(text.getStyle() + .withClickEvent(new ClickEvent( + Action.OPEN_URL, + String.format("%s://%s:%d", ports.get(port).toLowerCase(), address.getHostAddress(), port) + )) + .withHoverEvent(new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new LiteralText("Open in browser") + )) + ); + } + else if (ports.get(port) == "DynMap") { + text.setStyle(text.getStyle() + .withClickEvent(new ClickEvent( + ClickEvent.Action.OPEN_URL, + String.format("http://%s:%d", address.getHostAddress(), port) + )) + .withHoverEvent(new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new LiteralText("Open in browser") + )) + ); + } + } + + return text; + } +} diff --git a/src/main/java/cloudburst/rejects/utils/portscanner/PScanRunner.java b/src/main/java/cloudburst/rejects/utils/portscanner/PScanRunner.java new file mode 100644 index 0000000..ced6874 --- /dev/null +++ b/src/main/java/cloudburst/rejects/utils/portscanner/PScanRunner.java @@ -0,0 +1,66 @@ +package cloudburst.rejects.utils.portscanner; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.*; +import java.util.function.Consumer; + +public class PScanRunner { + public boolean running = true; + public int portsScanned = 0; + ExecutorService es; + List> futures = new ArrayList<>(); + Thread runner; + + public PScanRunner(InetAddress address, int threads, int threadDelay, int timeoutMS, Collection ports, + Consumer> callback) { + runner = new Thread(() -> { + es = Executors.newFixedThreadPool(threads); + ports.forEach(port -> { + futures.add(isPortOpen(es, address.getHostAddress(), port, timeoutMS, threadDelay)); + }); + try { + boolean _1 = es.awaitTermination(200L, TimeUnit.MILLISECONDS); + } catch (InterruptedException ignored) { + } + List results = new ArrayList<>(); + for (Future fsc : futures) { + try { + results.add(fsc.get()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + } + callback.accept(results); + }); + runner.start(); + } + + public void cancel() { + running = false; + } + + private Future isPortOpen(ExecutorService es, String ip, int port, int timeout, + int delay) { + return es.submit(() -> { + if (!running) + return new PortScannerManager.ScanResult(port, false); + Thread.sleep(delay); + portsScanned++; + try { + //System.out.println(ip + ":" + port); + Socket socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), timeout); + socket.close(); + return new PortScannerManager.ScanResult(port, true); + } catch (Exception exc) { + + return new PortScannerManager.ScanResult(port, false); + } + }); + } +} diff --git a/src/main/java/cloudburst/rejects/utils/portscanner/PortScannerManager.java b/src/main/java/cloudburst/rejects/utils/portscanner/PortScannerManager.java new file mode 100644 index 0000000..3b7cf76 --- /dev/null +++ b/src/main/java/cloudburst/rejects/utils/portscanner/PortScannerManager.java @@ -0,0 +1,45 @@ +package cloudburst.rejects.utils.portscanner; + +import java.util.ArrayList; +import java.util.List; + +public class PortScannerManager { + public static List scans = new ArrayList<>(); + + public static void killAllScans() { + for (PScanRunner runner : scans) { + if (runner.running) + runner.cancel(); + } + scans.clear(); + } + + public static class ScanResult { + private int port; + + private boolean isOpen; + + public ScanResult(int port, boolean isOpen) { + super(); + this.port = port; + this.isOpen = isOpen; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public boolean isOpen() { + return isOpen; + } + + public void setOpen(boolean isOpen) { + this.isOpen = isOpen; + } + + } +}