Fixed Synchronized Scrolling & Import Directory
This commit is contained in:
parent
ecdbfd9745
commit
152957c128
7 changed files with 47 additions and 28 deletions
|
@ -71,7 +71,7 @@ import static the.bytecode.club.bytecodeviewer.Constants.*;
|
||||||
* http://the.bytecode.club
|
* http://the.bytecode.club
|
||||||
*
|
*
|
||||||
* TODO BUGS:
|
* TODO BUGS:
|
||||||
* + Synchronized scrolling is broken
|
* + The compile mode inside the ResourceViewPanel for Krakatau and Smali assembly needs to be changed when opened with those specific decompilers
|
||||||
* + Spam-clicking the refresh button will cause the swing thread to deadlock (Quickly opening resources used to also do this)
|
* + 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
|
* This is caused by the ctrlMouseWheelZoom code, a temporary patch is just removing it worst case
|
||||||
* + Fix classfile searcher
|
* + Fix classfile searcher
|
||||||
|
|
|
@ -56,6 +56,6 @@ public class ResourceViewPanel
|
||||||
|
|
||||||
public void updatePane(ClassViewer cv, byte[] b, JButton button, boolean isPanelEditable)
|
public void updatePane(ClassViewer cv, byte[] b, JButton button, boolean isPanelEditable)
|
||||||
{
|
{
|
||||||
updateThread = new ResourceProcessClassToViewThread(this, cv, b, isPanelEditable, button);
|
updateThread = new ResourceViewProcessing(this, cv, b, isPanelEditable, button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ import java.awt.*;
|
||||||
* @since 6/27/2021
|
* @since 6/27/2021
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ResourceProcessClassToViewThread extends PaneUpdaterThread
|
public class ResourceViewProcessing extends PaneUpdaterThread
|
||||||
{
|
{
|
||||||
private final ResourceViewPanel resourceViewPanel;
|
private final ResourceViewPanel resourceViewPanel;
|
||||||
private final ClassViewer cv;
|
private final ClassViewer cv;
|
||||||
|
@ -47,7 +47,7 @@ public class ResourceProcessClassToViewThread extends PaneUpdaterThread
|
||||||
private final JButton button;
|
private final JButton button;
|
||||||
public boolean waitingFor;
|
public boolean waitingFor;
|
||||||
|
|
||||||
public ResourceProcessClassToViewThread(ResourceViewPanel resourceViewPanel, ClassViewer cv, byte[] b, boolean isPanelEditable, JButton button)
|
public ResourceViewProcessing(ResourceViewPanel resourceViewPanel, ClassViewer cv, byte[] b, boolean isPanelEditable, JButton button)
|
||||||
{
|
{
|
||||||
super(resourceViewPanel.panelIndex, resourceViewPanel.decompilerViewIndex);
|
super(resourceViewPanel.panelIndex, resourceViewPanel.decompilerViewIndex);
|
||||||
this.resourceViewPanel = resourceViewPanel;
|
this.resourceViewPanel = resourceViewPanel;
|
|
@ -336,17 +336,6 @@ public class ClassViewer extends ResourceViewer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getLineText(RSyntaxTextArea area, int line) {
|
|
||||||
try {
|
|
||||||
if (line < area.getLineCount()) {
|
|
||||||
int start = area.getLineStartOffset(line);
|
|
||||||
int end = area.getLineEndOffset(line);
|
|
||||||
return area.getText(start, end - start).trim();
|
|
||||||
}
|
|
||||||
} catch (BadLocationException ignored) { }
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getMaxViewLine(RSyntaxTextArea area)
|
public static int getMaxViewLine(RSyntaxTextArea area)
|
||||||
{
|
{
|
||||||
Container parent = area.getParent();
|
Container parent = area.getParent();
|
||||||
|
|
|
@ -104,12 +104,18 @@ public abstract class PaneUpdaterThread implements Runnable
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public final CaretListener caretListener = new CaretListener() {
|
public final CaretListener caretListener = new CaretListener()
|
||||||
|
{
|
||||||
@Override
|
@Override
|
||||||
public void caretUpdate(CaretEvent e) {
|
public void caretUpdate(CaretEvent e)
|
||||||
|
{
|
||||||
MethodParser methods = viewer.methods.get(paneIndex);
|
MethodParser methods = viewer.methods.get(paneIndex);
|
||||||
if (methods != null) {
|
if (methods != null)
|
||||||
|
{
|
||||||
int methodLine = methods.findActiveMethod(updateUpdaterTextArea.getCaretLineNumber());
|
int methodLine = methods.findActiveMethod(updateUpdaterTextArea.getCaretLineNumber());
|
||||||
|
|
||||||
|
System.out.println("LINE: " + methodLine);
|
||||||
|
|
||||||
if (methodLine != -1) {
|
if (methodLine != -1) {
|
||||||
if (BytecodeViewer.viewer.showClassMethods.isSelected()) {
|
if (BytecodeViewer.viewer.showClassMethods.isSelected()) {
|
||||||
if (methodsList != null) {
|
if (methodsList != null) {
|
||||||
|
@ -212,10 +218,12 @@ public abstract class PaneUpdaterThread implements Runnable
|
||||||
updateUpdaterTextArea.addCaretListener(caretListener);
|
updateUpdaterTextArea.addCaretListener(caretListener);
|
||||||
|
|
||||||
final MethodParser methods = viewer.methods.get(paneIndex);
|
final MethodParser methods = viewer.methods.get(paneIndex);
|
||||||
for (int i = 0; i < updateUpdaterTextArea.getLineCount(); i++) {
|
for (int i = 0; i < updateUpdaterTextArea.getLineCount(); i++)
|
||||||
String lineText = ClassViewer.getLineText(updateUpdaterTextArea, i);
|
{
|
||||||
|
String lineText = updateUpdaterTextArea.getLineText(i);
|
||||||
Matcher regexMatcher = MethodParser.regex.matcher(lineText);
|
Matcher regexMatcher = MethodParser.regex.matcher(lineText);
|
||||||
if (regexMatcher.find()) {
|
if (regexMatcher.find())
|
||||||
|
{
|
||||||
String methodName = regexMatcher.group("name");
|
String methodName = regexMatcher.group("name");
|
||||||
String methodParams = regexMatcher.group("params");
|
String methodParams = regexMatcher.group("params");
|
||||||
methods.addMethod(i, methodName, methodParams);
|
methods.addMethod(i, methodName, methodParams);
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package the.bytecode.club.bytecodeviewer.resources.importing.impl;
|
package the.bytecode.club.bytecodeviewer.resources.importing.impl;
|
||||||
|
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.resources.importing.Import;
|
import the.bytecode.club.bytecodeviewer.resources.importing.Import;
|
||||||
import the.bytecode.club.bytecodeviewer.resources.importing.Importer;
|
import the.bytecode.club.bytecodeviewer.resources.importing.Importer;
|
||||||
import the.bytecode.club.bytecodeviewer.util.FileContainer;
|
import the.bytecode.club.bytecodeviewer.util.FileContainer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.util.JarUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -22,12 +24,13 @@ public class DirectoryResourceImporter implements Importer
|
||||||
public boolean open(File file) throws Exception
|
public boolean open(File file) throws Exception
|
||||||
{
|
{
|
||||||
FileContainer container = new FileContainer(file);
|
FileContainer container = new FileContainer(file);
|
||||||
HashMap<String, byte[]> files1 = new HashMap<>();
|
HashMap<String, byte[]> allDirectoryFiles = new HashMap<>();
|
||||||
|
HashMap<String, ClassNode> allDirectoryClasses = new HashMap<>();
|
||||||
|
|
||||||
boolean finished = false;
|
boolean finished = false;
|
||||||
ArrayList<File> totalFiles = new ArrayList<>();
|
ArrayList<File> totalFiles = new ArrayList<>();
|
||||||
totalFiles.add(file);
|
totalFiles.add(file);
|
||||||
String dir = file.getAbsolutePath();//f.getAbsolutePath().substring(0, f.getAbsolutePath
|
String dir = file.getAbsolutePath();
|
||||||
// ().length()-f.getName().length());
|
|
||||||
|
|
||||||
while (!finished)
|
while (!finished)
|
||||||
{
|
{
|
||||||
|
@ -68,10 +71,26 @@ public class DirectoryResourceImporter implements Importer
|
||||||
{
|
{
|
||||||
Import.DEX.getImporter().open(child);
|
Import.DEX.getImporter().open(child);
|
||||||
}
|
}
|
||||||
|
else if (fileName.endsWith(".class"))
|
||||||
|
{
|
||||||
|
byte[] bytes = Files.readAllBytes(Paths.get(child.getAbsolutePath()));
|
||||||
|
|
||||||
|
String cafebabe = String.format("%02X", bytes[0])
|
||||||
|
+ String.format("%02X", bytes[1])
|
||||||
|
+ String.format("%02X", bytes[2])
|
||||||
|
+ String.format("%02X", bytes[3]);
|
||||||
|
|
||||||
|
//check the header for cafebabe
|
||||||
|
if (cafebabe.equalsIgnoreCase("cafebabe"))
|
||||||
|
{
|
||||||
|
final ClassNode cn = JarUtils.getNode(bytes);
|
||||||
|
allDirectoryClasses.put(trimmedPath, cn);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//pack files into a single container
|
//pack files into a single container
|
||||||
files1.put(trimmedPath, Files.readAllBytes(Paths.get(child.getAbsolutePath())));
|
allDirectoryFiles.put(trimmedPath, Files.readAllBytes(Paths.get(child.getAbsolutePath())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +98,8 @@ public class DirectoryResourceImporter implements Importer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container.files = files1;
|
container.classes.addAll(allDirectoryClasses.values());
|
||||||
|
container.files = allDirectoryFiles;
|
||||||
BytecodeViewer.files.add(container);
|
BytecodeViewer.files.add(container);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,8 +117,10 @@ public class MethodParser {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int findActiveMethod(int line) {
|
public int findActiveMethod(int line)
|
||||||
if (!methods.isEmpty()) {
|
{
|
||||||
|
if (!methods.isEmpty())
|
||||||
|
{
|
||||||
Map.Entry<Integer, Method> low = methods.floorEntry(line);
|
Map.Entry<Integer, Method> low = methods.floorEntry(line);
|
||||||
if (low != null) {
|
if (low != null) {
|
||||||
return low.getKey();
|
return low.getKey();
|
||||||
|
|
Loading…
Reference in a new issue