Start Of CLI Rewrite

This commit is contained in:
Konloch 2024-10-02 08:30:00 -06:00
parent 7e15a9ecb2
commit 182d64d997

AI 샘플 코드 생성 중입니다

Loading...
12 changed files with 402 additions and 42 deletions

View File

@ -30,8 +30,7 @@ import the.bytecode.club.bytecodeviewer.bootloader.Boot;
import the.bytecode.club.bytecodeviewer.bootloader.BootState; import the.bytecode.club.bytecodeviewer.bootloader.BootState;
import the.bytecode.club.bytecodeviewer.bootloader.InstallFatJar; import the.bytecode.club.bytecodeviewer.bootloader.InstallFatJar;
import the.bytecode.club.bytecodeviewer.bootloader.UpdateCheck; import the.bytecode.club.bytecodeviewer.bootloader.UpdateCheck;
import the.bytecode.club.bytecodeviewer.cli.CLIAction; import the.bytecode.club.bytecodeviewer.cli.BCVCommandLine;
import the.bytecode.club.bytecodeviewer.cli.CommandLineInput;
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI; import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
import the.bytecode.club.bytecodeviewer.gui.components.ExtendedJOptionPane; import the.bytecode.club.bytecodeviewer.gui.components.ExtendedJOptionPane;
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog; import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
@ -53,8 +52,6 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static javax.swing.JOptionPane.QUESTION_MESSAGE; import static javax.swing.JOptionPane.QUESTION_MESSAGE;
import static the.bytecode.club.bytecodeviewer.Constants.*; import static the.bytecode.club.bytecodeviewer.Constants.*;
@ -148,6 +145,9 @@ public class BytecodeViewer
//GSON Reference //GSON Reference
public static Gson gson = new GsonBuilder().setPrettyPrinting().create(); public static Gson gson = new GsonBuilder().setPrettyPrinting().create();
//BCV CLI
public static final BCVCommandLine CLI = new BCVCommandLine();
//Threads //Threads
private static final Thread VERSION_CHECKER = new Thread(new UpdateCheck(), "Version Checker"); private static final Thread VERSION_CHECKER = new Thread(new UpdateCheck(), "Version Checker");
private static final Thread PING_BACK = new Thread(new PingBack(), "Pingback"); 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."); System.err.println("Either deal with it or allow it using the -Djava.security.manager=allow parameter.");
} }
//init the CLI
CLI.init(launchArgs);
try try
{ {
//precache settings file //precache settings file
SettingsSerializer.preloadSettingsFile(); SettingsSerializer.preloadSettingsFile();
//setup look and feel //setup look and feel
Configuration.lafTheme.setLAF(); if(!CLI.isCLI())
Configuration.lafTheme.setLAF();
//set swing specific system properties //set swing specific system properties
System.setProperty("swing.aatext", "true"); System.setProperty("swing.aatext", "true");
//setup swing components //setup swing components
viewer = new MainViewerGUI(); if(!CLI.isCLI())
//SwingUtilities.updateComponentTreeUI(viewer); {
viewer = new MainViewerGUI();
//SwingUtilities.updateComponentTreeUI(viewer);
}
//load settings and set swing components state //load settings and set swing components state
SettingsSerializer.loadSettings(); SettingsSerializer.loadSettings();
@ -207,11 +214,6 @@ public class BytecodeViewer
if (!Settings.hasSetLanguageAsSystemLanguage) if (!Settings.hasSetLanguageAsSystemLanguage)
MiscUtils.setLanguage(MiscUtils.guessLanguage()); MiscUtils.setLanguage(MiscUtils.guessLanguage());
//handle CLI
CLIAction isCLI = CommandLineInput.parseCommandLine(args);
if (isCLI == CLIAction.STOP)
return;
//load with shaded libraries //load with shaded libraries
if (FAT_JAR) if (FAT_JAR)
{ {
@ -220,20 +222,15 @@ public class BytecodeViewer
else //load through bootloader else //load through bootloader
{ {
BOOT_CHECK.start(); BOOT_CHECK.start();
Boot.boot(args, isCLI != CLIAction.GUI); Boot.boot(args);
} }
//CLI arguments say spawn the GUI //CLI arguments say spawn the GUI
if (isCLI == CLIAction.GUI) if(!CLI.isCLI())
{ {
BytecodeViewer.boot(false); BytecodeViewer.boot();
Configuration.bootState = BootState.GUI_SHOWING; Configuration.bootState = BootState.GUI_SHOWING;
} }
else //CLI arguments say keep it CLI
{
BytecodeViewer.boot(true);
CommandLineInput.executeCommandLine(args);
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -243,10 +240,8 @@ public class BytecodeViewer
/** /**
* Boot after all of the libraries have been loaded * 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 //delete files in the temp folder
cleanupAsync(); cleanupAsync();
@ -265,8 +260,7 @@ public class BytecodeViewer
TASK_MANAGER.start(); TASK_MANAGER.start();
//setup the viewer //setup the viewer
if(!cli) viewer.calledAfterLoad();
viewer.calledAfterLoad();
//setup the recent files //setup the recent files
Settings.resetRecentFilesMenu(); Settings.resetRecentFilesMenu();
@ -283,18 +277,16 @@ public class BytecodeViewer
VERSION_CHECKER.start(); VERSION_CHECKER.start();
//show the main UI //show the main UI
if (!cli) viewer.setVisible(true);
viewer.setVisible(true);
//print startup time //print startup time
System.out.println("Start up took " + ((System.currentTimeMillis() - Configuration.BOOT_TIMESTAMP) / 1000) + " seconds"); System.out.println("Start up took " + ((System.currentTimeMillis() - Configuration.BOOT_TIMESTAMP) / 1000) + " seconds");
//request focus on GUI for hotkeys on start //request focus on GUI for hotkeys on start
if (!cli) viewer.requestFocus();
viewer.requestFocus();
//open files from launch args //open files from launch args
if (!cli && launchArgs.length >= 1) if (launchArgs.length >= 1)
for (String s : launchArgs) for (String s : launchArgs)
openFiles(new File[]{new File(s)}, true); openFiles(new File[]{new File(s)}, true);
} }

View File

@ -48,6 +48,9 @@ public class SettingsSerializer
public static synchronized void saveSettings() public static synchronized void saveSettings()
{ {
if(BytecodeViewer.CLI.isCLI()) //do not save settings on CLI
return;
try try
{ {
DiskWriter.replaceFile(SETTINGS_NAME, "BCV: " + VERSION, false); DiskWriter.replaceFile(SETTINGS_NAME, "BCV: " + VERSION, false);
@ -242,11 +245,15 @@ public class SettingsSerializer
//utilizes the Disk Reader's caching system. //utilizes the Disk Reader's caching system.
public static void loadSettings() public static void loadSettings()
{ {
//do not load settings on CLI
if (!settingsFileExists) if (!settingsFileExists)
return; return;
Settings.firstBoot = false; Settings.firstBoot = false;
if(BytecodeViewer.CLI.isCLI())
return;
try try
{ {
//parse the cached file from memory (from preload) //parse the cached file from memory (from preload)

View File

@ -59,15 +59,14 @@ public class Boot
private static final List<String> LIBS_FILE_LIST = new ArrayList<>(); private static final List<String> LIBS_FILE_LIST = new ArrayList<>();
private static final List<String> URL_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(); bootstrap();
ILoader<?> loader = findLoader(); ILoader<?> loader = findLoader();
screen = new InitialBootScreen(); screen = new InitialBootScreen();
if (!isCLI) SwingUtilities.invokeLater(() -> screen.setVisible(true));
SwingUtilities.invokeLater(() -> screen.setVisible(true));
create(loader, args.length <= 0 || Boolean.parseBoolean(args[0])); create(loader, args.length <= 0 || Boolean.parseBoolean(args[0]));

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -111,15 +111,8 @@ public class BootCheck implements Runnable
Boot.hide(); Boot.hide();
CLIAction CLI = CommandLineInput.parseCommandLine(BytecodeViewer.launchArgs); //Boot directly into GUI
BytecodeViewer.boot();
if (CLI == CLIAction.GUI)
BytecodeViewer.boot(false);
else
{
BytecodeViewer.boot(true);
CommandLineInput.executeCommandLine(BytecodeViewer.launchArgs);
}
} }
} }
} }