Tabbed Console
A better solution to the plugin console for when you have multiple resources inside of BCV
This commit is contained in:
parent
3e82f29b59
commit
ced48c76fd
8 changed files with 174 additions and 25 deletions
|
@ -86,7 +86,6 @@ import static the.bytecode.club.bytecodeviewer.util.MiscUtils.guessLanguage;
|
|||
* + Fix hook inject for EZ-Injection
|
||||
*
|
||||
* TODO FEATURES:
|
||||
* + Console Plugin needs tabbed consoles instead of creating a new window for each console
|
||||
* + CLI Headless needs to be supported
|
||||
* + Add stackmapframes to bytecode decompiler
|
||||
* + Add JEB decompiler optionally, requires them to add jeb library jar
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package the.bytecode.club.bytecodeviewer.api;
|
||||
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.SystemConsole;
|
||||
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
|
||||
|
||||
/***************************************************************************
|
||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||
|
@ -28,10 +29,24 @@ import the.bytecode.club.bytecodeviewer.gui.components.SystemConsole;
|
|||
|
||||
public class PluginConsole extends SystemConsole
|
||||
{
|
||||
private boolean showWindow;
|
||||
|
||||
public PluginConsole(String pluginName)
|
||||
{
|
||||
super("Bytecode Viewer - Plugin Console - " + pluginName);
|
||||
|
||||
PluginManager.addConsole(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b)
|
||||
{
|
||||
//do nothing
|
||||
if(!showWindow)
|
||||
return;
|
||||
|
||||
super.setVisible(b);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -6556940545421437508L;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.components;
|
||||
|
||||
import me.konloch.kontainer.io.DiskWriter;
|
||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||
import the.bytecode.club.bytecodeviewer.Constants;
|
||||
import the.bytecode.club.bytecodeviewer.resources.IconResources;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.Constants.fs;
|
||||
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -38,14 +35,17 @@ import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
|
|||
*/
|
||||
public class JFrameConsole extends JFrame
|
||||
{
|
||||
private final SearchableJTextArea textArea = new SearchableJTextArea();
|
||||
private String containerName;
|
||||
private int consoleID;
|
||||
private final SearchableJTextArea textArea;
|
||||
|
||||
public JFrameConsole(String title)
|
||||
{
|
||||
this.setIconImages(IconResources.iconList);
|
||||
setIconImages(IconResources.iconList);
|
||||
setTitle(title);
|
||||
setSize(new Dimension(542, 316));
|
||||
|
||||
textArea = new SearchableJTextArea();
|
||||
getContentPane().add(textArea.getScrollPane(), BorderLayout.CENTER);
|
||||
|
||||
this.setLocationRelativeTo(null);
|
||||
|
@ -71,33 +71,78 @@ public class JFrameConsole extends JFrame
|
|||
*/
|
||||
public void setText(String t)
|
||||
{
|
||||
textArea.setText(trim(t));
|
||||
textArea.setText(trimConsoleText(t));
|
||||
textArea.setCaretPosition(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SearchableJTextArea pane
|
||||
*/
|
||||
public SearchableJTextArea getTextArea()
|
||||
{
|
||||
return textArea;
|
||||
}
|
||||
|
||||
public String trim(String s)
|
||||
/**
|
||||
* Returns the console ID
|
||||
*/
|
||||
public int getConsoleID()
|
||||
{
|
||||
return consoleID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current container name
|
||||
*/
|
||||
public String getContainerName()
|
||||
{
|
||||
return containerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the console ID
|
||||
*/
|
||||
public void setConsoleID(int consoleID)
|
||||
{
|
||||
this.consoleID = consoleID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the container name
|
||||
*/
|
||||
public void setContainerName(String containerName)
|
||||
{
|
||||
this.containerName = containerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the console text to prevent killing the swing thread
|
||||
*/
|
||||
public String trimConsoleText(final String s)
|
||||
{
|
||||
int len = s.length();
|
||||
int max = 500_000; //TODO this can be increased to 1,000,000 the lower number was chosen to be safe
|
||||
|
||||
//TODO this should also be a setting eventually
|
||||
int max = 500_000;
|
||||
if(len >= max)
|
||||
{
|
||||
//TODO if two consoles are ran at the same time and exceed the maximum this file will be overwritten
|
||||
|
||||
//save to disk
|
||||
File tempFile = new File(tempDirectory+fs+"console.log");
|
||||
DiskWriter.replaceFile(tempFile.getAbsolutePath(), s, false);
|
||||
final File tempFile = new File(tempDirectory, "console_" + consoleID + ".log");
|
||||
new Thread(()->
|
||||
{
|
||||
//save to disk
|
||||
DiskWriter.replaceFile(tempFile.getAbsolutePath(), s, false);
|
||||
}, "Console Log Saving").start();
|
||||
|
||||
//trim
|
||||
int skipped = len - max;
|
||||
s = s.substring(0, max);
|
||||
s = ("Skipping " + skipped + " chars, allowing " + max + "\n\r")
|
||||
+ "Full log saved to: " + tempFile.getAbsolutePath() + "\n\r"
|
||||
+ s;
|
||||
String trimmed = s.substring(0, max);
|
||||
trimmed = ("WARNING: Skipping " + skipped + " chars, allowing " + max + "\n\r")
|
||||
+ "Full log saved to: " + tempFile.getAbsolutePath() + "\n\r\n\r"
|
||||
+ trimmed;
|
||||
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
return s;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.components;
|
||||
|
||||
import the.bytecode.club.bytecodeviewer.resources.IconResources;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/***************************************************************************
|
||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 7/14/2021
|
||||
*/
|
||||
|
||||
public class JFrameConsoleTabbed extends JFrame
|
||||
{
|
||||
private final JTabbedPane tabbedPane;
|
||||
|
||||
public JFrameConsoleTabbed(String title)
|
||||
{
|
||||
setIconImages(IconResources.iconList);
|
||||
setTitle(title);
|
||||
setSize(new Dimension(542, 316));
|
||||
|
||||
tabbedPane = new JTabbedPane();
|
||||
getContentPane().add(tabbedPane, BorderLayout.CENTER);
|
||||
|
||||
this.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
public void addConsole(Component console, String containerName)
|
||||
{
|
||||
tabbedPane.add(console, containerName);
|
||||
}
|
||||
}
|
|
@ -18,8 +18,6 @@ package the.bytecode.club.bytecodeviewer.gui.components;
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***************************************************************************/
|
||||
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
|
||||
/**
|
||||
* A simple console GUI.
|
||||
*
|
||||
|
|
|
@ -301,7 +301,7 @@ public class ResourceListPane extends TranslatedVisibleComponent implements File
|
|||
if (c.name.equals(cheapHax))
|
||||
container = c;
|
||||
}
|
||||
|
||||
|
||||
String name = nameBuffer.toString();
|
||||
|
||||
//TODO add file header check
|
||||
|
@ -311,13 +311,13 @@ public class ResourceListPane extends TranslatedVisibleComponent implements File
|
|||
name.substring(0, name.length() - ".class".length()));
|
||||
|
||||
if (cn != null)
|
||||
BytecodeViewer.viewer.workPane.addClassResource(container, nameBuffer.toString());
|
||||
BytecodeViewer.viewer.workPane.addClassResource(container, name);
|
||||
else
|
||||
BytecodeViewer.viewer.workPane.addFileResource(container, nameBuffer.toString());
|
||||
BytecodeViewer.viewer.workPane.addFileResource(container, name);
|
||||
}
|
||||
else
|
||||
else if(container.resourceFiles.containsKey(name))
|
||||
{
|
||||
BytecodeViewer.viewer.workPane.addFileResource(container, nameBuffer.toString());
|
||||
BytecodeViewer.viewer.workPane.addFileResource(container, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ public class TabRemovalEvent implements ContainerListener
|
|||
public void componentRemoved(ContainerEvent e)
|
||||
{
|
||||
final Component c = e.getChild();
|
||||
|
||||
if(!(c instanceof ResourceViewer))
|
||||
return;
|
||||
|
||||
String workingName = ((ResourceViewer) c).resource.workingName;
|
||||
BytecodeViewer.viewer.workPane.openedTabs.remove(workingName);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.util.*;
|
|||
import javax.swing.filechooser.FileFilter;
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.api.Plugin;
|
||||
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsoleTabbed;
|
||||
import the.bytecode.club.bytecodeviewer.plugin.strategies.*;
|
||||
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
||||
|
||||
|
@ -35,11 +37,20 @@ import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
|||
* @author Bibl
|
||||
* @since 01/16/16, 14:36, Adaptable PluginLaunchStrategy system.
|
||||
*/
|
||||
public final class PluginManager {
|
||||
|
||||
public final class PluginManager
|
||||
{
|
||||
private static final Map<String, PluginLaunchStrategy> launchStrategies = new HashMap<>();
|
||||
private static final PluginFileFilter filter = new PluginFileFilter();
|
||||
private static List<Plugin> pluginInstances = new ArrayList<>();
|
||||
|
||||
//TODO this system needs to be redone, currently it will conflict if more than one plugin is ran at the same time
|
||||
// the solution is to tie the plugin object into the plugin console,
|
||||
// then move all of this into the plugin class as non-static objects
|
||||
|
||||
private static Plugin activePlugin;
|
||||
private static JFrameConsoleTabbed activeTabbedConsole;
|
||||
private static int consoleCount = 0;
|
||||
|
||||
static
|
||||
{
|
||||
|
@ -67,6 +78,15 @@ public final class PluginManager {
|
|||
*/
|
||||
public static void runPlugin(Plugin newPluginInstance)
|
||||
{
|
||||
//reset the console count
|
||||
consoleCount = 0;
|
||||
|
||||
//reset the active tabbed console
|
||||
activeTabbedConsole = null;
|
||||
|
||||
//reset the active plugin
|
||||
activePlugin = newPluginInstance;
|
||||
|
||||
//clean the plugin list from dead threads
|
||||
pluginInstances.removeIf(Plugin::isFinished);
|
||||
|
||||
|
@ -96,6 +116,23 @@ public final class PluginManager {
|
|||
if (p != null)
|
||||
runPlugin(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an active console from a plugin being ran
|
||||
*/
|
||||
public static void addConsole(PluginConsole console)
|
||||
{
|
||||
int id = consoleCount++;
|
||||
|
||||
if(activeTabbedConsole == null)
|
||||
{
|
||||
activeTabbedConsole = new JFrameConsoleTabbed(console.getTitle());
|
||||
activeTabbedConsole.setVisible(true);
|
||||
}
|
||||
|
||||
console.setConsoleID(id);
|
||||
activeTabbedConsole.addConsole(console.getComponent(0), activePlugin.activeContainer.name);
|
||||
}
|
||||
|
||||
public static void register(String name, PluginLaunchStrategy strat) {
|
||||
launchStrategies.put(name, strat);
|
||||
|
|
Loading…
Reference in a new issue