summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java')
-rw-r--r--src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java b/src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java
new file mode 100644
index 0000000..03f76c9
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java
@@ -0,0 +1,129 @@
1package cuchaz.enigma.gui;
2
3import cuchaz.enigma.Deobfuscator;
4import cuchaz.enigma.analysis.EntryReference;
5import cuchaz.enigma.analysis.SourceIndex;
6import cuchaz.enigma.analysis.Token;
7import cuchaz.enigma.api.EnigmaPlugin;
8import cuchaz.enigma.gui.highlight.TokenHighlightType;
9import cuchaz.enigma.translation.LocalNameGenerator;
10import cuchaz.enigma.translation.Translator;
11import cuchaz.enigma.translation.representation.TypeDescriptor;
12import cuchaz.enigma.translation.representation.entry.ClassEntry;
13import cuchaz.enigma.translation.representation.entry.Entry;
14import cuchaz.enigma.translation.representation.entry.FieldEntry;
15import cuchaz.enigma.translation.representation.entry.LocalVariableDefEntry;
16
17import javax.annotation.Nullable;
18import java.util.*;
19
20public class DecompiledClassSource {
21 private final ClassEntry classEntry;
22 private final Deobfuscator deobfuscator;
23
24 private final SourceIndex obfuscatedIndex;
25 private SourceIndex remappedIndex;
26
27 private final Map<TokenHighlightType, Collection<Token>> highlightedTokens = new EnumMap<>(TokenHighlightType.class);
28
29 public DecompiledClassSource(ClassEntry classEntry, Deobfuscator deobfuscator, SourceIndex index) {
30 this.classEntry = classEntry;
31 this.deobfuscator = deobfuscator;
32 this.obfuscatedIndex = index;
33 this.remappedIndex = index;
34 }
35
36 public void remapSource(Translator translator) {
37 highlightedTokens.clear();
38
39 SourceRemapper remapper = new SourceRemapper(obfuscatedIndex.getSource(), obfuscatedIndex.referenceTokens());
40
41 SourceRemapper.Result remapResult = remapper.remap((token, movedToken) -> remapToken(token, movedToken, translator));
42 remappedIndex = obfuscatedIndex.remapTo(remapResult);
43 }
44
45 private String remapToken(Token token, Token movedToken, Translator translator) {
46 EntryReference<Entry<?>, Entry<?>> reference = obfuscatedIndex.getReference(token);
47
48 if (deobfuscator.isRenamable(reference)) {
49 Entry<?> entry = reference.getNameableEntry();
50 Entry<?> translatedEntry = translator.translate(entry);
51
52 if (isDeobfuscated(entry, translatedEntry)) {
53 highlightToken(movedToken, TokenHighlightType.DEOBFUSCATED);
54 return translatedEntry.getSourceRemapName();
55 } else {
56 String proposedName = proposeName(entry);
57 if (proposedName != null) {
58 highlightToken(movedToken, TokenHighlightType.PROPOSED);
59 return proposedName;
60 }
61
62 highlightToken(movedToken, TokenHighlightType.OBFUSCATED);
63
64 String defaultName = generateDefaultName(translatedEntry);
65 if (defaultName != null) {
66 return defaultName;
67 }
68 }
69 }
70
71 return null;
72 }
73
74 @Nullable
75 private String proposeName(Entry<?> entry) {
76 if (entry instanceof FieldEntry) {
77 for (EnigmaPlugin plugin : deobfuscator.getPlugins()) {
78 String owner = entry.getContainingClass().getFullName();
79 String proposal = plugin.proposeFieldName(owner, entry.getName(), ((FieldEntry) entry).getDesc().toString());
80 if (proposal != null) {
81 return proposal;
82 }
83 }
84 }
85 return null;
86 }
87
88 @Nullable
89 private String generateDefaultName(Entry<?> entry) {
90 if (entry instanceof LocalVariableDefEntry) {
91 LocalVariableDefEntry localVariable = (LocalVariableDefEntry) entry;
92
93 int index = localVariable.getIndex();
94 if (localVariable.isArgument()) {
95 List<TypeDescriptor> arguments = localVariable.getParent().getDesc().getArgumentDescs();
96 return LocalNameGenerator.generateArgumentName(index, localVariable.getDesc(), arguments);
97 } else {
98 return LocalNameGenerator.generateLocalVariableName(index, localVariable.getDesc());
99 }
100 }
101
102 return null;
103 }
104
105 private boolean isDeobfuscated(Entry<?> entry, Entry<?> translatedEntry) {
106 return !entry.getName().equals(translatedEntry.getName());
107 }
108
109 public ClassEntry getEntry() {
110 return classEntry;
111 }
112
113 public SourceIndex getIndex() {
114 return remappedIndex;
115 }
116
117 public Map<TokenHighlightType, Collection<Token>> getHighlightedTokens() {
118 return highlightedTokens;
119 }
120
121 private void highlightToken(Token token, TokenHighlightType highlightType) {
122 highlightedTokens.computeIfAbsent(highlightType, t -> new ArrayList<>()).add(token);
123 }
124
125 @Override
126 public String toString() {
127 return remappedIndex.getSource();
128 }
129}