Start Of CLI Rewrite
This commit is contained in:
parent
7e15a9ecb2
commit
182d64d997
|
@ -30,8 +30,7 @@ import the.bytecode.club.bytecodeviewer.bootloader.Boot;
|
|||
import the.bytecode.club.bytecodeviewer.bootloader.BootState;
|
||||
import the.bytecode.club.bytecodeviewer.bootloader.InstallFatJar;
|
||||
import the.bytecode.club.bytecodeviewer.bootloader.UpdateCheck;
|
||||
import the.bytecode.club.bytecodeviewer.cli.CLIAction;
|
||||
import the.bytecode.club.bytecodeviewer.cli.CommandLineInput;
|
||||
import the.bytecode.club.bytecodeviewer.cli.BCVCommandLine;
|
||||
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.ExtendedJOptionPane;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
|
||||
|
@ -53,8 +52,6 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
|
||||
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
||||
|
@ -148,6 +145,9 @@ public class BytecodeViewer
|
|||
//GSON Reference
|
||||
public static Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
//BCV CLI
|
||||
public static final BCVCommandLine CLI = new BCVCommandLine();
|
||||
|
||||
//Threads
|
||||
private static final Thread VERSION_CHECKER = new Thread(new UpdateCheck(), "Version Checker");
|
||||
private static final Thread PING_BACK = new Thread(new PingBack(), "Pingback");
|
||||
|
@ -184,20 +184,27 @@ public class BytecodeViewer
|
|||
System.err.println("Either deal with it or allow it using the -Djava.security.manager=allow parameter.");
|
||||
}
|
||||
|
||||
//init the CLI
|
||||
CLI.init(launchArgs);
|
||||
|
||||
try
|
||||
{
|
||||
//precache settings file
|
||||
SettingsSerializer.preloadSettingsFile();
|
||||
|
||||
//setup look and feel
|
||||
Configuration.lafTheme.setLAF();
|
||||
if(!CLI.isCLI())
|
||||
Configuration.lafTheme.setLAF();
|
||||
|
||||
//set swing specific system properties
|
||||
System.setProperty("swing.aatext", "true");
|
||||
|
||||
//setup swing components
|
||||
viewer = new MainViewerGUI();
|
||||
//SwingUtilities.updateComponentTreeUI(viewer);
|
||||
if(!CLI.isCLI())
|
||||
{
|
||||
viewer = new MainViewerGUI();
|
||||
//SwingUtilities.updateComponentTreeUI(viewer);
|
||||
}
|
||||
|
||||
//load settings and set swing components state
|
||||
SettingsSerializer.loadSettings();
|
||||
|
@ -207,11 +214,6 @@ public class BytecodeViewer
|
|||
if (!Settings.hasSetLanguageAsSystemLanguage)
|
||||
MiscUtils.setLanguage(MiscUtils.guessLanguage());
|
||||
|
||||
//handle CLI
|
||||
CLIAction isCLI = CommandLineInput.parseCommandLine(args);
|
||||
if (isCLI == CLIAction.STOP)
|
||||
return;
|
||||
|
||||
//load with shaded libraries
|
||||
if (FAT_JAR)
|
||||
{
|
||||
|
@ -220,20 +222,15 @@ public class BytecodeViewer
|
|||
else //load through bootloader
|
||||
{
|
||||
BOOT_CHECK.start();
|
||||
Boot.boot(args, isCLI != CLIAction.GUI);
|
||||
Boot.boot(args);
|
||||
}
|
||||
|
||||
//CLI arguments say spawn the GUI
|
||||
if (isCLI == CLIAction.GUI)
|
||||
if(!CLI.isCLI())
|
||||
{
|
||||
BytecodeViewer.boot(false);
|
||||
BytecodeViewer.boot();
|
||||
Configuration.bootState = BootState.GUI_SHOWING;
|
||||
}
|
||||
else //CLI arguments say keep it CLI
|
||||
{
|
||||
BytecodeViewer.boot(true);
|
||||
CommandLineInput.executeCommandLine(args);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -243,10 +240,8 @@ public class BytecodeViewer
|
|||
|
||||
/**
|
||||
* Boot after all of the libraries have been loaded
|
||||
*
|
||||
* @param cli is it running CLI mode or not
|
||||
*/
|
||||
public static void boot(boolean cli)
|
||||
public static void boot()
|
||||
{
|
||||
//delete files in the temp folder
|
||||
cleanupAsync();
|
||||
|
@ -265,8 +260,7 @@ public class BytecodeViewer
|
|||
TASK_MANAGER.start();
|
||||
|
||||
//setup the viewer
|
||||
if(!cli)
|
||||
viewer.calledAfterLoad();
|
||||
viewer.calledAfterLoad();
|
||||
|
||||
//setup the recent files
|
||||
Settings.resetRecentFilesMenu();
|
||||
|
@ -283,18 +277,16 @@ public class BytecodeViewer
|
|||
VERSION_CHECKER.start();
|
||||
|
||||
//show the main UI
|
||||
if (!cli)
|
||||
viewer.setVisible(true);
|
||||
viewer.setVisible(true);
|
||||
|
||||
//print startup time
|
||||
System.out.println("Start up took " + ((System.currentTimeMillis() - Configuration.BOOT_TIMESTAMP) / 1000) + " seconds");
|
||||
|
||||
//request focus on GUI for hotkeys on start
|
||||
if (!cli)
|
||||
viewer.requestFocus();
|
||||
viewer.requestFocus();
|
||||
|
||||
//open files from launch args
|
||||
if (!cli && launchArgs.length >= 1)
|
||||
if (launchArgs.length >= 1)
|
||||
for (String s : launchArgs)
|
||||
openFiles(new File[]{new File(s)}, true);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ public class SettingsSerializer
|
|||
|
||||
public static synchronized void saveSettings()
|
||||
{
|
||||
if(BytecodeViewer.CLI.isCLI()) //do not save settings on CLI
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
DiskWriter.replaceFile(SETTINGS_NAME, "BCV: " + VERSION, false);
|
||||
|
@ -242,11 +245,15 @@ public class SettingsSerializer
|
|||
//utilizes the Disk Reader's caching system.
|
||||
public static void loadSettings()
|
||||
{
|
||||
//do not load settings on CLI
|
||||
if (!settingsFileExists)
|
||||
return;
|
||||
|
||||
Settings.firstBoot = false;
|
||||
|
||||
if(BytecodeViewer.CLI.isCLI())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
//parse the cached file from memory (from preload)
|
||||
|
|
|
@ -59,15 +59,14 @@ public class Boot
|
|||
private static final List<String> LIBS_FILE_LIST = new ArrayList<>();
|
||||
private static final List<String> URL_LIST = new ArrayList<>();
|
||||
|
||||
public static void boot(String[] args, boolean isCLI) throws Exception
|
||||
public static void boot(String[] args) throws Exception
|
||||
{
|
||||
bootstrap();
|
||||
ILoader<?> loader = findLoader();
|
||||
|
||||
screen = new InitialBootScreen();
|
||||
|
||||
if (!isCLI)
|
||||
SwingUtilities.invokeLater(() -> screen.setVisible(true));
|
||||
SwingUtilities.invokeLater(() -> screen.setVisible(true));
|
||||
|
||||
create(loader, args.length <= 0 || Boolean.parseBoolean(args[0]));
|
||||
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
package the.bytecode.club.bytecodeviewer.cli;
|
||||
|
||||
import org.apache.commons.cli.*;
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.cli.actions.commands.HelpCommand;
|
||||
import the.bytecode.club.bytecodeviewer.util.SleepUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 10/2/2024
|
||||
*/
|
||||
public class BCVCommandLine
|
||||
{
|
||||
|
||||
private final Options OPTIONS = new Options();
|
||||
private final CommandLineParser PARSER = new DefaultParser();
|
||||
private final ArrayList<CLICommand> COMMANDS = new ArrayList<>();
|
||||
private boolean isCLI = false;
|
||||
|
||||
public void init(String[] args)
|
||||
{
|
||||
OPTIONS.addOption("i", true, "sets the input.");
|
||||
OPTIONS.addOption("o", true, "sets the output.");
|
||||
OPTIONS.addOption("t", true, "sets the target class to decompile, append all to decomp all as zip.");
|
||||
OPTIONS.addOption("nowait", true, "won't wait the 5 seconds to allow the user to read the CLI.");
|
||||
|
||||
COMMANDS.add(new HelpCommand());
|
||||
|
||||
for(CLICommand command : COMMANDS)
|
||||
OPTIONS.addOption(command.name, command.hasArgs, command.description);
|
||||
|
||||
isCLI = containsCLICommand(args);
|
||||
|
||||
if(isCLI)
|
||||
parseCommandLine(args);
|
||||
}
|
||||
|
||||
private boolean containsCLICommand(String[] args)
|
||||
{
|
||||
if (args == null || args.length == 0)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
CommandLine cmd = PARSER.parse(OPTIONS, args);
|
||||
|
||||
for(CLICommand command : COMMANDS)
|
||||
if(cmd.hasOption(command.name) && command.isCLI)
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void parseCommandLine(String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
CommandLine cmd = PARSER.parse(OPTIONS, args);
|
||||
|
||||
//TODO this is a backwards way of searching and will cause collisions
|
||||
// I'm sure the Apache CLI has a better way of navigating this
|
||||
|
||||
for(CLICommand command : COMMANDS)
|
||||
{
|
||||
if(cmd.hasOption(command.name))
|
||||
{
|
||||
command.runCommand(cmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
handleCLIDecompilation(cmd);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BytecodeViewer.handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCLIDecompilation(CommandLine cmd)
|
||||
{
|
||||
if (cmd.getOptionValue("i") == null)
|
||||
{
|
||||
System.err.println("Set the input with -i");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd.getOptionValue("o") == null)
|
||||
{
|
||||
System.err.println("Set the output with -o");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd.getOptionValue("t") == null)
|
||||
{
|
||||
System.err.println("Set the target with -t");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cmd.hasOption("nowait"))
|
||||
SleepUtil.sleep(5 * 1000);
|
||||
|
||||
File input = new File(cmd.getOptionValue("i"));
|
||||
File output = new File(cmd.getOptionValue("o"));
|
||||
String decompiler = cmd.getOptionValue("decompiler");
|
||||
|
||||
if (!input.exists())
|
||||
{
|
||||
System.err.println(input.getAbsolutePath() + " does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (output.exists())
|
||||
{
|
||||
System.err.println("WARNING: Deleted old " + output.getAbsolutePath() + ".");
|
||||
output.delete();
|
||||
}
|
||||
|
||||
//check if zip, jar, apk, dex, or class
|
||||
//if its zip/jar/apk/dex attempt unzip as whole zip
|
||||
//if its just class allow any
|
||||
|
||||
if (decompiler != null
|
||||
&& !decompiler.equalsIgnoreCase("procyon")
|
||||
&& !decompiler.equalsIgnoreCase("cfr")
|
||||
&& !decompiler.equalsIgnoreCase("fernflower")
|
||||
&& !decompiler.equalsIgnoreCase("krakatau")
|
||||
&& !decompiler.equalsIgnoreCase("krakatau-bytecode")
|
||||
&& !decompiler.equalsIgnoreCase("jd-gui")
|
||||
&& !decompiler.equalsIgnoreCase("smali")
|
||||
&& !decompiler.equalsIgnoreCase("asmifier"))
|
||||
{
|
||||
System.out.println("Error, no decompiler called '" + decompiler + "' found. Type -list" + " for the list");
|
||||
}
|
||||
|
||||
//TODO decompiling happens here
|
||||
}
|
||||
|
||||
public boolean isCLI()
|
||||
{
|
||||
return isCLI;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package the.bytecode.club.bytecodeviewer.cli;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 10/2/2024
|
||||
*/
|
||||
public abstract class CLICommand
|
||||
{
|
||||
|
||||
public final String name;
|
||||
public final String description;
|
||||
public final boolean hasArgs;
|
||||
public final boolean isCLI;
|
||||
|
||||
protected CLICommand(String name, String description, boolean hasArgs, boolean isCLI)
|
||||
{
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.hasArgs = hasArgs;
|
||||
this.isCLI = isCLI;
|
||||
}
|
||||
|
||||
public abstract void runCommand(CommandLine cmd);
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package the.bytecode.club.bytecodeviewer.cli.actions.commands;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import the.bytecode.club.bytecodeviewer.Constants;
|
||||
import the.bytecode.club.bytecodeviewer.cli.CLICommand;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 10/2/2024
|
||||
*/
|
||||
public class CleanBootCommand extends CLICommand
|
||||
{
|
||||
|
||||
public CleanBootCommand()
|
||||
{
|
||||
super("cleanboot", "Deletes the BCV directory and continues to boot into the GUI", false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandLine cmd)
|
||||
{
|
||||
new File(Constants.getBCVDirectory()).delete();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package the.bytecode.club.bytecodeviewer.cli.actions.commands;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import the.bytecode.club.bytecodeviewer.Constants;
|
||||
import the.bytecode.club.bytecodeviewer.cli.CLICommand;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.cli.CLIAction.GUI;
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 10/2/2024
|
||||
*/
|
||||
public class CleanCommand extends CLICommand
|
||||
{
|
||||
|
||||
public CleanCommand()
|
||||
{
|
||||
super("clean", "Deletes the BCV directory", false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandLine cmd)
|
||||
{
|
||||
new File(Constants.getBCVDirectory()).delete();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package the.bytecode.club.bytecodeviewer.cli.actions.commands;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import the.bytecode.club.bytecodeviewer.cli.CLICommand;
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 10/2/2024
|
||||
*/
|
||||
public class DecompilerCommand extends CLICommand
|
||||
{
|
||||
|
||||
public DecompilerCommand()
|
||||
{
|
||||
super("decompiler", "sets the decompiler, procyon by default.", true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandLine cmd)
|
||||
{
|
||||
for (String s : new String[]{
|
||||
"==BCV CLI Commands==",
|
||||
"-help Displays the help menu",
|
||||
"-list Displays the available decompilers",
|
||||
"-decompiler <decompiler> Selects the decompiler, procyon by default",
|
||||
"-i <input file> Selects the input file",
|
||||
"-o <output file> Selects the output file",
|
||||
"-t <target classname> Must either be the fully qualified classname or \"all\" to decompile all as zip",
|
||||
"-nowait Doesn't wait for the user to read the CLI messages",
|
||||
"==BCV GUI Commands==",
|
||||
"-clean Deletes the BCV directory",
|
||||
"-english Forces English language translations"
|
||||
})
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package the.bytecode.club.bytecodeviewer.cli.actions.commands;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||
import the.bytecode.club.bytecodeviewer.Constants;
|
||||
import the.bytecode.club.bytecodeviewer.cli.CLICommand;
|
||||
import the.bytecode.club.bytecodeviewer.translation.Language;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 10/2/2024
|
||||
*/
|
||||
public class EnglishCommand extends CLICommand
|
||||
{
|
||||
|
||||
public EnglishCommand()
|
||||
{
|
||||
super("english", "Forces English language translations and continues to boot into the GUI", false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandLine cmd)
|
||||
{
|
||||
Configuration.language = Language.ENGLISH;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package the.bytecode.club.bytecodeviewer.cli.actions.commands;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import the.bytecode.club.bytecodeviewer.cli.CLICommand;
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 10/2/2024
|
||||
*/
|
||||
public class HelpCommand extends CLICommand
|
||||
{
|
||||
|
||||
public HelpCommand()
|
||||
{
|
||||
super("help", "prints the help menu.", false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandLine cmd)
|
||||
{
|
||||
for (String s : new String[]{
|
||||
"==BCV CLI Commands==",
|
||||
"-clean Deletes the BCV directory",
|
||||
"-help Displays the help menu",
|
||||
"-list Displays the available CLI decompilers",
|
||||
"-decompiler <decompiler> Selects the decompiler, procyon by default",
|
||||
"-i <input file> Selects the input file",
|
||||
"-o <output file> Selects the output file",
|
||||
"-t <target classname> Must either be the fully qualified classname or \"all\" to decompile all as zip",
|
||||
"-nowait Doesn't wait for the user to read the CLI messages",
|
||||
"==BCV GUI Commands==",
|
||||
"-cleanboot Deletes the BCV directory and continues to boot into the GUI",
|
||||
"-english Forces English language translations"
|
||||
})
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package the.bytecode.club.bytecodeviewer.cli.actions.commands;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import the.bytecode.club.bytecodeviewer.cli.CLICommand;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.Constants.VERSION;
|
||||
|
||||
/**
|
||||
* @author Konloch
|
||||
* @since 10/2/2024
|
||||
*/
|
||||
public class ListCommand extends CLICommand
|
||||
{
|
||||
|
||||
public ListCommand()
|
||||
{
|
||||
super("list", "lists all the available decompilers for BCV " + VERSION + ".", false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandLine cmd)
|
||||
{
|
||||
for (String s : new String[]{
|
||||
"==BCV CLI Decompilers==",
|
||||
"Procyon",
|
||||
"CFR",
|
||||
"FernFlower",
|
||||
"Krakatau",
|
||||
"Krakatau-Bytecode",
|
||||
"JD-GUI",
|
||||
"Smali",
|
||||
"ASMifier"
|
||||
})
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
|
@ -111,15 +111,8 @@ public class BootCheck implements Runnable
|
|||
|
||||
Boot.hide();
|
||||
|
||||
CLIAction CLI = CommandLineInput.parseCommandLine(BytecodeViewer.launchArgs);
|
||||
|
||||
if (CLI == CLIAction.GUI)
|
||||
BytecodeViewer.boot(false);
|
||||
else
|
||||
{
|
||||
BytecodeViewer.boot(true);
|
||||
CommandLineInput.executeCommandLine(BytecodeViewer.launchArgs);
|
||||
}
|
||||
//Boot directly into GUI
|
||||
BytecodeViewer.boot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user