parent
5603f466b3
commit
2314af5f7f
5 changed files with 135 additions and 120 deletions
|
@ -72,29 +72,31 @@ import static the.bytecode.club.bytecodeviewer.Constants.*;
|
|||
* http://the.bytecode.club
|
||||
*
|
||||
* TODO BUGS:
|
||||
* Spam-clicking the refresh button will cause the swing thread to deadlock (Quickly opening resources used to also do this)
|
||||
* + Tab simplified titles aren't working correctly until refreshed
|
||||
* + Synchronized scrolling is broken
|
||||
* + Spam-clicking the refresh button will cause the swing thread to deadlock (Quickly opening resources used to also do this)
|
||||
* This is caused by the ctrlMouseWheelZoom code, a temporary patch is just removing it worst case
|
||||
* Open as folder doesn't actually work
|
||||
* Fix classfile searcher
|
||||
* Smali Assembly compile - Needs to be fixed
|
||||
* Krakatau Assembly compile - Needs to be fixed
|
||||
* + Open as folder doesn't actually work
|
||||
* + Fix classfile searcher
|
||||
* + Smali Assembly compile - Needs to be fixed
|
||||
* + Krakatau Assembly compile - Needs to be fixed
|
||||
*
|
||||
* TODO IN-PROGRESS:
|
||||
* Finish dragging code
|
||||
* Finish right-click tab menu detection
|
||||
* Fix hook inject for EZ-Injection
|
||||
* + Finish dragging code
|
||||
* + Finish right-click tab menu detection
|
||||
* + Fix hook inject for EZ-Injection
|
||||
*
|
||||
* TODO FEATURES:
|
||||
* Add stackmapframes to bytecode decompiler
|
||||
* Add JEB decompiler optionally, requires them to add jeb library jar
|
||||
* Add https://github.com/ptnkjke/Java-Bytecode-Editor visualize as a plugin
|
||||
* Add https://github.com/exbin/bined as the replacement Hed Viewer/Editor
|
||||
* Make the decompilers launch in a separate process
|
||||
* Make it use that global last used inside of export as jar
|
||||
* Make zipfile not include the decode shit
|
||||
* Make ez-injection plugin console show all sys.out calls
|
||||
* Add decompile as zip for krakatau-bytecode, jd-gui and smali for CLI
|
||||
* Add decompile all as zip for CLI
|
||||
* + Add stackmapframes to bytecode decompiler
|
||||
* + Add JEB decompiler optionally, requires them to add jeb library jar
|
||||
* + Add https://github.com/ptnkjke/Java-Bytecode-Editor visualize as a plugin
|
||||
* + Add https://github.com/exbin/bined as the replacement Hed Viewer/Editor
|
||||
* + Make the decompilers launch in a separate process
|
||||
* + Make it use that global last used inside of export as jar
|
||||
* + Make zipfile not include the decode shit
|
||||
* + Make ez-injection plugin console show all sys.out calls
|
||||
* + Add decompile as zip for krakatau-bytecode, jd-gui and smali for CLI
|
||||
* + Add decompile all as zip for CLI
|
||||
*
|
||||
* @author Konloch
|
||||
* @author The entire BCV community
|
||||
|
@ -235,7 +237,7 @@ public class BytecodeViewer
|
|||
}));
|
||||
|
||||
viewer.calledAfterLoad();
|
||||
resetRecentFilesMenu();
|
||||
Constants.resetRecentFilesMenu();
|
||||
|
||||
if (!Configuration.pingback) {
|
||||
pingBack.start();
|
||||
|
@ -518,7 +520,7 @@ public class BytecodeViewer
|
|||
if (recentFiles)
|
||||
for (File f : files)
|
||||
if (f.exists())
|
||||
BytecodeViewer.addRecentFile(f);
|
||||
Constants.addRecentFile(f);
|
||||
|
||||
BytecodeViewer.viewer.updateBusyStatus(true);
|
||||
Configuration.needsReDump = true;
|
||||
|
@ -585,90 +587,6 @@ public class BytecodeViewer
|
|||
the.bytecode.club.bytecodeviewer.api.BytecodeViewer.getClassNodeLoader().clear();
|
||||
}
|
||||
|
||||
private static final List<String> killList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Add the recent file
|
||||
*
|
||||
* @param f the recent file
|
||||
*/
|
||||
public static void addRecentFile(File f) {
|
||||
for (int i = 0; i < recentFiles.size(); i++) { // remove dead strings
|
||||
String s = recentFiles.get(i);
|
||||
if (s.isEmpty() || i > maxRecentFiles)
|
||||
killList.add(s);
|
||||
}
|
||||
if (!killList.isEmpty()) {
|
||||
for (String s : killList)
|
||||
recentFiles.remove(s);
|
||||
killList.clear();
|
||||
}
|
||||
|
||||
// already added on the list
|
||||
recentFiles.remove(f.getAbsolutePath());
|
||||
if (recentFiles.size() >= maxRecentFiles)
|
||||
recentFiles.remove(maxRecentFiles - 1); // zero indexing
|
||||
|
||||
recentFiles.add(0, f.getAbsolutePath());
|
||||
DiskWriter.replaceFile(filesName, MiscUtils.listToString(recentFiles), false);
|
||||
resetRecentFilesMenu();
|
||||
}
|
||||
|
||||
private static final List<String> killList2 = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Add to the recent plugin list
|
||||
*
|
||||
* @param f the plugin file
|
||||
*/
|
||||
public static void addRecentPlugin(File f) {
|
||||
for (int i = 0; i < recentPlugins.size(); i++) { // remove dead strings
|
||||
String s = recentPlugins.get(i);
|
||||
if (s.isEmpty() || i > maxRecentFiles)
|
||||
killList2.add(s);
|
||||
}
|
||||
if (!killList2.isEmpty()) {
|
||||
for (String s : killList2)
|
||||
recentPlugins.remove(s);
|
||||
killList2.clear();
|
||||
}
|
||||
|
||||
// already added on the list
|
||||
recentPlugins.remove(f.getAbsolutePath());
|
||||
if (recentPlugins.size() >= maxRecentFiles)
|
||||
recentPlugins.remove(maxRecentFiles - 1); // zero indexing
|
||||
|
||||
recentPlugins.add(0, f.getAbsolutePath());
|
||||
DiskWriter.replaceFile(pluginsName, MiscUtils.listToString(recentPlugins), false);
|
||||
resetRecentFilesMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* resets the recent files menu
|
||||
*/
|
||||
public static void resetRecentFilesMenu() {
|
||||
viewer.recentFilesSecondaryMenu.removeAll();
|
||||
for (String s : recentFiles)
|
||||
if (!s.isEmpty()) {
|
||||
JMenuItem m = new JMenuItem(s);
|
||||
m.addActionListener(e -> {
|
||||
JMenuItem m12 = (JMenuItem) e.getSource();
|
||||
openFiles(new File[]{new File(m12.getText())}, true);
|
||||
});
|
||||
viewer.recentFilesSecondaryMenu.add(m);
|
||||
}
|
||||
viewer.recentPluginsSecondaryMenu.removeAll();
|
||||
for (String s : recentPlugins)
|
||||
if (!s.isEmpty()) {
|
||||
JMenuItem m = new JMenuItem(s);
|
||||
m.addActionListener(e -> {
|
||||
JMenuItem m1 = (JMenuItem) e.getSource();
|
||||
startPlugin(new File(m1.getText()));
|
||||
});
|
||||
viewer.recentPluginsSecondaryMenu.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the temp directory
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,10 @@ import com.google.gson.Gson;
|
|||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import me.konloch.kontainer.io.DiskReader;
|
||||
import me.konloch.kontainer.io.DiskWriter;
|
||||
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -42,12 +45,14 @@ public class Constants
|
|||
public static String enjarifyWorkingDirectory = getBCVDirectory() + fs + "enjarify_" + enjarifyVersion;
|
||||
public static final String[] SUPPORTED_FILE_EXTENSIONS = new String[]{"jar", "zip", "class", "apk", "dex", "war", "jsp"};
|
||||
|
||||
public static List<String> recentPlugins;
|
||||
public static List<String> recentFiles;
|
||||
private static List<String> recentPlugins;
|
||||
private static List<String> recentFiles;
|
||||
public static Gson gson;
|
||||
|
||||
static {
|
||||
try {
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
if (new File(filesName).exists())
|
||||
recentFiles = gson.fromJson(DiskReader.loadAsString(filesName), new TypeToken<ArrayList<String>>() {}.getType());
|
||||
|
@ -58,17 +63,89 @@ public class Constants
|
|||
recentPlugins = gson.fromJson(DiskReader.loadAsString(pluginsName), new TypeToken<ArrayList<String>>() {}.getType());
|
||||
else
|
||||
recentPlugins = DiskReader.loadArrayList(getBCVDirectory() + fs + "recentplugins.bcv", false);
|
||||
} catch (Exception e) {
|
||||
|
||||
MiscUtils.deduplicateAndTrim(recentFiles, 25);
|
||||
MiscUtils.deduplicateAndTrim(recentPlugins, 25);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the recent file
|
||||
*
|
||||
* @param f the recent file
|
||||
*/
|
||||
public static void addRecentFile(File f)
|
||||
{
|
||||
recentFiles.remove(f.getAbsolutePath()); // already added on the list
|
||||
recentFiles.add(0, f.getAbsolutePath());
|
||||
MiscUtils.deduplicateAndTrim(recentFiles, 25);
|
||||
DiskWriter.replaceFile(filesName, MiscUtils.listToString(recentFiles), false);
|
||||
resetRecentFilesMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the recent plugin list
|
||||
*
|
||||
* @param f the plugin file
|
||||
*/
|
||||
public static void addRecentPlugin(File f)
|
||||
{
|
||||
recentPlugins.remove(f.getAbsolutePath()); // already added on the list
|
||||
recentPlugins.add(0, f.getAbsolutePath());
|
||||
MiscUtils.deduplicateAndTrim(recentPlugins, 25);
|
||||
DiskWriter.replaceFile(pluginsName, MiscUtils.listToString(recentPlugins), false);
|
||||
resetRecentFilesMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* resets the recent files menu
|
||||
*/
|
||||
protected static void resetRecentFilesMenu()
|
||||
{
|
||||
//build recent files
|
||||
BytecodeViewer.viewer.recentFilesSecondaryMenu.removeAll();
|
||||
for (String s : recentFiles)
|
||||
{
|
||||
if (!s.isEmpty())
|
||||
{
|
||||
JMenuItem m = new JMenuItem(s);
|
||||
m.addActionListener(e ->
|
||||
{
|
||||
JMenuItem m12 = (JMenuItem) e.getSource();
|
||||
BytecodeViewer.openFiles(new File[]{new File(m12.getText())}, true);
|
||||
});
|
||||
BytecodeViewer.viewer.recentFilesSecondaryMenu.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
//build recent plugins
|
||||
BytecodeViewer.viewer.recentPluginsSecondaryMenu.removeAll();
|
||||
for (String s : recentPlugins)
|
||||
{
|
||||
if (!s.isEmpty())
|
||||
{
|
||||
JMenuItem m = new JMenuItem(s);
|
||||
m.addActionListener(e ->
|
||||
{
|
||||
JMenuItem m1 = (JMenuItem) e.getSource();
|
||||
BytecodeViewer.startPlugin(new File(m1.getText()));
|
||||
});
|
||||
BytecodeViewer.viewer.recentPluginsSecondaryMenu.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the BCV directory
|
||||
*
|
||||
* @return the static BCV directory
|
||||
*/
|
||||
public static String getBCVDirectory() {
|
||||
public static String getBCVDirectory()
|
||||
{
|
||||
while (!BCVDir.exists())
|
||||
BCVDir.mkdirs();
|
||||
|
||||
|
@ -83,7 +160,8 @@ public class Constants
|
|||
*
|
||||
* @return true if the os.name property contains 'win'
|
||||
*/
|
||||
private static boolean isWindows() {
|
||||
private static boolean isWindows()
|
||||
{
|
||||
return System.getProperty("os.name").toLowerCase().contains("win");
|
||||
}
|
||||
|
||||
|
@ -92,7 +170,8 @@ public class Constants
|
|||
*
|
||||
* @param f file you want hidden
|
||||
*/
|
||||
private static void hideFile(File f) {
|
||||
private static void hideFile(File f)
|
||||
{
|
||||
BytecodeViewer.sm.stopBlocking();
|
||||
try {
|
||||
// Hide file by running attrib system command (on Windows)
|
||||
|
|
|
@ -51,7 +51,6 @@ import the.bytecode.club.bytecodeviewer.util.SyntaxLanguage;
|
|||
|
||||
public class FileViewer extends ResourceViewer
|
||||
{
|
||||
public final String name;
|
||||
public final byte[] contents;
|
||||
public final String workingName;
|
||||
|
||||
|
@ -82,8 +81,6 @@ public class FileViewer extends ResourceViewer
|
|||
final String nameLowerCase = this.name.toLowerCase();
|
||||
final String contentsAsString = new String(contents);
|
||||
|
||||
refreshTitle();
|
||||
|
||||
//image viewer
|
||||
if (!MiscUtils.isPureAscii(contentsAsString))
|
||||
{
|
||||
|
@ -128,6 +125,8 @@ public class FileViewer extends ResourceViewer
|
|||
textArea.setCaretPosition(0);
|
||||
|
||||
mainPanel.add(textArea.getScrollPane());
|
||||
|
||||
refreshTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -139,6 +138,8 @@ public class FileViewer extends ResourceViewer
|
|||
|
||||
public void refresh(JButton src)
|
||||
{
|
||||
refreshTitle();
|
||||
|
||||
if (!canRefresh)
|
||||
{
|
||||
src.setEnabled(true);
|
||||
|
@ -152,8 +153,6 @@ public class FileViewer extends ResourceViewer
|
|||
JLabel label = new JLabel("", new ImageIcon(image), JLabel.CENTER);
|
||||
mainPanel.add(label, BorderLayout.CENTER);
|
||||
mainPanel.updateUI();
|
||||
|
||||
refreshTitle();
|
||||
|
||||
src.setEnabled(true);
|
||||
}
|
||||
|
|
|
@ -24,13 +24,20 @@ import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
* A ResourceViewer
|
||||
*
|
||||
* @author Konloch
|
||||
*/
|
||||
|
||||
public abstract class ResourceViewer extends JPanel
|
||||
{
|
||||
public ClassNode cn;
|
||||
public String originalName;
|
||||
public String name;
|
||||
public FileContainer container;
|
||||
|
||||
public abstract void refreshTitle();
|
||||
|
||||
public String getTabName()
|
||||
{
|
||||
String tabName = name;
|
||||
|
@ -42,8 +49,6 @@ public abstract class ResourceViewer extends JPanel
|
|||
|
||||
return tabName;
|
||||
}
|
||||
|
||||
public abstract void refreshTitle();
|
||||
|
||||
private static final long serialVersionUID = -2965538493489119191L;
|
||||
}
|
|
@ -210,6 +210,20 @@ public class MiscUtils
|
|||
return defaultImage;
|
||||
}
|
||||
|
||||
public static void deduplicateAndTrim(List<String> list, int maxLength)
|
||||
{
|
||||
List<String> temporaryList = new ArrayList<>();
|
||||
for(String s : list)
|
||||
if(!s.isEmpty() && !temporaryList.contains(s))
|
||||
temporaryList.add(s);
|
||||
|
||||
list.clear();
|
||||
list.addAll(temporaryList);
|
||||
|
||||
while(temporaryList.size() > maxLength)
|
||||
list.remove(0);
|
||||
}
|
||||
|
||||
public static boolean isPureAscii(String v) {
|
||||
return asciiEncoder.canEncode(v);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue