Global Hotkeys Cleanup

This commit is contained in:
Konloch 2021-07-06 16:08:08 -07:00
parent b99f6bf98a
commit e2a8857499
5 changed files with 133 additions and 105 deletions

View file

@ -354,7 +354,8 @@ public class BytecodeViewer
* @param name the file name * @param name the file name
* @return the file contents as a byte[] * @return the file contents as a byte[]
*/ */
public static byte[] getFileContents(String name) { public static byte[] getFileContents(String name)
{
for (FileContainer container : files) for (FileContainer container : files)
if (container.files.containsKey(name)) if (container.files.containsKey(name))
return container.files.get(name); return container.files.get(name);
@ -369,15 +370,15 @@ public class BytecodeViewer
* @return * @return
* @throws IOException * @throws IOException
*/ */
public static byte[] getClassFile(Class<?> clazz) throws IOException { public static byte[] getClassFile(Class<?> clazz) throws IOException
try (InputStream is = clazz.getResourceAsStream( {
"/" + clazz.getName().replace('.', '/') + ".class"); try (InputStream is = clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class");
ByteArrayOutputStream baos = new ByteArrayOutputStream()) { ByteArrayOutputStream baos = new ByteArrayOutputStream())
{
int r; int r;
byte[] buffer = new byte[8192]; 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); baos.write(buffer, 0, r);
}
return baos.toByteArray(); return baos.toByteArray();
} }
} }
@ -390,18 +391,18 @@ public class BytecodeViewer
*/ */
public static void updateNode(ClassNode oldNode, ClassNode newNode) public static void updateNode(ClassNode oldNode, ClassNode newNode)
{ {
for (FileContainer container : files) { for (FileContainer container : files)
if (container.classes.remove(oldNode)) if (container.classes.remove(oldNode))
container.classes.add(newNode); container.classes.add(newNode);
} }
}
/** /**
* Gets all of the loaded classes as an array list * Gets all of the loaded classes as an array list
* *
* @return the loaded classes as an array list * @return the loaded classes as an array list
*/ */
public static ArrayList<ClassNode> getLoadedClasses() { public static ArrayList<ClassNode> getLoadedClasses()
{
ArrayList<ClassNode> a = new ArrayList<>(); ArrayList<ClassNode> a = new ArrayList<>();
for (FileContainer container : files) for (FileContainer container : files)
@ -433,7 +434,8 @@ public class BytecodeViewer
* @param message if it should send a message saying it's compiled sucessfully. * @param message if it should send a message saying it's compiled sucessfully.
* @return true if no errors, false if it failed to compile. * @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); BytecodeViewer.updateBusyStatus(true);
boolean noErrors = true; boolean noErrors = true;
boolean actuallyTried = false; boolean actuallyTried = false;
@ -483,7 +485,8 @@ public class BytecodeViewer
* @param files the file(s) you wish to open * @param files the file(s) you wish to open
* @param recentFiles if it should append to the recent files menu * @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) if (recentFiles)
{ {
for (File f : files) for (File f : files)
@ -504,7 +507,8 @@ public class BytecodeViewer
* *
* @param file the file of the plugin * @param file the file of the plugin
*/ */
public static void startPlugin(File file) { public static void startPlugin(File file)
{
if (!file.exists()) if (!file.exists())
{ {
BytecodeViewer.showMessage("The plugin file " + file.getAbsolutePath() + " could not be found."); 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 * @param message the message you need to send
*/ */
public static void showMessage(String message) { public static void showMessage(String message)
{
BetterJOptionPane.showMessageDialog(viewer, message); BetterJOptionPane.showMessageDialog(viewer, message);
} }
@ -590,6 +595,9 @@ public class BytecodeViewer
tempF.mkdir(); tempF.mkdir();
} }
/**
* Refreshes the title on all of the opened tabs
*/
public static void refreshAllTabTitles() public static void refreshAllTabTitles()
{ {
for(int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++) for(int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++)
@ -598,92 +606,4 @@ public class BytecodeViewer
viewer.refreshTitle(); 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());
}
}
} }

View file

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

View file

@ -1,6 +1,7 @@
package the.bytecode.club.bytecodeviewer.gui.components; package the.bytecode.club.bytecodeviewer.gui.components;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.GlobalHotKeys;
import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener; import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener;
import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener; 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)) if ((keyEvent.getKeyCode() == KeyEvent.VK_F) && ((keyEvent.getModifiers() & KeyEvent.CTRL_MASK) != 0))
searchInput.requestFocus(); searchInput.requestFocus();
BytecodeViewer.checkHotKey(keyEvent); GlobalHotKeys.keyPressed(keyEvent);
})); }));
} }

View file

@ -4,6 +4,7 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rtextarea.RTextScrollPane; import org.fife.ui.rtextarea.RTextScrollPane;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Configuration; import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.GlobalHotKeys;
import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener; import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener;
import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener; import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener;
@ -98,7 +99,7 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea
return; return;
} }
BytecodeViewer.checkHotKey(keyEvent); GlobalHotKeys.keyPressed(keyEvent);
})); }));
} }

View file

@ -1,6 +1,7 @@
package the.bytecode.club.bytecodeviewer.util; package the.bytecode.club.bytecodeviewer.util;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.GlobalHotKeys;
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea; import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
import java.awt.*; import java.awt.*;
@ -23,7 +24,7 @@ public class KeyEventDispatch implements KeyEventDispatcher
return false; return false;
} }
BytecodeViewer.checkHotKey(e); GlobalHotKeys.keyPressed(e);
return false; return false;
} }
} }