From 1ec1ece9efbcc668b9c79de58d79b3176da1b7ca Mon Sep 17 00:00:00 2001 From: YanisBft Date: Tue, 15 Jun 2021 23:30:03 +0200 Subject: Structure panel options (#400) * Structure panel options * changes * always show inner classes in the tree * workaround for toString() and similar * show constructor methods depending on the class obfuscation * use ListCellRenderer instead of toString * list cell renderer--- .../cuchaz/enigma/analysis/StructureTreeNode.java | 54 ++++++++++++++------ .../enigma/analysis/StructureTreeOptions.java | 59 ++++++++++++++++++++++ enigma/src/main/resources/lang/en_us.json | 14 ++++- enigma/src/main/resources/lang/fr_fr.json | 14 ++++- enigma/src/main/resources/lang/ja_jp.json | 1 - 5 files changed, 124 insertions(+), 18 deletions(-) create mode 100644 enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeOptions.java (limited to 'enigma/src') diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java index b4343c1..aea7618 100644 --- a/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java +++ b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java @@ -10,7 +10,9 @@ import cuchaz.enigma.translation.representation.entry.*; import javax.swing.tree.DefaultMutableTreeNode; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.stream.Stream; public class StructureTreeNode extends DefaultMutableTreeNode { private final List nameProposalServices; @@ -32,25 +34,47 @@ public class StructureTreeNode extends DefaultMutableTreeNode { return this.entry; } - public void load(EnigmaProject project, boolean hideDeobfuscated) { - List children = project.getJarIndex().getChildrenByClass().get(this.parentEntry); - - for (ParentedEntry child : children) { + public void load(EnigmaProject project, StructureTreeOptions options) { + Stream children = project.getJarIndex().getChildrenByClass().get(this.parentEntry).stream(); + + children = switch (options.obfuscationVisibility()) { + case ALL -> children; + case OBFUSCATED -> children + // remove deobfuscated members if only obfuscated, unless it's an inner class + .filter(e -> (e instanceof ClassEntry) || (project.isObfuscated(e) && project.isRenamable(e))) + // keep constructor methods if the class is obfuscated + .filter(e -> !(e instanceof MethodEntry m && m.isConstructor()) || project.isObfuscated(e.getParent())); + case DEOBFUSCATED -> children.filter(e -> (e instanceof ClassEntry) + || (!project.isObfuscated(e) && project.isRenamable(e)) + // keep constructor methods if the class is deobfuscated + || (e instanceof MethodEntry m && m.isConstructor()) && !project.isObfuscated(e.getParent())); + }; + + children = switch (options.documentationVisibility()) { + case ALL -> children; + // TODO remove EntryRemapper.deobfuscate() calls when javadocs will no longer be tied to deobfuscation + case DOCUMENTED -> children.filter(e -> (e instanceof ClassEntry) || (project.getMapper().deobfuscate(e).getJavadocs() != null && !project.getMapper().deobfuscate(e).getJavadocs().isBlank())); + case NON_DOCUMENTED -> children.filter(e -> (e instanceof ClassEntry) || (project.getMapper().deobfuscate(e).getJavadocs() == null || project.getMapper().deobfuscate(e).getJavadocs().isBlank())); + }; + + children = switch (options.sortingOrder()) { + case DEFAULT -> children; + case A_Z -> children.sorted(Comparator.comparing(e -> (e instanceof MethodEntry m && m.isConstructor()) + // compare the class name when the entry is a constructor + ? project.getMapper().deobfuscate(e.getParent()).getSimpleName().toLowerCase() + : project.getMapper().deobfuscate(e).getSimpleName().toLowerCase())); + case Z_A -> children.sorted(Comparator.comparing(e -> (e instanceof MethodEntry m && m.isConstructor()) + ? project.getMapper().deobfuscate(((ParentedEntry) e).getParent()).getSimpleName().toLowerCase() + : project.getMapper().deobfuscate((ParentedEntry) e).getSimpleName().toLowerCase()) + .reversed()); + }; + + for (ParentedEntry child : children.toList()) { StructureTreeNode childNode = new StructureTreeNode(project, this.parentEntry, child); if (child instanceof ClassEntry) { childNode = new StructureTreeNode(project, (ClassEntry) child, child); - childNode.load(project, hideDeobfuscated); - } - - // don't add deobfuscated members if hideDeobfuscated is true, unless it's an inner class - if (hideDeobfuscated && !project.isObfuscated(child) && !(child instanceof ClassEntry)) { - continue; - } - - // don't add constructor methods if hideDeobfuscated is true - if (hideDeobfuscated && (child instanceof MethodEntry method) && method.isConstructor()) { - continue; + childNode.load(project, options); } this.add(childNode); diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeOptions.java b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeOptions.java new file mode 100644 index 0000000..cfc80b4 --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeOptions.java @@ -0,0 +1,59 @@ +package cuchaz.enigma.analysis; + +public record StructureTreeOptions( + ObfuscationVisibility obfuscationVisibility, + DocumentationVisibility documentationVisibility, + SortingOrder sortingOrder) { + + public enum ObfuscationVisibility implements Option { + ALL("structure.options.obfuscation.all"), + OBFUSCATED("structure.options.obfuscation.obfuscated"), + DEOBFUSCATED("structure.options.obfuscation.deobfuscated"); + + private final String translationKey; + + ObfuscationVisibility(String translationKey) { + this.translationKey = translationKey; + } + + public String getTranslationKey() { + return this.translationKey; + } + } + + public enum DocumentationVisibility implements Option { + ALL("structure.options.documentation.all"), + DOCUMENTED("structure.options.documentation.documented"), + NON_DOCUMENTED("structure.options.documentation.non_documented"); + + private final String translationKey; + + DocumentationVisibility(String translationKey) { + this.translationKey = translationKey; + } + + public String getTranslationKey() { + return this.translationKey; + } + } + + public enum SortingOrder implements Option { + DEFAULT("structure.options.sorting.default"), + A_Z("structure.options.sorting.a_z"), + Z_A("structure.options.sorting.z_a"); + + private final String translationKey; + + SortingOrder(String translationKey) { + this.translationKey = translationKey; + } + + public String getTranslationKey() { + return this.translationKey; + } + } + + public interface Option { + String getTranslationKey(); + } +} diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json index 57b2ca8..35a4d93 100644 --- a/enigma/src/main/resources/lang/en_us.json +++ b/enigma/src/main/resources/lang/en_us.json @@ -106,13 +106,25 @@ "info_panel.editor.class.decompiling": "(decompiling...)", "info_panel.editor.class.not_found": "Unable to find class:", "info_panel.tree.structure": "Structure", - "info_panel.tree.structure.hide_deobfuscated": "Hide deobfuscated members", "info_panel.tree.inheritance": "Inheritance", "info_panel.tree.implementations": "Implementations", "info_panel.tree.calls": "Call Graph", "popup.copied": "Copied!", + "structure.options.obfuscation": "Obfuscation Visibility", + "structure.options.obfuscation.all": "All", + "structure.options.obfuscation.obfuscated": "Only obfuscated", + "structure.options.obfuscation.deobfuscated": "Only deobfuscated", + "structure.options.documentation": "Documentation Visibility", + "structure.options.documentation.all": "All", + "structure.options.documentation.documented": "Only documented", + "structure.options.documentation.non_documented": "Only non documented", + "structure.options.sorting": "Sorting Order", + "structure.options.sorting.default": "Default", + "structure.options.sorting.a_z": "A to Z", + "structure.options.sorting.z_a": "Z to A", + "log_panel.messages": "Messages", "log_panel.users": "Users", diff --git a/enigma/src/main/resources/lang/fr_fr.json b/enigma/src/main/resources/lang/fr_fr.json index 5c46c87..ea1a20f 100644 --- a/enigma/src/main/resources/lang/fr_fr.json +++ b/enigma/src/main/resources/lang/fr_fr.json @@ -106,13 +106,25 @@ "info_panel.editor.class.decompiling": "(décompilation...)", "info_panel.editor.class.not_found": "Impossible de trouver la classe :", "info_panel.tree.structure": "Structure", - "info_panel.tree.structure.hide_deobfuscated": "Masquer les membres déobfusqués", "info_panel.tree.inheritance": "Héritage", "info_panel.tree.implementations": "Implémentations", "info_panel.tree.calls": "Graphique des appels", "popup.copied": "Copié !", + "structure.options.obfuscation": "Visibilité de l'obfuscation", + "structure.options.obfuscation.all": "Tous", + "structure.options.obfuscation.obfuscated": "Seulement obfusqués", + "structure.options.obfuscation.deobfuscated": "Seulement déobfusqués", + "structure.options.documentation": "Visibilité de la documentation", + "structure.options.documentation.all": "Tous", + "structure.options.documentation.documented": "Seulement documentés", + "structure.options.documentation.non_documented": "Seulement non documentés", + "structure.options.sorting": "Ordre de tri", + "structure.options.sorting.default": "Par défaut", + "structure.options.sorting.a_z": "A à Z", + "structure.options.sorting.z_a": "Z à A", + "log_panel.messages": "Messages", "log_panel.users": "Utilisateurs", diff --git a/enigma/src/main/resources/lang/ja_jp.json b/enigma/src/main/resources/lang/ja_jp.json index 0ff162a..9399e17 100644 --- a/enigma/src/main/resources/lang/ja_jp.json +++ b/enigma/src/main/resources/lang/ja_jp.json @@ -102,7 +102,6 @@ "info_panel.editor.class.decompiling": "(デコンパイル中...)", "info_panel.editor.class.not_found": "クラスが見つけられません:", "info_panel.tree.structure": "構造", - "info_panel.tree.structure.hide_deobfuscated": "難読化解除されたメンバを隠す", "info_panel.tree.inheritance": "継承", "info_panel.tree.implementations": "実装", "info_panel.tree.calls": "呼び出し関係", -- cgit v1.2.3