diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java b/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java index 9739ff58..beb6a756 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java @@ -354,7 +354,8 @@ public class BytecodeViewer * @param name the file name * @return the file contents as a byte[] */ - public static byte[] getFileContents(String name) { + public static byte[] getFileContents(String name) + { for (FileContainer container : files) if (container.files.containsKey(name)) return container.files.get(name); @@ -369,15 +370,15 @@ public class BytecodeViewer * @return * @throws IOException */ - public static byte[] getClassFile(Class clazz) throws IOException { - try (InputStream is = clazz.getResourceAsStream( - "/" + clazz.getName().replace('.', '/') + ".class"); - ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + public static byte[] getClassFile(Class clazz) throws IOException + { + try (InputStream is = clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class"); + ByteArrayOutputStream baos = new ByteArrayOutputStream()) + { int r; byte[] buffer = new byte[8192]; - while ((r = Objects.requireNonNull(is).read(buffer)) >= 0) { + while ((r = Objects.requireNonNull(is).read(buffer)) >= 0) baos.write(buffer, 0, r); - } return baos.toByteArray(); } } @@ -390,10 +391,9 @@ public class BytecodeViewer */ public static void updateNode(ClassNode oldNode, ClassNode newNode) { - for (FileContainer container : files) { + for (FileContainer container : files) if (container.classes.remove(oldNode)) container.classes.add(newNode); - } } /** @@ -401,7 +401,8 @@ public class BytecodeViewer * * @return the loaded classes as an array list */ - public static ArrayList getLoadedClasses() { + public static ArrayList getLoadedClasses() + { ArrayList a = new ArrayList<>(); for (FileContainer container : files) @@ -433,7 +434,8 @@ public class BytecodeViewer * @param message if it should send a message saying it's compiled sucessfully. * @return true if no errors, false if it failed to compile. */ - public static boolean compile(boolean message, boolean successAlert) { + public static boolean compile(boolean message, boolean successAlert) + { BytecodeViewer.updateBusyStatus(true); boolean noErrors = true; boolean actuallyTried = false; @@ -483,7 +485,8 @@ public class BytecodeViewer * @param files the file(s) you wish to open * @param recentFiles if it should append to the recent files menu */ - public static void openFiles(final File[] files, boolean recentFiles) { + public static void openFiles(final File[] files, boolean recentFiles) + { if (recentFiles) { for (File f : files) @@ -504,7 +507,8 @@ public class BytecodeViewer * * @param file the file of the plugin */ - public static void startPlugin(File file) { + public static void startPlugin(File file) + { if (!file.exists()) { BytecodeViewer.showMessage("The plugin file " + file.getAbsolutePath() + " could not be found."); @@ -525,7 +529,8 @@ public class BytecodeViewer * * @param message the message you need to send */ - public static void showMessage(String message) { + public static void showMessage(String message) + { BetterJOptionPane.showMessageDialog(viewer, message); } @@ -590,6 +595,9 @@ public class BytecodeViewer tempF.mkdir(); } + /** + * Refreshes the title on all of the opened tabs + */ public static void refreshAllTabTitles() { for(int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++) @@ -598,92 +606,4 @@ public class BytecodeViewer viewer.refreshTitle(); } } - - /** - * Checks the hotkeys - * - * @param e - */ - public static void checkHotKey(KeyEvent e) { - if (System.currentTimeMillis() - Configuration.lastHotKeyExecuted <= (4000)) - return; - - if ((e.getKeyCode() == KeyEvent.VK_O) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) - { - Configuration.lastHotKeyExecuted = System.currentTimeMillis(); - - final File file = DialogueUtils.fileChooser("Select File or Folder to open in BCV", - "APKs, DEX, Class Files or Zip/Jar/War Archives", - Constants.SUPPORTED_FILE_EXTENSIONS); - - if(file == null) - return; - - BytecodeViewer.updateBusyStatus(true); - BytecodeViewer.openFiles(new File[]{file}, true); - BytecodeViewer.updateBusyStatus(false); - } else if ((e.getKeyCode() == KeyEvent.VK_N) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - Configuration.lastHotKeyExecuted = System.currentTimeMillis(); - BytecodeViewer.resetWorkspace(true); - } else if ((e.getKeyCode() == KeyEvent.VK_T) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - Configuration.lastHotKeyExecuted = System.currentTimeMillis(); - Thread t = new Thread(() -> BytecodeViewer.compile(true, false), "Compile"); - t.start(); - } else if ((e.getKeyCode() == KeyEvent.VK_R) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - Configuration.lastHotKeyExecuted = System.currentTimeMillis(); - if (BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - new RunOptions().setVisible(true); - } else if ((e.getKeyCode() == KeyEvent.VK_S) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - Configuration.lastHotKeyExecuted = System.currentTimeMillis(); - - if (BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - - Thread resourceExport = new Thread(() -> - { - if (BytecodeViewer.autoCompileSuccessful()) - return; - - JFileChooser fc = new FileChooser(Configuration.getLastDirectory(), - "Select Zip Export", - "Zip Archives", - "zip"); - - int returnVal = fc.showSaveDialog(viewer); - if (returnVal == JFileChooser.APPROVE_OPTION) - { - Configuration.lastDirectory = fc.getSelectedFile().getAbsolutePath(); - File file = fc.getSelectedFile(); - - if (!file.getAbsolutePath().endsWith(".zip")) - file = new File(file.getAbsolutePath() + ".zip"); - - if (!DialogueUtils.canOverwriteFile(file)) - return; - - final File file2 = file; - - BytecodeViewer.updateBusyStatus(true); - Thread jarExport = new Thread(() -> { - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), - file2.getAbsolutePath()); - BytecodeViewer.updateBusyStatus(false); - }, "Jar Export"); - jarExport.start(); - } - }, "Resource Export"); - resourceExport.start(); - } - else if ((e.getKeyCode() == KeyEvent.VK_W) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) - { - Configuration.lastHotKeyExecuted = System.currentTimeMillis(); - if (viewer.workPane.getCurrentViewer() != null) - viewer.workPane.tabs.remove(viewer.workPane.getCurrentViewer()); - } - } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/GlobalHotKeys.java b/src/main/java/the/bytecode/club/bytecodeviewer/GlobalHotKeys.java new file mode 100644 index 00000000..45217b66 --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/GlobalHotKeys.java @@ -0,0 +1,105 @@ +package the.bytecode.club.bytecodeviewer; + +import the.bytecode.club.bytecodeviewer.gui.components.FileChooser; +import the.bytecode.club.bytecodeviewer.gui.components.RunOptions; +import the.bytecode.club.bytecodeviewer.util.DialogueUtils; +import the.bytecode.club.bytecodeviewer.util.JarUtils; + +import javax.swing.*; +import java.awt.event.KeyEvent; +import java.io.File; + +/** + * Whenever a key is pressed on the swing UI it should get logged here + * + * @author Konloch + * @since 7/6/2021 + */ +public class GlobalHotKeys +{ + /** + * Checks the hotkeys + */ + public static void keyPressed(KeyEvent e) { + if (System.currentTimeMillis() - Configuration.lastHotKeyExecuted <= (4000)) + return; + + if ((e.getKeyCode() == KeyEvent.VK_O) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) + { + Configuration.lastHotKeyExecuted = System.currentTimeMillis(); + + final File file = DialogueUtils.fileChooser("Select File or Folder to open in BCV", + "APKs, DEX, Class Files or Zip/Jar/War Archives", + Constants.SUPPORTED_FILE_EXTENSIONS); + + if(file == null) + return; + + BytecodeViewer.updateBusyStatus(true); + BytecodeViewer.openFiles(new File[]{file}, true); + BytecodeViewer.updateBusyStatus(false); + } else if ((e.getKeyCode() == KeyEvent.VK_N) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { + Configuration.lastHotKeyExecuted = System.currentTimeMillis(); + BytecodeViewer.resetWorkspace(true); + } else if ((e.getKeyCode() == KeyEvent.VK_T) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { + Configuration.lastHotKeyExecuted = System.currentTimeMillis(); + Thread t = new Thread(() -> BytecodeViewer.compile(true, false), "Compile"); + t.start(); + } else if ((e.getKeyCode() == KeyEvent.VK_R) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { + Configuration.lastHotKeyExecuted = System.currentTimeMillis(); + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + new RunOptions().setVisible(true); + } else if ((e.getKeyCode() == KeyEvent.VK_S) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { + Configuration.lastHotKeyExecuted = System.currentTimeMillis(); + + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + Thread resourceExport = new Thread(() -> + { + if (BytecodeViewer.autoCompileSuccessful()) + return; + + JFileChooser fc = new FileChooser(Configuration.getLastDirectory(), + "Select Zip Export", + "Zip Archives", + "zip"); + + int returnVal = fc.showSaveDialog(BytecodeViewer.viewer); + if (returnVal == JFileChooser.APPROVE_OPTION) + { + Configuration.lastDirectory = fc.getSelectedFile().getAbsolutePath(); + File file = fc.getSelectedFile(); + + if (!file.getAbsolutePath().endsWith(".zip")) + file = new File(file.getAbsolutePath() + ".zip"); + + if (!DialogueUtils.canOverwriteFile(file)) + return; + + final File file2 = file; + + BytecodeViewer.updateBusyStatus(true); + Thread jarExport = new Thread(() -> { + JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), + file2.getAbsolutePath()); + BytecodeViewer.updateBusyStatus(false); + }, "Jar Export"); + jarExport.start(); + } + }, "Resource Export"); + resourceExport.start(); + } + else if ((e.getKeyCode() == KeyEvent.VK_W) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) + { + Configuration.lastHotKeyExecuted = System.currentTimeMillis(); + if (BytecodeViewer.viewer.workPane.getCurrentViewer() != null) + BytecodeViewer.viewer.workPane.tabs.remove(BytecodeViewer.viewer.workPane.getCurrentViewer()); + } + } +} diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/SearchableJTextArea.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/SearchableJTextArea.java index e0b14441..8fea293d 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/SearchableJTextArea.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/SearchableJTextArea.java @@ -1,6 +1,7 @@ package the.bytecode.club.bytecodeviewer.gui.components; import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.GlobalHotKeys; import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener; import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener; @@ -76,7 +77,7 @@ public class SearchableJTextArea extends JTextArea if ((keyEvent.getKeyCode() == KeyEvent.VK_F) && ((keyEvent.getModifiers() & KeyEvent.CTRL_MASK) != 0)) searchInput.requestFocus(); - BytecodeViewer.checkHotKey(keyEvent); + GlobalHotKeys.keyPressed(keyEvent); })); } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/SearchableRSyntaxTextArea.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/SearchableRSyntaxTextArea.java index 32bb4175..6d1cc377 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/SearchableRSyntaxTextArea.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/SearchableRSyntaxTextArea.java @@ -4,6 +4,7 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rtextarea.RTextScrollPane; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Configuration; +import the.bytecode.club.bytecodeviewer.GlobalHotKeys; import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener; import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener; @@ -98,7 +99,7 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea return; } - BytecodeViewer.checkHotKey(keyEvent); + GlobalHotKeys.keyPressed(keyEvent); })); } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/KeyEventDispatch.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/KeyEventDispatch.java index 12b4755d..d6527064 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/KeyEventDispatch.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/KeyEventDispatch.java @@ -1,6 +1,7 @@ package the.bytecode.club.bytecodeviewer.util; import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.GlobalHotKeys; import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea; import java.awt.*; @@ -23,7 +24,7 @@ public class KeyEventDispatch implements KeyEventDispatcher return false; } - BytecodeViewer.checkHotKey(e); + GlobalHotKeys.keyPressed(e); return false; } }