2018-01-31 15:03:53 +00:00
|
|
|
package the.bytecode.club.bytecodeviewer;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
2021-07-27 10:17:57 +00:00
|
|
|
import java.util.*;
|
2021-06-26 01:13:46 +00:00
|
|
|
import javax.swing.*;
|
2021-06-26 12:59:51 +00:00
|
|
|
|
2021-06-29 09:41:29 +00:00
|
|
|
import com.google.gson.Gson;
|
|
|
|
import com.google.gson.GsonBuilder;
|
2018-01-31 15:03:53 +00:00
|
|
|
import org.apache.commons.io.FileUtils;
|
|
|
|
import org.objectweb.asm.tree.ClassNode;
|
2021-07-21 16:52:01 +00:00
|
|
|
|
|
|
|
import me.konloch.kontainer.io.DiskReader;
|
|
|
|
|
2021-07-10 16:05:08 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.api.BCV;
|
2021-07-07 04:45:39 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
|
2021-07-21 23:21:45 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.bootloader.Boot;
|
2021-07-24 02:17:20 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.bootloader.BootState;
|
2021-07-21 22:28:48 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.bootloader.InstallFatJar;
|
2021-07-21 19:55:03 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.bootloader.UpdateCheck;
|
2021-07-21 16:52:01 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
|
2021-06-26 17:36:26 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.gui.components.*;
|
2021-06-26 12:26:12 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.TabbedPane;
|
2021-06-26 01:13:46 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
|
2021-06-26 12:26:12 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
|
2021-07-08 08:50:57 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.plugin.PluginWriter;
|
2021-07-21 16:52:01 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.Refactorer;
|
2021-07-18 19:11:34 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
2021-07-21 16:52:01 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
|
2021-06-26 15:10:02 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.resources.importing.ImportResource;
|
2021-07-21 16:52:01 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.util.*;
|
2021-06-21 09:45:31 +00:00
|
|
|
|
2021-07-27 10:17:57 +00:00
|
|
|
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
|
2021-06-21 09:45:31 +00:00
|
|
|
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
2018-01-31 15:03:53 +00:00
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* 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/>. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A lightweight Java Reverse Engineering suite, developed by Konloch - http://konloch.me
|
2021-06-21 09:45:31 +00:00
|
|
|
*
|
2019-04-13 03:42:04 +00:00
|
|
|
* All you have to do is add a jar or class file into the workspace,
|
2019-04-17 06:45:15 +00:00
|
|
|
* select the file you want then it will start decompiling the class in the background.
|
|
|
|
* When it's done it will show the Source code, Bytecode and Hexcode of the class file you chose.
|
2021-06-21 09:45:31 +00:00
|
|
|
*
|
2019-04-17 06:45:15 +00:00
|
|
|
* There is also a plugin system that will allow you to interact with the loaded classfiles.
|
|
|
|
* For example you can write a String deobfuscator, a malicious code searcher,
|
|
|
|
* or anything else you can think of.
|
2021-06-21 09:45:31 +00:00
|
|
|
*
|
2019-04-17 06:45:15 +00:00
|
|
|
* You can either use one of the pre-written plugins, or write your own. It supports java scripting.
|
|
|
|
* Once a plugin is activated, it will send a ClassNode ArrayList of every single class loaded in the
|
|
|
|
* file system to the execute function, this allows the user to handle it completely using ASM.
|
2021-06-21 09:45:31 +00:00
|
|
|
*
|
2019-04-17 06:45:15 +00:00
|
|
|
* Are you a Java Reverse Engineer? Or maybe you want to learn Java Reverse Engineering?
|
2021-04-12 20:19:12 +00:00
|
|
|
* Join The Bytecode Club, we're noob friendly, and censorship free.
|
|
|
|
* http://the.bytecode.club
|
2021-06-21 09:45:31 +00:00
|
|
|
*
|
2021-06-26 02:59:43 +00:00
|
|
|
* TODO BUGS:
|
2021-06-28 04:14:20 +00:00
|
|
|
* + View>Visual Settings>Show Class Methods
|
2021-06-26 05:25:50 +00:00
|
|
|
* + Spam-clicking the refresh button will cause the swing thread to deadlock (Quickly opening resources used to also do this)
|
2021-06-26 02:59:43 +00:00
|
|
|
* This is caused by the ctrlMouseWheelZoom code, a temporary patch is just removing it worst case
|
|
|
|
*
|
2021-07-13 12:34:04 +00:00
|
|
|
* TODO API BUGS:
|
|
|
|
* + All of the plugins that modify code need to include BytecodeViewer.updateAllClassNodeByteArrays();
|
|
|
|
* + All of the plugins that do any code changes should also include BytecodeViewer.refreshAllTabs();
|
|
|
|
* + Anything using getLoadedClasses() needs to be replaced with the new API
|
2021-07-13 14:33:32 +00:00
|
|
|
* + Anything using blindlySearchForClassNode() should instead search through the resource container search function
|
2021-07-30 04:13:34 +00:00
|
|
|
* + BCV's classLoader should be destroyed each time a resource is added or removed
|
2021-07-13 12:34:04 +00:00
|
|
|
*
|
2021-07-23 22:33:34 +00:00
|
|
|
* TODO DarkLAF Specific Bugs:
|
|
|
|
* + Resource List creates swing lag with large project
|
|
|
|
* + JMenuBar can only be displayed on a JFrame, a work around is needed for this
|
|
|
|
*
|
2021-06-26 02:59:43 +00:00
|
|
|
* TODO IN-PROGRESS:
|
2021-07-16 20:55:03 +00:00
|
|
|
* + Resource Exporter/Save/Decompile As Zip needs to be rewritten
|
2021-06-26 05:25:50 +00:00
|
|
|
* + Finish dragging code
|
|
|
|
* + Finish right-click tab menu detection
|
|
|
|
* + Fix hook inject for EZ-Injection
|
2021-06-26 02:59:43 +00:00
|
|
|
*
|
|
|
|
* TODO FEATURES:
|
2021-07-21 16:20:25 +00:00
|
|
|
* + On refresh save scroll position
|
2021-07-20 17:03:17 +00:00
|
|
|
* + Option to only compile currently viewed class (true by default)
|
2021-07-01 21:54:10 +00:00
|
|
|
* + CLI Headless needs to be supported
|
2021-06-26 05:25:50 +00:00
|
|
|
* + Add stackmapframes to bytecode decompiler
|
2021-07-30 04:13:34 +00:00
|
|
|
* + Add https://github.com/exbin/bined as the replacement Hex Viewer/Editor
|
2021-06-26 05:25:50 +00:00
|
|
|
* + Make the decompilers launch in a separate process
|
|
|
|
* + Add decompile as zip for krakatau-bytecode, jd-gui and smali for CLI
|
|
|
|
* + Add decompile all as zip for CLI
|
2021-07-11 12:33:18 +00:00
|
|
|
* + Console on the Main Viewer UI
|
|
|
|
* + Font settings
|
2018-01-31 15:41:24 +00:00
|
|
|
*
|
2021-07-04 08:51:05 +00:00
|
|
|
* TODO IDEAS:
|
2021-07-05 02:07:34 +00:00
|
|
|
* + App Bundle Support
|
2021-07-21 16:20:25 +00:00
|
|
|
* + Add JEB decompiler optionally, requires them to add jeb library jar
|
2021-07-05 04:50:28 +00:00
|
|
|
* + Add the setting to force all non-class resources to be opened with the Hex Viewer
|
2021-07-04 10:23:14 +00:00
|
|
|
* ^ Optionally a right-click menu open-as would work inside of the resource list
|
2021-07-04 08:51:05 +00:00
|
|
|
* + Allow class files to be opened without needing the .class extension
|
|
|
|
* ^ Easiest way to do this is to read the file header CAFEBABE on resource view
|
2021-07-11 09:31:56 +00:00
|
|
|
* + Add BCEL Support:
|
|
|
|
* ^ https://github.com/ptnkjke/Java-Bytecode-Editor visualizer as a plugin
|
2021-07-21 10:44:33 +00:00
|
|
|
* + Add animated GIF support to image viewer
|
|
|
|
* + Add drag support to images (allow not only to zoom, but also to drag the image)
|
2021-07-04 08:51:05 +00:00
|
|
|
*
|
2018-01-31 15:03:53 +00:00
|
|
|
* @author Konloch
|
2019-04-17 06:45:15 +00:00
|
|
|
* @author The entire BCV community
|
2018-01-31 15:03:53 +00:00
|
|
|
*/
|
|
|
|
|
2021-06-21 09:45:31 +00:00
|
|
|
public class BytecodeViewer
|
|
|
|
{
|
2021-07-07 04:21:06 +00:00
|
|
|
//TODO fix this for tab dragging & better tab controls
|
2021-07-07 00:23:34 +00:00
|
|
|
public static boolean EXPERIMENTAL_TAB_CODE = false;
|
|
|
|
|
2021-07-07 04:21:06 +00:00
|
|
|
//the launch args called on BCV
|
2021-07-06 23:54:20 +00:00
|
|
|
public static String[] launchArgs;
|
2021-07-07 04:21:06 +00:00
|
|
|
|
|
|
|
//the GUI reference
|
|
|
|
public static MainViewerGUI viewer;
|
|
|
|
|
|
|
|
//All of the opened resources (Files/Classes/Etc)
|
2021-07-27 10:17:57 +00:00
|
|
|
public static LinkedHashMap<String,ResourceContainer> resourceContainers = new LinkedHashMap<>();
|
2021-07-07 04:21:06 +00:00
|
|
|
|
|
|
|
//All of the created processes (Decompilers/etc)
|
|
|
|
public static List<Process> createdProcesses = new ArrayList<>();
|
|
|
|
|
|
|
|
//Security Manager for dynamic analysis debugging
|
2021-07-19 17:46:35 +00:00
|
|
|
public static SecurityMan sm = new SecurityMan();
|
2021-07-07 04:21:06 +00:00
|
|
|
|
|
|
|
//Refactorer
|
2021-06-21 09:45:31 +00:00
|
|
|
public static Refactorer refactorer = new Refactorer();
|
2021-07-07 04:21:06 +00:00
|
|
|
|
|
|
|
//GSON Reference
|
2021-06-29 09:41:29 +00:00
|
|
|
public static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
2021-07-07 00:23:34 +00:00
|
|
|
|
2021-07-07 04:21:06 +00:00
|
|
|
//Threads
|
2021-07-21 19:55:03 +00:00
|
|
|
private static final Thread versionChecker = new Thread(new UpdateCheck(), "Version Checker");
|
2021-07-06 23:53:37 +00:00
|
|
|
private static final Thread pingBack = new Thread(new PingBack(), "Pingback");
|
|
|
|
private static final Thread installFatJar = new Thread(new InstallFatJar(), "Install Fat-Jar");
|
2021-07-01 09:48:10 +00:00
|
|
|
private static final Thread bootCheck = new Thread(new BootCheck(), "Boot Check");
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Main startup
|
|
|
|
*
|
|
|
|
* @param args files you want to open or CLI
|
|
|
|
*/
|
2021-07-01 21:54:10 +00:00
|
|
|
public static void main(String[] args)
|
|
|
|
{
|
2021-07-06 23:54:20 +00:00
|
|
|
launchArgs = args;
|
2021-07-06 23:53:37 +00:00
|
|
|
|
|
|
|
//welcome message
|
2021-07-07 00:53:29 +00:00
|
|
|
System.out.print("Bytecode Viewer " + VERSION);
|
2021-07-21 15:20:38 +00:00
|
|
|
if (FAT_JAR)
|
2021-07-21 14:44:25 +00:00
|
|
|
System.out.print(" [Fat Jar]");
|
2021-07-07 00:53:29 +00:00
|
|
|
|
|
|
|
System.out.println(" - Created by @Konloch");
|
|
|
|
System.out.println("https://bytecodeviewer.com - https://the.bytecode.club");
|
2021-07-06 23:53:37 +00:00
|
|
|
|
|
|
|
//set the security manager
|
2018-01-31 15:41:24 +00:00
|
|
|
System.setSecurityManager(sm);
|
2021-06-21 09:45:31 +00:00
|
|
|
|
2021-07-06 23:53:37 +00:00
|
|
|
try
|
|
|
|
{
|
2021-06-26 01:13:46 +00:00
|
|
|
//precache settings file
|
2021-06-29 09:41:29 +00:00
|
|
|
SettingsSerializer.preloadSettingsFile();
|
2021-07-21 16:20:25 +00:00
|
|
|
|
2021-06-26 01:13:46 +00:00
|
|
|
//setup look and feel
|
|
|
|
Configuration.lafTheme.setLAF();
|
|
|
|
|
2021-07-01 21:54:10 +00:00
|
|
|
//set swing specific system properties
|
|
|
|
System.setProperty("swing.aatext", "true");
|
|
|
|
|
|
|
|
//setup swing components
|
2018-01-31 15:41:24 +00:00
|
|
|
viewer = new MainViewerGUI();
|
2021-06-29 00:05:18 +00:00
|
|
|
SwingUtilities.updateComponentTreeUI(viewer);
|
2021-07-01 21:54:10 +00:00
|
|
|
|
|
|
|
//load settings and set swing components state
|
2021-06-29 09:41:29 +00:00
|
|
|
SettingsSerializer.loadSettings();
|
2021-07-24 02:17:20 +00:00
|
|
|
Configuration.bootState = BootState.SETTINGS_LOADED;
|
2021-07-01 21:54:10 +00:00
|
|
|
|
|
|
|
//set translation language
|
2021-07-21 15:20:38 +00:00
|
|
|
if (!Settings.hasSetLanguageAsSystemLanguage)
|
2021-07-21 16:52:01 +00:00
|
|
|
MiscUtils.setLanguage(MiscUtils.guessLanguage());
|
2021-06-29 00:05:18 +00:00
|
|
|
|
2021-07-01 21:54:10 +00:00
|
|
|
//handle CLI
|
2018-01-31 15:41:24 +00:00
|
|
|
int CLI = CommandLineInput.parseCommandLine(args);
|
|
|
|
if (CLI == CommandLineInput.STOP)
|
|
|
|
return;
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-11 08:44:37 +00:00
|
|
|
//load with shaded libraries
|
|
|
|
if (FAT_JAR)
|
2021-07-06 23:53:37 +00:00
|
|
|
{
|
2021-07-11 08:44:37 +00:00
|
|
|
installFatJar.start();
|
2021-07-06 23:53:37 +00:00
|
|
|
}
|
2021-07-11 08:44:37 +00:00
|
|
|
else //load through bootloader
|
2021-07-10 16:05:08 +00:00
|
|
|
{
|
2021-07-11 08:44:37 +00:00
|
|
|
bootCheck.start();
|
|
|
|
Boot.boot(args, CLI != CommandLineInput.GUI);
|
2021-07-10 16:05:08 +00:00
|
|
|
}
|
2021-07-16 03:50:05 +00:00
|
|
|
|
|
|
|
//CLI arguments say spawn the GUI
|
2021-07-08 09:24:12 +00:00
|
|
|
if (CLI == CommandLineInput.GUI)
|
2021-07-10 16:05:08 +00:00
|
|
|
{
|
2021-06-21 11:32:07 +00:00
|
|
|
BytecodeViewer.boot(false);
|
2021-07-24 02:17:20 +00:00
|
|
|
Configuration.bootState = BootState.GUI_SHOWING;
|
2021-07-10 16:05:08 +00:00
|
|
|
}
|
2021-07-16 03:50:05 +00:00
|
|
|
else //CLI arguments say keep it CLI
|
2021-07-06 23:53:37 +00:00
|
|
|
{
|
2021-06-21 11:32:07 +00:00
|
|
|
BytecodeViewer.boot(true);
|
2018-01-31 15:41:24 +00:00
|
|
|
CommandLineInput.executeCommandLine(args);
|
|
|
|
}
|
2021-07-06 23:53:37 +00:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2021-07-07 02:51:10 +00:00
|
|
|
BytecodeViewer.handleException(e);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Boot after all of the libraries have been loaded
|
|
|
|
*
|
|
|
|
* @param cli is it running CLI mode or not
|
|
|
|
*/
|
2021-07-05 02:07:34 +00:00
|
|
|
public static void boot(boolean cli)
|
|
|
|
{
|
2021-07-07 04:45:39 +00:00
|
|
|
//delete files in the temp folder
|
2021-07-01 09:06:12 +00:00
|
|
|
cleanupAsync();
|
2021-07-07 04:45:39 +00:00
|
|
|
|
|
|
|
//shutdown hooks
|
2021-07-05 02:07:34 +00:00
|
|
|
Runtime.getRuntime().addShutdownHook(new Thread(() ->
|
|
|
|
{
|
2021-04-12 22:31:22 +00:00
|
|
|
for (Process proc : createdProcesses)
|
|
|
|
proc.destroy();
|
2021-07-21 16:20:25 +00:00
|
|
|
|
2021-06-29 09:41:29 +00:00
|
|
|
SettingsSerializer.saveSettings();
|
2021-04-12 22:31:22 +00:00
|
|
|
cleanup();
|
2021-07-01 09:48:10 +00:00
|
|
|
}, "Shutdown Hook"));
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-07 04:45:39 +00:00
|
|
|
//setup the viewer
|
2018-01-31 15:41:24 +00:00
|
|
|
viewer.calledAfterLoad();
|
2021-07-07 04:45:39 +00:00
|
|
|
|
|
|
|
//setup the recent files
|
2021-06-29 09:41:29 +00:00
|
|
|
Settings.resetRecentFilesMenu();
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-05 02:07:34 +00:00
|
|
|
//ping back once on first boot to add to global user count
|
|
|
|
if (!Configuration.pingback)
|
|
|
|
{
|
2021-06-21 11:32:07 +00:00
|
|
|
pingBack.start();
|
2021-06-21 11:13:11 +00:00
|
|
|
Configuration.pingback = true;
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-07-07 04:45:39 +00:00
|
|
|
|
|
|
|
//version checking
|
2021-07-21 14:28:30 +00:00
|
|
|
if (viewer.updateCheck.isSelected() && !DEV_MODE)
|
2018-01-31 15:41:24 +00:00
|
|
|
versionChecker.start();
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-07 04:45:39 +00:00
|
|
|
//show the main UI
|
2018-01-31 15:41:24 +00:00
|
|
|
if (!cli)
|
|
|
|
viewer.setVisible(true);
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-07 04:45:39 +00:00
|
|
|
//print startup time
|
2021-06-21 11:13:11 +00:00
|
|
|
System.out.println("Start up took " + ((System.currentTimeMillis() - Configuration.start) / 1000) + " seconds");
|
2021-07-07 04:45:39 +00:00
|
|
|
|
2021-07-07 05:57:35 +00:00
|
|
|
//request focus on GUI for hotkeys on start
|
2021-07-21 15:20:38 +00:00
|
|
|
if (!cli)
|
2021-07-07 05:57:35 +00:00
|
|
|
viewer.requestFocus();
|
|
|
|
|
2021-07-07 04:45:39 +00:00
|
|
|
//open files from launch args
|
2018-01-31 15:41:24 +00:00
|
|
|
if (!cli)
|
2021-07-06 23:54:20 +00:00
|
|
|
if (launchArgs.length >= 1)
|
|
|
|
for (String s : launchArgs)
|
2018-01-31 15:41:24 +00:00
|
|
|
openFiles(new File[]{new File(s)}, true);
|
|
|
|
}
|
2021-07-07 03:05:35 +00:00
|
|
|
|
2021-07-16 20:55:03 +00:00
|
|
|
/**
|
|
|
|
* Adds a resource container to BCVs resource container list
|
|
|
|
*/
|
|
|
|
public static void addResourceContainer(ResourceContainer container)
|
|
|
|
{
|
2021-07-27 10:17:57 +00:00
|
|
|
resourceContainers.put(container.name, container);
|
2021-07-21 15:20:38 +00:00
|
|
|
SwingUtilities.invokeLater(() ->
|
2021-07-16 20:55:03 +00:00
|
|
|
{
|
2021-07-21 16:20:25 +00:00
|
|
|
try {
|
2021-07-16 20:55:03 +00:00
|
|
|
viewer.resourcePane.addResourceContainer(container);
|
2021-07-21 16:20:25 +00:00
|
|
|
} catch (Exception e) {
|
2021-07-16 20:55:03 +00:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-07-07 05:38:47 +00:00
|
|
|
/**
|
|
|
|
* Returns true if there is at least one file resource loaded
|
|
|
|
*/
|
|
|
|
public static boolean hasResources()
|
|
|
|
{
|
2021-07-11 12:33:18 +00:00
|
|
|
return !resourceContainers.isEmpty();
|
2021-07-07 05:38:47 +00:00
|
|
|
}
|
|
|
|
|
2021-07-07 03:05:35 +00:00
|
|
|
/**
|
|
|
|
* Returns true if there is currently a tab open with a resource inside of it
|
|
|
|
*/
|
|
|
|
public static boolean hasActiveResource()
|
|
|
|
{
|
|
|
|
return getActiveResource() != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if there is currently a tab open with a resource inside of it
|
|
|
|
*/
|
|
|
|
public static boolean isActiveResourceClass()
|
|
|
|
{
|
|
|
|
ResourceViewer resource = getActiveResource();
|
|
|
|
return resource instanceof ClassViewer;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the currently opened & viewed resource
|
|
|
|
*/
|
|
|
|
public static ResourceViewer getActiveResource()
|
|
|
|
{
|
|
|
|
return BytecodeViewer.viewer.workPane.getActiveResource();
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Returns the currently opened ClassNode
|
|
|
|
*
|
|
|
|
* @return the currently opened ClassNode
|
|
|
|
*/
|
2021-07-07 03:05:35 +00:00
|
|
|
public static ClassNode getCurrentlyOpenedClassNode()
|
|
|
|
{
|
2021-07-14 11:58:35 +00:00
|
|
|
return getActiveResource().resource.getResourceClassNode();
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Returns the ClassNode by the specified name
|
2021-07-21 15:20:38 +00:00
|
|
|
* <p>
|
2021-07-13 14:33:32 +00:00
|
|
|
* TODO anything relying on this should be rewritten to search using the resource container
|
2021-07-10 16:05:08 +00:00
|
|
|
*
|
2018-01-31 15:41:24 +00:00
|
|
|
* @param name the class name
|
|
|
|
* @return the ClassNode instance
|
|
|
|
*/
|
2021-07-10 16:05:08 +00:00
|
|
|
@Deprecated
|
|
|
|
public static ClassNode blindlySearchForClassNode(String name)
|
2021-07-06 23:53:37 +00:00
|
|
|
{
|
2021-07-27 10:17:57 +00:00
|
|
|
for (ResourceContainer container : resourceContainers.values())
|
2021-07-10 16:05:08 +00:00
|
|
|
{
|
|
|
|
ClassNode node = container.getClassNode(name);
|
2021-07-21 16:20:25 +00:00
|
|
|
|
2021-07-21 15:20:38 +00:00
|
|
|
if (node != null)
|
2021-07-10 16:05:08 +00:00
|
|
|
return node;
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
return null;
|
|
|
|
}
|
2021-07-07 00:23:34 +00:00
|
|
|
|
|
|
|
/**
|
2021-07-13 14:33:32 +00:00
|
|
|
* Returns the resource container by the specific name
|
2021-07-07 00:23:34 +00:00
|
|
|
*/
|
2021-07-11 08:44:37 +00:00
|
|
|
public static ResourceContainer getFileContainer(String name)
|
2021-07-06 23:53:37 +00:00
|
|
|
{
|
2021-07-27 10:17:57 +00:00
|
|
|
for (ResourceContainer container : resourceContainers.values())
|
2019-04-17 06:45:15 +00:00
|
|
|
if (container.name.equals(name))
|
|
|
|
return container;
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2019-04-17 06:45:15 +00:00
|
|
|
return null;
|
|
|
|
}
|
2021-07-07 00:23:34 +00:00
|
|
|
|
|
|
|
/**
|
2021-07-13 14:33:32 +00:00
|
|
|
* Returns all of the loaded resource containers
|
2021-07-07 00:23:34 +00:00
|
|
|
*/
|
2021-07-27 10:17:57 +00:00
|
|
|
public static Collection<ResourceContainer> getResourceContainers()
|
2021-07-21 15:20:38 +00:00
|
|
|
{
|
2021-07-27 10:17:57 +00:00
|
|
|
return resourceContainers.values();
|
2019-06-01 01:04:07 +00:00
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Grabs the file contents of the loaded resources.
|
2021-07-21 15:20:38 +00:00
|
|
|
* <p>
|
2021-07-13 14:33:32 +00:00
|
|
|
* TODO anything relying on this should be rewritten to use the resource container's getFileContents
|
|
|
|
*
|
2018-01-31 15:41:24 +00:00
|
|
|
* @param name the file name
|
|
|
|
* @return the file contents as a byte[]
|
|
|
|
*/
|
2021-07-13 14:33:32 +00:00
|
|
|
@Deprecated
|
2021-07-06 23:08:08 +00:00
|
|
|
public static byte[] getFileContents(String name)
|
|
|
|
{
|
2021-07-27 10:17:57 +00:00
|
|
|
for (ResourceContainer container : resourceContainers.values())
|
2021-07-10 16:05:08 +00:00
|
|
|
if (container.resourceFiles.containsKey(name))
|
|
|
|
return container.resourceFiles.get(name);
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
return null;
|
|
|
|
}
|
2021-06-26 12:38:58 +00:00
|
|
|
|
|
|
|
/**
|
2021-07-07 00:23:34 +00:00
|
|
|
* Grab the byte array from the loaded Class object by getting the resource from the classloader
|
2021-06-26 12:38:58 +00:00
|
|
|
*/
|
2021-07-07 00:23:34 +00:00
|
|
|
public static byte[] getClassFileBytes(Class<?> clazz) throws IOException
|
2021-07-06 23:08:08 +00:00
|
|
|
{
|
2021-07-07 00:23:34 +00:00
|
|
|
return ClassFileUtils.getClassFileBytes(clazz);
|
2021-06-26 12:38:58 +00:00
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Gets all of the loaded classes as an array list
|
2021-07-21 16:20:25 +00:00
|
|
|
*
|
2021-07-13 12:34:04 +00:00
|
|
|
* TODO: remove this and replace it with:
|
2021-07-21 15:20:38 +00:00
|
|
|
* BytecodeViewer.getResourceContainers().forEach(container -> {
|
2021-07-21 16:20:25 +00:00
|
|
|
* execute(new ArrayList<>(container.resourceClasses.values()));
|
2021-07-21 15:20:38 +00:00
|
|
|
* });
|
2021-07-13 12:34:04 +00:00
|
|
|
*
|
2018-01-31 15:41:24 +00:00
|
|
|
* @return the loaded classes as an array list
|
|
|
|
*/
|
2021-07-13 12:34:04 +00:00
|
|
|
@Deprecated
|
2021-07-06 23:08:08 +00:00
|
|
|
public static ArrayList<ClassNode> getLoadedClasses()
|
|
|
|
{
|
2021-04-12 22:31:22 +00:00
|
|
|
ArrayList<ClassNode> a = new ArrayList<>();
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-27 10:17:57 +00:00
|
|
|
for (ResourceContainer container : resourceContainers.values())
|
2021-07-10 16:05:08 +00:00
|
|
|
for (ClassNode c : container.resourceClasses.values())
|
2018-01-31 15:41:24 +00:00
|
|
|
if (!a.contains(c))
|
|
|
|
a.add(c);
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
return a;
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-03 19:29:31 +00:00
|
|
|
/**
|
|
|
|
* Called any time refresh is called to automatically compile all of the compilable panes that're opened.
|
|
|
|
*/
|
|
|
|
public static boolean autoCompileSuccessful()
|
|
|
|
{
|
2021-07-21 15:20:38 +00:00
|
|
|
if (!BytecodeViewer.viewer.autoCompileOnRefresh.isSelected())
|
2021-07-03 19:29:31 +00:00
|
|
|
return true;
|
|
|
|
|
2021-07-21 15:20:38 +00:00
|
|
|
try
|
|
|
|
{
|
2021-07-06 00:26:11 +00:00
|
|
|
return compile(false, false);
|
2021-07-21 15:20:38 +00:00
|
|
|
}
|
|
|
|
catch (NullPointerException ignored)
|
|
|
|
{
|
2021-07-03 19:29:31 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Compile all of the compilable panes that're opened.
|
|
|
|
*
|
|
|
|
* @param message if it should send a message saying it's compiled sucessfully.
|
|
|
|
* @return true if no errors, false if it failed to compile.
|
|
|
|
*/
|
2021-07-06 23:08:08 +00:00
|
|
|
public static boolean compile(boolean message, boolean successAlert)
|
|
|
|
{
|
2021-07-06 22:57:42 +00:00
|
|
|
BytecodeViewer.updateBusyStatus(true);
|
2021-07-05 02:07:34 +00:00
|
|
|
boolean noErrors = true;
|
2018-01-31 15:41:24 +00:00
|
|
|
boolean actuallyTried = false;
|
2021-07-06 00:06:05 +00:00
|
|
|
|
2021-06-26 01:13:46 +00:00
|
|
|
for (java.awt.Component c : BytecodeViewer.viewer.workPane.getLoadedViewers())
|
|
|
|
{
|
|
|
|
if (c instanceof ClassViewer)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
ClassViewer cv = (ClassViewer) c;
|
2021-06-26 01:13:46 +00:00
|
|
|
|
2021-07-21 15:20:38 +00:00
|
|
|
if (noErrors && !cv.bytecodeViewPanel1.compile())
|
2021-07-05 02:07:34 +00:00
|
|
|
noErrors = false;
|
2021-07-21 15:20:38 +00:00
|
|
|
if (noErrors && !cv.bytecodeViewPanel2.compile())
|
2021-07-05 02:07:34 +00:00
|
|
|
noErrors = false;
|
2021-07-21 15:20:38 +00:00
|
|
|
if (noErrors && !cv.bytecodeViewPanel3.compile())
|
2021-07-05 02:07:34 +00:00
|
|
|
noErrors = false;
|
|
|
|
|
2021-07-21 15:20:38 +00:00
|
|
|
if (cv.bytecodeViewPanel1.textArea != null && cv.bytecodeViewPanel1.textArea.isEditable())
|
2018-01-31 15:41:24 +00:00
|
|
|
actuallyTried = true;
|
2021-07-21 15:20:38 +00:00
|
|
|
if (cv.bytecodeViewPanel2.textArea != null && cv.bytecodeViewPanel2.textArea.isEditable())
|
2018-01-31 15:41:24 +00:00
|
|
|
actuallyTried = true;
|
2021-07-21 15:20:38 +00:00
|
|
|
if (cv.bytecodeViewPanel3.textArea != null && cv.bytecodeViewPanel3.textArea.isEditable())
|
2018-01-31 15:41:24 +00:00
|
|
|
actuallyTried = true;
|
|
|
|
}
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
if (message)
|
2021-07-05 02:07:34 +00:00
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
if (actuallyTried)
|
2021-07-05 02:07:34 +00:00
|
|
|
{
|
2021-07-21 15:20:38 +00:00
|
|
|
if (noErrors && successAlert)
|
2021-07-05 02:07:34 +00:00
|
|
|
BytecodeViewer.showMessage("Compiled Successfully.");
|
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
else
|
2021-07-05 02:07:34 +00:00
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
BytecodeViewer.showMessage("You have no editable panes opened, make one editable and try again.");
|
2021-07-05 02:07:34 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-06 00:06:05 +00:00
|
|
|
|
2021-07-06 22:57:42 +00:00
|
|
|
BytecodeViewer.updateBusyStatus(false);
|
2018-01-31 15:41:24 +00:00
|
|
|
return true;
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Opens a file, optional if it should append to the recent files menu
|
|
|
|
*
|
|
|
|
* @param files the file(s) you wish to open
|
|
|
|
* @param recentFiles if it should append to the recent files menu
|
|
|
|
*/
|
2021-07-06 23:08:08 +00:00
|
|
|
public static void openFiles(final File[] files, boolean recentFiles)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
if (recentFiles)
|
2021-07-01 09:06:12 +00:00
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
for (File f : files)
|
|
|
|
if (f.exists())
|
2021-06-29 09:41:29 +00:00
|
|
|
Settings.addRecentFile(f);
|
2021-07-01 09:06:12 +00:00
|
|
|
|
|
|
|
SettingsSerializer.saveSettingsAsync();
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-06 22:57:42 +00:00
|
|
|
BytecodeViewer.updateBusyStatus(true);
|
2021-06-21 11:13:11 +00:00
|
|
|
Configuration.needsReDump = true;
|
2021-07-01 09:48:10 +00:00
|
|
|
Thread t = new Thread(new ImportResource(files), "Import Resource");
|
2018-01-31 15:41:24 +00:00
|
|
|
t.start();
|
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Starts the specified plugin
|
|
|
|
*
|
|
|
|
* @param file the file of the plugin
|
|
|
|
*/
|
2021-07-06 23:08:08 +00:00
|
|
|
public static void startPlugin(File file)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
if (!file.exists())
|
2021-07-05 04:24:19 +00:00
|
|
|
{
|
|
|
|
BytecodeViewer.showMessage("The plugin file " + file.getAbsolutePath() + " could not be found.");
|
|
|
|
Settings.removeRecentPlugin(file);
|
2018-01-31 15:41:24 +00:00
|
|
|
return;
|
2021-07-05 04:24:19 +00:00
|
|
|
}
|
2021-07-08 08:50:57 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
PluginWriter writer = new PluginWriter(DiskReader.loadAsString(file.getAbsolutePath()), file.getName());
|
|
|
|
writer.setSourceFile(file);
|
|
|
|
writer.setVisible(true);
|
2021-07-21 15:20:38 +00:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2021-07-07 02:51:10 +00:00
|
|
|
BytecodeViewer.handleException(e);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-07-08 08:50:57 +00:00
|
|
|
|
2021-07-21 16:52:01 +00:00
|
|
|
Settings.addRecentPlugin(file);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
/**
|
|
|
|
* Send a message to alert the user
|
|
|
|
*
|
|
|
|
* @param message the message you need to send
|
|
|
|
*/
|
2021-07-06 23:08:08 +00:00
|
|
|
public static void showMessage(String message)
|
|
|
|
{
|
2021-07-21 16:20:25 +00:00
|
|
|
ExtendedJOptionPane.showMessageDialog(viewer, message);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-07-21 15:20:38 +00:00
|
|
|
|
2021-07-13 10:33:49 +00:00
|
|
|
/**
|
|
|
|
* Send a message to alert the user
|
|
|
|
*/
|
|
|
|
public static String showInput(String message)
|
|
|
|
{
|
2021-07-21 16:20:25 +00:00
|
|
|
return ExtendedJOptionPane.showInputDialog(viewer, message);
|
2021-07-13 10:33:49 +00:00
|
|
|
}
|
2021-07-06 22:57:42 +00:00
|
|
|
|
2021-07-27 10:17:57 +00:00
|
|
|
/**
|
|
|
|
* Send a message to alert the user
|
|
|
|
*/
|
|
|
|
public static String showInput(String message, String title, String initialMessage)
|
|
|
|
{
|
|
|
|
return (String) ExtendedJOptionPane.showInputDialog(viewer, message, title,
|
|
|
|
QUESTION_MESSAGE, null, null, initialMessage);
|
|
|
|
}
|
|
|
|
|
2021-07-06 22:57:42 +00:00
|
|
|
/**
|
|
|
|
* Alerts the user the program is running something in the background
|
|
|
|
*/
|
|
|
|
public static void updateBusyStatus(boolean busyStatus)
|
|
|
|
{
|
|
|
|
viewer.updateBusyStatus(busyStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears all active busy status icons
|
|
|
|
*/
|
|
|
|
public static void clearBusyStatus()
|
|
|
|
{
|
|
|
|
viewer.clearBusyStatus();
|
|
|
|
}
|
2021-07-06 23:53:37 +00:00
|
|
|
|
2021-07-07 02:46:12 +00:00
|
|
|
/**
|
|
|
|
* Returns true if there are no loaded resource classes
|
|
|
|
*/
|
|
|
|
public static boolean promptIfNoLoadedClasses()
|
|
|
|
{
|
|
|
|
if (BytecodeViewer.getLoadedClasses().isEmpty())
|
|
|
|
{
|
2021-07-18 21:36:00 +00:00
|
|
|
BytecodeViewer.showMessage(TranslatedStrings.FIRST_OPEN_A_CLASS.toString());
|
2021-07-07 02:46:12 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-07-16 20:55:03 +00:00
|
|
|
/**
|
|
|
|
* Returns true if there are no loaded resource classes
|
|
|
|
*/
|
|
|
|
public static boolean promptIfNoLoadedResources()
|
|
|
|
{
|
|
|
|
if (BytecodeViewer.resourceContainers.isEmpty())
|
|
|
|
{
|
2021-07-18 21:36:00 +00:00
|
|
|
BytecodeViewer.showMessage(TranslatedStrings.FIRST_OPEN_A_RESOURCE.toString());
|
2021-07-16 20:55:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-07-07 02:46:12 +00:00
|
|
|
/**
|
|
|
|
* Handle the exception by creating a new window for bug reporting
|
|
|
|
*/
|
|
|
|
public static void handleException(Throwable t)
|
|
|
|
{
|
2021-07-07 04:45:39 +00:00
|
|
|
handleException(t, ExceptionUI.KONLOCH);
|
2021-07-07 02:51:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle the exception by creating a new window for bug reporting
|
|
|
|
*/
|
|
|
|
public static void handleException(Throwable t, String author)
|
|
|
|
{
|
2021-07-07 04:45:39 +00:00
|
|
|
new ExceptionUI(t, author);
|
2021-07-07 02:46:12 +00:00
|
|
|
}
|
|
|
|
|
2021-07-13 10:33:49 +00:00
|
|
|
/**
|
|
|
|
* Refreshes the title on all of the opened tabs
|
|
|
|
*/
|
|
|
|
public static void updateAllClassNodeByteArrays()
|
|
|
|
{
|
2021-07-27 10:17:57 +00:00
|
|
|
resourceContainers.values().forEach(ResourceContainer::updateClassNodeBytes);
|
2021-07-13 10:33:49 +00:00
|
|
|
}
|
|
|
|
|
2021-07-06 23:53:37 +00:00
|
|
|
/**
|
|
|
|
* Refreshes the title on all of the opened tabs
|
|
|
|
*/
|
|
|
|
public static void refreshAllTabTitles()
|
|
|
|
{
|
|
|
|
for(int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++)
|
|
|
|
{
|
|
|
|
ResourceViewer viewer = ((TabbedPane) BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i)).resource;
|
|
|
|
viewer.refreshTitle();
|
|
|
|
}
|
|
|
|
}
|
2021-07-13 10:33:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Refreshes the title on all of the opened tabs
|
|
|
|
*/
|
|
|
|
public static void refreshAllTabs()
|
|
|
|
{
|
|
|
|
new Thread(()->
|
|
|
|
{
|
|
|
|
updateBusyStatus(true);
|
|
|
|
for (int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++)
|
|
|
|
{
|
|
|
|
ResourceViewer viewer = ((TabbedPane) BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i)).resource;
|
|
|
|
viewer.refresh(null);
|
|
|
|
}
|
|
|
|
updateBusyStatus(false);
|
|
|
|
}, "Refresh All Tabs").start();
|
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Resets the workspace with optional user input required
|
|
|
|
*
|
|
|
|
* @param ask if should require user input or not
|
|
|
|
*/
|
2021-07-06 22:57:42 +00:00
|
|
|
public static void resetWorkspace(boolean ask)
|
2021-06-26 18:10:55 +00:00
|
|
|
{
|
|
|
|
if (ask)
|
|
|
|
{
|
2021-07-21 16:20:25 +00:00
|
|
|
MultipleChoiceDialog dialog = new MultipleChoiceDialog(TranslatedStrings.RESET_TITLE.toString(),
|
|
|
|
TranslatedStrings.RESET_CONFIRM.toString(),
|
2021-07-18 19:11:34 +00:00
|
|
|
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
|
2021-07-06 22:57:42 +00:00
|
|
|
|
2021-07-21 15:20:38 +00:00
|
|
|
if (dialog.promptChoice() != 0)
|
2019-04-17 06:45:15 +00:00
|
|
|
return;
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-07-06 22:57:42 +00:00
|
|
|
|
2021-07-10 16:05:08 +00:00
|
|
|
resetWorkspace();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resets the workspace
|
|
|
|
*/
|
|
|
|
public static void resetWorkspace()
|
|
|
|
{
|
2021-07-11 12:33:18 +00:00
|
|
|
BytecodeViewer.resourceContainers.clear();
|
2021-07-10 16:05:08 +00:00
|
|
|
LazyNameUtil.reset();
|
|
|
|
BytecodeViewer.viewer.resourcePane.resetWorkspace();
|
|
|
|
BytecodeViewer.viewer.workPane.resetWorkspace();
|
|
|
|
BytecodeViewer.viewer.searchBoxPane.resetWorkspace();
|
|
|
|
BCV.getClassNodeLoader().clear();
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-07-01 09:06:12 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears the temp directory
|
|
|
|
*/
|
|
|
|
public static void cleanupAsync()
|
|
|
|
{
|
2021-07-01 09:48:10 +00:00
|
|
|
Thread cleanupThread = new Thread(BytecodeViewer::cleanup, "Cleanup");
|
2021-07-01 09:06:12 +00:00
|
|
|
cleanupThread.start();
|
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears the temp directory
|
|
|
|
*/
|
2021-07-01 09:06:12 +00:00
|
|
|
public static void cleanup()
|
|
|
|
{
|
2021-04-12 22:31:22 +00:00
|
|
|
File tempF = new File(tempDirectory);
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
FileUtils.deleteDirectory(tempF);
|
2021-07-06 22:57:42 +00:00
|
|
|
} catch (Exception ignored) { }
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
while (!tempF.exists()) // keep making dirs
|
|
|
|
tempF.mkdir();
|
|
|
|
}
|
2021-06-26 12:26:12 +00:00
|
|
|
|
2021-07-06 23:08:08 +00:00
|
|
|
/**
|
2021-07-06 23:53:37 +00:00
|
|
|
* because Smali and Baksmali System.exit if it failed
|
2021-07-06 23:08:08 +00:00
|
|
|
*/
|
2021-07-06 23:53:37 +00:00
|
|
|
public static void exit(int i) { }
|
2018-01-31 15:03:53 +00:00
|
|
|
}
|