From 3deb88ed13c129c0951f31d8c2bed2b9c906d178 Mon Sep 17 00:00:00 2001 From: GraxCode Date: Mon, 27 Apr 2020 13:45:43 +0200 Subject: [PATCH] configs --- build.gradle | 7 +- .../swing/panel/ConfigurationPanel.java | 105 +++++++++++++++++- .../threadtear/swing/tree/ClassTreePanel.java | 16 ++- 3 files changed, 123 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 04f740c..c6722d5 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'eclipse' } -version = '2.2.2' +version = '2.3.0' sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -23,6 +23,10 @@ repositories { dependencies { compile 'commons-io:commons-io:2.6' + compile 'org.apache.commons:commons-configuration2:2.7' + compile 'commons-beanutils:commons-beanutils:1.9.4' + + compile 'com.github.weisj:darklaf-core:2.0.3' compile 'com.github.weisj:darklaf-theme:2.0.3' compile 'com.github.weisj:darklaf-property-loader:2.0.3' @@ -33,6 +37,7 @@ dependencies { compile 'org.ow2.asm:asm-util:8.0.1' compile 'org.benf:cfr:0.149' + compile 'com.fifesoft:rsyntaxtextarea:3.1.1' } diff --git a/src/me/nov/threadtear/swing/panel/ConfigurationPanel.java b/src/me/nov/threadtear/swing/panel/ConfigurationPanel.java index 6579759..80fac71 100644 --- a/src/me/nov/threadtear/swing/panel/ConfigurationPanel.java +++ b/src/me/nov/threadtear/swing/panel/ConfigurationPanel.java @@ -2,6 +2,7 @@ import java.awt.GridLayout; import java.io.File; +import java.util.ArrayList; import javax.swing.BorderFactory; import javax.swing.JButton; @@ -11,10 +12,19 @@ import javax.swing.JPanel; import javax.swing.filechooser.FileNameExtensionFilter; +import org.apache.commons.configuration2.Configuration; +import org.apache.commons.configuration2.FileBasedConfiguration; +import org.apache.commons.configuration2.PropertiesConfiguration; +import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder; +import org.apache.commons.configuration2.builder.fluent.Parameters; + import com.github.weisj.darklaf.icons.IconLoader; import me.nov.threadtear.Threadtear; +import me.nov.threadtear.execution.Execution; import me.nov.threadtear.io.JarIO; +import me.nov.threadtear.swing.tree.component.ExecutionTreeNode; +import me.nov.threadtear.swing.tree.component.SortedTreeClassNode; public class ConfigurationPanel extends JPanel { private static final long serialVersionUID = 1L; @@ -50,10 +60,31 @@ private JPanel createCheckboxes() { private JPanel createBottomButtons() { JPanel panel = new JPanel(new GridLayout(1, 4, 16, 16)); JButton loadCfg = new JButton("Load config", IconLoader.get().loadSVGIcon("res/load_config.svg", false)); - loadCfg.setEnabled(false); + loadCfg.addActionListener(l -> { + JFileChooser jfc = new JFileChooser(System.getProperty("user.home")); + jfc.setAcceptAllFileFilterUsed(false); + jfc.setDialogTitle("Load config"); + jfc.setFileFilter(new FileNameExtensionFilter("Threadtear config file (*.tcf)", "tcf")); + int result = jfc.showOpenDialog(this); + if (result == JFileChooser.APPROVE_OPTION) { + File input = jfc.getSelectedFile(); + loadConfig(input); + } + }); panel.add(loadCfg); JButton saveCfg = new JButton("Save config", IconLoader.get().loadSVGIcon("res/save_config.svg", false)); - saveCfg.setEnabled(false); + saveCfg.addActionListener(l -> { + JFileChooser jfc = new JFileChooser(System.getProperty("user.home")); + jfc.setAcceptAllFileFilterUsed(false); + jfc.setSelectedFile(new File(jfc.getCurrentDirectory(), "config.tcf")); + jfc.setDialogTitle("Save config"); + jfc.setFileFilter(new FileNameExtensionFilter("Threadtear config file (*.tcf)", "tcf")); + int result = jfc.showSaveDialog(this); + if (result == JFileChooser.APPROVE_OPTION) { + File output = jfc.getSelectedFile(); + saveConfig(output); + } + }); panel.add(saveCfg); JButton save = new JButton("Save as jar file", IconLoader.get().loadSVGIcon("res/save.svg", false)); save.addActionListener(l -> { @@ -82,4 +113,74 @@ private JPanel createBottomButtons() { panel.add(run); return panel; } + + private void saveConfig(File output) { + try { + output.createNewFile(); + FileBasedConfigurationBuilder builder = new FileBasedConfigurationBuilder(PropertiesConfiguration.class) + .configure(new Parameters().fileBased().setFile(output)); + FileBasedConfiguration config = builder.getConfiguration(); + config.setProperty("verbose", verbose.isSelected()); + config.setProperty("no_sec", disableSecurity.isSelected()); + config.setProperty("rem_sig", removeSignature.isSelected()); + + File input = main.listPanel.classList.inputFile; + if (input != null) { + config.setProperty("file", input.getAbsolutePath()); + config.setProperty("ignored", main.listPanel.classList.classes.stream().filter(c -> !c.transform).map(c -> c.node.name).toArray(String[]::new)); + } + ArrayList executions = main.listPanel.executionList.getExecutions(); + if (!executions.isEmpty()) { + config.setProperty("executions", executions.stream().map(e -> e.getClass().getName()).toArray(String[]::new)); + } + builder.save(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void loadConfig(File input) { + try { + FileBasedConfigurationBuilder builder = new FileBasedConfigurationBuilder(PropertiesConfiguration.class) + .configure(new Parameters().fileBased().setFile(input)); + Configuration config = builder.getConfiguration(); + verbose.setSelected(config.getBoolean("verbose")); + watermark.setSelected(true); + disableSecurity.setSelected(config.getBoolean("no_sec")); + removeSignature.setSelected(config.getBoolean("rem_sig")); + if (config.containsKey("file")) { + File file = new File(config.getString("file")); + if (file.exists()) { + main.listPanel.classList.onJarLoad(file); + if (config.containsKey("ignored")) { + String[] ignored = config.getStringArray("ignored"); + for (String ignore : ignored) { + main.listPanel.classList.ignore(ignore); + } + main.listPanel.classList.refreshIgnored(); + main.listPanel.classList.model.reload(); + main.listPanel.classList.updateAllNames((SortedTreeClassNode) main.listPanel.classList.model.getRoot()); + main.listPanel.classList.repaint(); + } + } else { + JOptionPane.showMessageDialog(this, "Input file not found: " + file.getAbsolutePath()); + } + } + if (config.containsKey("executions")) { + String[] executions = config.getStringArray("executions"); + for (String execution : executions) { + try { + Execution e = (Execution) Class.forName(execution).newInstance(); + ((ExecutionTreeNode) main.listPanel.executionList.model.getRoot()).add(new ExecutionTreeNode(e, true)); + main.listPanel.executionList.model.reload(); + main.listPanel.executionList.repaint(); + } catch (Exception e) { + JOptionPane.showMessageDialog(this, "Execution failed to initialize: " + execution + " (" + e.toString() + ")"); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/src/me/nov/threadtear/swing/tree/ClassTreePanel.java b/src/me/nov/threadtear/swing/tree/ClassTreePanel.java index d53774c..99b2fa8 100644 --- a/src/me/nov/threadtear/swing/tree/ClassTreePanel.java +++ b/src/me/nov/threadtear/swing/tree/ClassTreePanel.java @@ -94,7 +94,6 @@ private JPanel createButtons() { ignoreChilds(tn); } refreshIgnored(); - repaint(); tree.grabFocus(); }); ignore.setEnabled(false); @@ -102,11 +101,24 @@ private JPanel createButtons() { return panel; } - private void refreshIgnored() { + public void refreshIgnored() { if (classes != null) { long disabled = classes.stream().filter(c -> !c.transform).count(); outerPanel.setBorder(BorderFactory.createTitledBorder("Class list - " + classes.size() + " classes (" + disabled + " ignored)")); } + repaint(); + } + + public void ignore(String className) { + classes.stream().filter(c -> c.node.name.equals(className)).forEach(c -> c.transform = false); + } + + public void updateAllNames(SortedTreeClassNode root) { + root.updateClassName(); + for (int i = 0; i < root.getChildCount(); i++) { + SortedTreeClassNode child = (SortedTreeClassNode) root.getChildAt(i); + updateAllNames(child); + } } private void ignoreChilds(SortedTreeClassNode node) {