Skip to content

Commit 182d64d

Browse files
committed
Start Of CLI Rewrite
1 parent 7e15a9e commit 182d64d

12 files changed

Lines changed: 402 additions & 42 deletions

File tree

src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
import the.bytecode.club.bytecodeviewer.bootloader.BootState;
3131
import the.bytecode.club.bytecodeviewer.bootloader.InstallFatJar;
3232
import the.bytecode.club.bytecodeviewer.bootloader.UpdateCheck;
33-
import the.bytecode.club.bytecodeviewer.cli.CLIAction;
34-
import the.bytecode.club.bytecodeviewer.cli.CommandLineInput;
33+
import the.bytecode.club.bytecodeviewer.cli.BCVCommandLine;
3534
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
3635
import the.bytecode.club.bytecodeviewer.gui.components.ExtendedJOptionPane;
3736
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
@@ -53,8 +52,6 @@
5352
import java.io.IOException;
5453
import java.util.List;
5554
import java.util.*;
56-
import java.util.concurrent.ExecutorService;
57-
import java.util.concurrent.Executors;
5855

5956
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
6057
import static the.bytecode.club.bytecodeviewer.Constants.*;
@@ -148,6 +145,9 @@ public class BytecodeViewer
148145
//GSON Reference
149146
public static Gson gson = new GsonBuilder().setPrettyPrinting().create();
150147

148+
//BCV CLI
149+
public static final BCVCommandLine CLI = new BCVCommandLine();
150+
151151
//Threads
152152
private static final Thread VERSION_CHECKER = new Thread(new UpdateCheck(), "Version Checker");
153153
private static final Thread PING_BACK = new Thread(new PingBack(), "Pingback");
@@ -184,20 +184,27 @@ public static void main(String[] args)
184184
System.err.println("Either deal with it or allow it using the -Djava.security.manager=allow parameter.");
185185
}
186186

187+
//init the CLI
188+
CLI.init(launchArgs);
189+
187190
try
188191
{
189192
//precache settings file
190193
SettingsSerializer.preloadSettingsFile();
191194

192195
//setup look and feel
193-
Configuration.lafTheme.setLAF();
196+
if(!CLI.isCLI())
197+
Configuration.lafTheme.setLAF();
194198

195199
//set swing specific system properties
196200
System.setProperty("swing.aatext", "true");
197201

198202
//setup swing components
199-
viewer = new MainViewerGUI();
200-
//SwingUtilities.updateComponentTreeUI(viewer);
203+
if(!CLI.isCLI())
204+
{
205+
viewer = new MainViewerGUI();
206+
//SwingUtilities.updateComponentTreeUI(viewer);
207+
}
201208

202209
//load settings and set swing components state
203210
SettingsSerializer.loadSettings();
@@ -207,11 +214,6 @@ public static void main(String[] args)
207214
if (!Settings.hasSetLanguageAsSystemLanguage)
208215
MiscUtils.setLanguage(MiscUtils.guessLanguage());
209216

210-
//handle CLI
211-
CLIAction isCLI = CommandLineInput.parseCommandLine(args);
212-
if (isCLI == CLIAction.STOP)
213-
return;
214-
215217
//load with shaded libraries
216218
if (FAT_JAR)
217219
{
@@ -220,20 +222,15 @@ public static void main(String[] args)
220222
else //load through bootloader
221223
{
222224
BOOT_CHECK.start();
223-
Boot.boot(args, isCLI != CLIAction.GUI);
225+
Boot.boot(args);
224226
}
225227

226228
//CLI arguments say spawn the GUI
227-
if (isCLI == CLIAction.GUI)
229+
if(!CLI.isCLI())
228230
{
229-
BytecodeViewer.boot(false);
231+
BytecodeViewer.boot();
230232
Configuration.bootState = BootState.GUI_SHOWING;
231233
}
232-
else //CLI arguments say keep it CLI
233-
{
234-
BytecodeViewer.boot(true);
235-
CommandLineInput.executeCommandLine(args);
236-
}
237234
}
238235
catch (Exception e)
239236
{
@@ -243,10 +240,8 @@ public static void main(String[] args)
243240

244241
/**
245242
* Boot after all of the libraries have been loaded
246-
*
247-
* @param cli is it running CLI mode or not
248243
*/
249-
public static void boot(boolean cli)
244+
public static void boot()
250245
{
251246
//delete files in the temp folder
252247
cleanupAsync();
@@ -265,8 +260,7 @@ public static void boot(boolean cli)
265260
TASK_MANAGER.start();
266261

267262
//setup the viewer
268-
if(!cli)
269-
viewer.calledAfterLoad();
263+
viewer.calledAfterLoad();
270264

271265
//setup the recent files
272266
Settings.resetRecentFilesMenu();
@@ -283,18 +277,16 @@ public static void boot(boolean cli)
283277
VERSION_CHECKER.start();
284278

285279
//show the main UI
286-
if (!cli)
287-
viewer.setVisible(true);
280+
viewer.setVisible(true);
288281

289282
//print startup time
290283
System.out.println("Start up took " + ((System.currentTimeMillis() - Configuration.BOOT_TIMESTAMP) / 1000) + " seconds");
291284

292285
//request focus on GUI for hotkeys on start
293-
if (!cli)
294-
viewer.requestFocus();
286+
viewer.requestFocus();
295287

296288
//open files from launch args
297-
if (!cli && launchArgs.length >= 1)
289+
if (launchArgs.length >= 1)
298290
for (String s : launchArgs)
299291
openFiles(new File[]{new File(s)}, true);
300292
}

src/main/java/the/bytecode/club/bytecodeviewer/SettingsSerializer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ public static void saveSettingsAsync()
4848

4949
public static synchronized void saveSettings()
5050
{
51+
if(BytecodeViewer.CLI.isCLI()) //do not save settings on CLI
52+
return;
53+
5154
try
5255
{
5356
DiskWriter.replaceFile(SETTINGS_NAME, "BCV: " + VERSION, false);
@@ -242,11 +245,15 @@ public static void preloadSettingsFile()
242245
//utilizes the Disk Reader's caching system.
243246
public static void loadSettings()
244247
{
248+
//do not load settings on CLI
245249
if (!settingsFileExists)
246250
return;
247251

248252
Settings.firstBoot = false;
249253

254+
if(BytecodeViewer.CLI.isCLI())
255+
return;
256+
250257
try
251258
{
252259
//parse the cached file from memory (from preload)

src/main/java/the/bytecode/club/bytecodeviewer/bootloader/Boot.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,14 @@ public class Boot
5959
private static final List<String> LIBS_FILE_LIST = new ArrayList<>();
6060
private static final List<String> URL_LIST = new ArrayList<>();
6161

62-
public static void boot(String[] args, boolean isCLI) throws Exception
62+
public static void boot(String[] args) throws Exception
6363
{
6464
bootstrap();
6565
ILoader<?> loader = findLoader();
6666

6767
screen = new InitialBootScreen();
6868

69-
if (!isCLI)
70-
SwingUtilities.invokeLater(() -> screen.setVisible(true));
69+
SwingUtilities.invokeLater(() -> screen.setVisible(true));
7170

7271
create(loader, args.length <= 0 || Boolean.parseBoolean(args[0]));
7372

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package the.bytecode.club.bytecodeviewer.cli;
2+
3+
import org.apache.commons.cli.*;
4+
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
5+
import the.bytecode.club.bytecodeviewer.cli.actions.commands.HelpCommand;
6+
import the.bytecode.club.bytecodeviewer.util.SleepUtil;
7+
8+
import java.io.File;
9+
import java.util.ArrayList;
10+
11+
/**
12+
* @author Konloch
13+
* @since 10/2/2024
14+
*/
15+
public class BCVCommandLine
16+
{
17+
18+
private final Options OPTIONS = new Options();
19+
private final CommandLineParser PARSER = new DefaultParser();
20+
private final ArrayList<CLICommand> COMMANDS = new ArrayList<>();
21+
private boolean isCLI = false;
22+
23+
public void init(String[] args)
24+
{
25+
OPTIONS.addOption("i", true, "sets the input.");
26+
OPTIONS.addOption("o", true, "sets the output.");
27+
OPTIONS.addOption("t", true, "sets the target class to decompile, append all to decomp all as zip.");
28+
OPTIONS.addOption("nowait", true, "won't wait the 5 seconds to allow the user to read the CLI.");
29+
30+
COMMANDS.add(new HelpCommand());
31+
32+
for(CLICommand command : COMMANDS)
33+
OPTIONS.addOption(command.name, command.hasArgs, command.description);
34+
35+
isCLI = containsCLICommand(args);
36+
37+
if(isCLI)
38+
parseCommandLine(args);
39+
}
40+
41+
private boolean containsCLICommand(String[] args)
42+
{
43+
if (args == null || args.length == 0)
44+
return false;
45+
46+
try
47+
{
48+
CommandLine cmd = PARSER.parse(OPTIONS, args);
49+
50+
for(CLICommand command : COMMANDS)
51+
if(cmd.hasOption(command.name) && command.isCLI)
52+
return true;
53+
}
54+
catch (Exception e)
55+
{
56+
e.printStackTrace();
57+
}
58+
59+
return false;
60+
}
61+
62+
private void parseCommandLine(String[] args)
63+
{
64+
try
65+
{
66+
CommandLine cmd = PARSER.parse(OPTIONS, args);
67+
68+
//TODO this is a backwards way of searching and will cause collisions
69+
// I'm sure the Apache CLI has a better way of navigating this
70+
71+
for(CLICommand command : COMMANDS)
72+
{
73+
if(cmd.hasOption(command.name))
74+
{
75+
command.runCommand(cmd);
76+
return;
77+
}
78+
}
79+
80+
handleCLIDecompilation(cmd);
81+
}
82+
catch (Exception e)
83+
{
84+
BytecodeViewer.handleException(e);
85+
}
86+
}
87+
88+
private void handleCLIDecompilation(CommandLine cmd)
89+
{
90+
if (cmd.getOptionValue("i") == null)
91+
{
92+
System.err.println("Set the input with -i");
93+
return;
94+
}
95+
96+
if (cmd.getOptionValue("o") == null)
97+
{
98+
System.err.println("Set the output with -o");
99+
return;
100+
}
101+
102+
if (cmd.getOptionValue("t") == null)
103+
{
104+
System.err.println("Set the target with -t");
105+
return;
106+
}
107+
108+
if (!cmd.hasOption("nowait"))
109+
SleepUtil.sleep(5 * 1000);
110+
111+
File input = new File(cmd.getOptionValue("i"));
112+
File output = new File(cmd.getOptionValue("o"));
113+
String decompiler = cmd.getOptionValue("decompiler");
114+
115+
if (!input.exists())
116+
{
117+
System.err.println(input.getAbsolutePath() + " does not exist.");
118+
return;
119+
}
120+
121+
if (output.exists())
122+
{
123+
System.err.println("WARNING: Deleted old " + output.getAbsolutePath() + ".");
124+
output.delete();
125+
}
126+
127+
//check if zip, jar, apk, dex, or class
128+
//if its zip/jar/apk/dex attempt unzip as whole zip
129+
//if its just class allow any
130+
131+
if (decompiler != null
132+
&& !decompiler.equalsIgnoreCase("procyon")
133+
&& !decompiler.equalsIgnoreCase("cfr")
134+
&& !decompiler.equalsIgnoreCase("fernflower")
135+
&& !decompiler.equalsIgnoreCase("krakatau")
136+
&& !decompiler.equalsIgnoreCase("krakatau-bytecode")
137+
&& !decompiler.equalsIgnoreCase("jd-gui")
138+
&& !decompiler.equalsIgnoreCase("smali")
139+
&& !decompiler.equalsIgnoreCase("asmifier"))
140+
{
141+
System.out.println("Error, no decompiler called '" + decompiler + "' found. Type -list" + " for the list");
142+
}
143+
144+
//TODO decompiling happens here
145+
}
146+
147+
public boolean isCLI()
148+
{
149+
return isCLI;
150+
}
151+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package the.bytecode.club.bytecodeviewer.cli;
2+
3+
import org.apache.commons.cli.CommandLine;
4+
5+
/**
6+
* @author Konloch
7+
* @since 10/2/2024
8+
*/
9+
public abstract class CLICommand
10+
{
11+
12+
public final String name;
13+
public final String description;
14+
public final boolean hasArgs;
15+
public final boolean isCLI;
16+
17+
protected CLICommand(String name, String description, boolean hasArgs, boolean isCLI)
18+
{
19+
this.name = name;
20+
this.description = description;
21+
this.hasArgs = hasArgs;
22+
this.isCLI = isCLI;
23+
}
24+
25+
public abstract void runCommand(CommandLine cmd);
26+
27+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package the.bytecode.club.bytecodeviewer.cli.actions.commands;
2+
3+
import org.apache.commons.cli.CommandLine;
4+
import the.bytecode.club.bytecodeviewer.Constants;
5+
import the.bytecode.club.bytecodeviewer.cli.CLICommand;
6+
7+
import java.io.File;
8+
9+
/**
10+
* @author Konloch
11+
* @since 10/2/2024
12+
*/
13+
public class CleanBootCommand extends CLICommand
14+
{
15+
16+
public CleanBootCommand()
17+
{
18+
super("cleanboot", "Deletes the BCV directory and continues to boot into the GUI", false, false);
19+
}
20+
21+
@Override
22+
public void runCommand(CommandLine cmd)
23+
{
24+
new File(Constants.getBCVDirectory()).delete();
25+
}
26+
}

0 commit comments

Comments
 (0)