summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/gui/GuiController.java
diff options
context:
space:
mode:
authorGravatar Modmuss502019-06-19 18:51:31 +0100
committerGravatar GitHub2019-06-19 18:51:31 +0100
commit546c617598b10c341fe6549678803f6ac0c95619 (patch)
treed818bcebf7634ed5b716ee29619725fdc29a04e8 /src/main/java/cuchaz/enigma/gui/GuiController.java
parentfix unwanted declaration navigation during Quick Find (diff)
parentParse profile json from cli args (diff)
downloadenigma-fork-546c617598b10c341fe6549678803f6ac0c95619.tar.gz
enigma-fork-546c617598b10c341fe6549678803f6ac0c95619.tar.xz
enigma-fork-546c617598b10c341fe6549678803f6ac0c95619.zip
Merge pull request #135 from gegy1000/proposal-tweak
Plugin rework
Diffstat (limited to 'src/main/java/cuchaz/enigma/gui/GuiController.java')
-rw-r--r--src/main/java/cuchaz/enigma/gui/GuiController.java351
1 files changed, 217 insertions, 134 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java
index 1683333..209b5d1 100644
--- a/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -14,9 +14,10 @@ package cuchaz.enigma.gui;
14import com.google.common.collect.Lists; 14import com.google.common.collect.Lists;
15import com.google.common.util.concurrent.ThreadFactoryBuilder; 15import com.google.common.util.concurrent.ThreadFactoryBuilder;
16import com.strobel.decompiler.languages.java.ast.CompilationUnit; 16import com.strobel.decompiler.languages.java.ast.CompilationUnit;
17import cuchaz.enigma.Deobfuscator; 17import cuchaz.enigma.*;
18import cuchaz.enigma.SourceProvider;
19import cuchaz.enigma.analysis.*; 18import cuchaz.enigma.analysis.*;
19import cuchaz.enigma.api.service.ObfuscationTestService;
20import cuchaz.enigma.bytecode.translators.SourceFixVisitor;
20import cuchaz.enigma.config.Config; 21import cuchaz.enigma.config.Config;
21import cuchaz.enigma.gui.dialog.ProgressDialog; 22import cuchaz.enigma.gui.dialog.ProgressDialog;
22import cuchaz.enigma.gui.util.History; 23import cuchaz.enigma.gui.util.History;
@@ -30,114 +31,157 @@ import cuchaz.enigma.translation.representation.entry.Entry;
30import cuchaz.enigma.translation.representation.entry.FieldEntry; 31import cuchaz.enigma.translation.representation.entry.FieldEntry;
31import cuchaz.enigma.translation.representation.entry.MethodEntry; 32import cuchaz.enigma.translation.representation.entry.MethodEntry;
32import cuchaz.enigma.utils.ReadableToken; 33import cuchaz.enigma.utils.ReadableToken;
34import org.objectweb.asm.Opcodes;
33 35
34import javax.annotation.Nullable; 36import javax.annotation.Nullable;
35import javax.swing.*; 37import javax.swing.*;
36import java.awt.event.ItemEvent; 38import java.awt.event.ItemEvent;
37import java.io.File;
38import java.io.IOException;
39import java.io.PrintWriter; 39import java.io.PrintWriter;
40import java.io.StringWriter; 40import java.io.StringWriter;
41import java.nio.file.Path; 41import java.nio.file.Path;
42import java.util.Collection; 42import java.util.Collection;
43import java.util.List; 43import java.util.List;
44import java.util.Optional;
44import java.util.concurrent.ExecutorService; 45import java.util.concurrent.ExecutorService;
45import java.util.concurrent.Executors; 46import java.util.concurrent.Executors;
46import java.util.jar.JarFile;
47import java.util.stream.Collectors; 47import java.util.stream.Collectors;
48import java.util.stream.Stream;
48 49
49public class GuiController { 50public class GuiController {
50 private static final ExecutorService DECOMPILER_SERVICE = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setDaemon(true).setNameFormat("decompiler-thread").build()); 51 private static final ExecutorService DECOMPILER_SERVICE = Executors.newSingleThreadExecutor(
52 new ThreadFactoryBuilder()
53 .setDaemon(true)
54 .setNameFormat("decompiler-thread")
55 .build()
56 );
51 57
52 private final Gui gui; 58 private final Gui gui;
53 private Deobfuscator deobfuscator; 59 public final Enigma enigma;
54 private DecompiledClassSource currentSource;
55 60
61 public EnigmaProject project;
62 private SourceProvider sourceProvider;
63 private IndexTreeBuilder indexTreeBuilder;
56 64
57 private Path loadedMappingPath; 65 private Path loadedMappingPath;
58 private MappingFormat loadedMappingFormat; 66 private MappingFormat loadedMappingFormat;
59 67
60 public GuiController(Gui gui) { 68 private DecompiledClassSource currentSource;
69
70 public GuiController(Gui gui, EnigmaProfile profile) {
61 this.gui = gui; 71 this.gui = gui;
72 this.enigma = Enigma.builder()
73 .setProfile(profile)
74 .build();
62 } 75 }
63 76
64 public boolean isDirty() { 77 public boolean isDirty() {
65 if (deobfuscator == null) { 78 return project != null && project.getMapper().isDirty();
66 return false;
67 }
68 return deobfuscator.getMapper().isDirty();
69 } 79 }
70 80
71 public void openJar(final JarFile jar) throws IOException { 81 public void openJar(final Path jarPath) {
72 this.gui.onStartOpenJar("Loading JAR..."); 82 this.gui.onStartOpenJar();
73 this.deobfuscator = new Deobfuscator(jar, this.gui::onStartOpenJar); 83
74 this.gui.onFinishOpenJar(jar.getName()); 84 ProgressDialog.runOffThread(gui.getFrame(), progress -> {
75 refreshClasses(); 85 project = enigma.openJar(jarPath, progress);
86
87 indexTreeBuilder = new IndexTreeBuilder(project.getJarIndex());
88
89 CompiledSourceTypeLoader typeLoader = new CompiledSourceTypeLoader(project.getClassCache());
90 typeLoader.addVisitor(visitor -> new SourceFixVisitor(Opcodes.ASM5, visitor, project.getJarIndex()));
91 sourceProvider = new SourceProvider(SourceProvider.createSettings(), typeLoader);
92
93 gui.onFinishOpenJar(jarPath.getFileName().toString());
94
95 refreshClasses();
96 });
76 } 97 }
77 98
78 public void closeJar() { 99 public void closeJar() {
79 this.deobfuscator = null; 100 this.project = null;
80 this.gui.onCloseJar(); 101 this.gui.onCloseJar();
81 } 102 }
82 103
83 public void openMappings(MappingFormat format, Path path) { 104 public void openMappings(MappingFormat format, Path path) {
84 if (deobfuscator == null) return; 105 if (project == null) return;
85 ProgressDialog.runInThread(this.gui.getFrame(), progress -> { 106
107 gui.setMappingsFile(path);
108
109 ProgressDialog.runOffThread(gui.getFrame(), progress -> {
86 try { 110 try {
87 EntryTree<EntryMapping> mappings = format.read(path, progress); 111 EntryTree<EntryMapping> mappings = format.read(path, progress);
88 deobfuscator.setMappings(mappings, progress); 112 project.setMappings(mappings);
89 113
90 gui.setMappingsFile(path);
91 loadedMappingFormat = format; 114 loadedMappingFormat = format;
92 loadedMappingPath = path; 115 loadedMappingPath = path;
93 116
94 refreshClasses(); 117 refreshClasses();
95 refreshCurrentClass(); 118 refreshCurrentClass();
96 } catch (MappingParseException e) { 119 } catch (MappingParseException e) {
97 JOptionPane.showMessageDialog(this.gui.getFrame(), e.getMessage()); 120 JOptionPane.showMessageDialog(gui.getFrame(), e.getMessage());
98 } 121 }
99 }); 122 });
100 } 123 }
101 124
102 public void saveMappings(Path path) { 125 public void saveMappings(Path path) {
103 saveMappings(loadedMappingFormat, path); 126 if (project == null) return;
127
128 saveMappings(path, loadedMappingFormat);
104 } 129 }
105 130
106 public void saveMappings(MappingFormat format, Path path) { 131 public void saveMappings(Path path, MappingFormat format) {
107 if (deobfuscator == null) return; 132 if (project == null) return;
108 EntryRemapper mapper = deobfuscator.getMapper(); 133
134 ProgressDialog.runOffThread(this.gui.getFrame(), progress -> {
135 EntryRemapper mapper = project.getMapper();
136
137 MappingDelta<EntryMapping> delta = mapper.takeMappingDelta();
138 boolean saveAll = !path.equals(loadedMappingPath);
109 139
110 MappingDelta<EntryMapping> delta = mapper.takeMappingDelta(); 140 loadedMappingFormat = format;
111 boolean saveAll = !path.equals(loadedMappingPath); 141 loadedMappingPath = path;
112 142
113 ProgressDialog.runInThread(this.gui.getFrame(), progress -> {
114 if (saveAll) { 143 if (saveAll) {
115 format.write(mapper.getObfToDeobf(), path, progress); 144 format.write(mapper.getObfToDeobf(), path, progress);
116 } else { 145 } else {
117 format.write(mapper.getObfToDeobf(), delta, path, progress); 146 format.write(mapper.getObfToDeobf(), delta, path, progress);
118 } 147 }
119 }); 148 });
120
121 loadedMappingFormat = format;
122 loadedMappingPath = path;
123 } 149 }
124 150
125 public void closeMappings() { 151 public void closeMappings() {
126 if (deobfuscator == null) return; 152 if (project == null) return;
127 this.deobfuscator.setMappings(null); 153
154 project.setMappings(null);
155
128 this.gui.setMappingsFile(null); 156 this.gui.setMappingsFile(null);
129 refreshClasses(); 157 refreshClasses();
130 refreshCurrentClass(); 158 refreshCurrentClass();
131 } 159 }
132 160
133 public void exportSource(final File dirOut) { 161 public void dropMappings() {
134 if (deobfuscator == null) return; 162 if (project == null) return;
135 ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeSources(dirOut.toPath(), progress)); 163
164 ProgressDialog.runOffThread(this.gui.getFrame(), progress -> project.dropMappings(progress));
136 } 165 }
137 166
138 public void exportJar(final File fileOut) { 167 public void exportSource(final Path path) {
139 if (deobfuscator == null) return; 168 if (project == null) return;
140 ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeTransformedJar(fileOut, progress)); 169
170 ProgressDialog.runOffThread(this.gui.getFrame(), progress -> {
171 EnigmaProject.JarExport jar = project.exportRemappedJar(progress);
172 EnigmaProject.SourceExport source = jar.decompile(progress);
173
174 source.write(path, progress);
175 });
176 }
177
178 public void exportJar(final Path path) {
179 if (project == null) return;
180
181 ProgressDialog.runOffThread(this.gui.getFrame(), progress -> {
182 EnigmaProject.JarExport jar = project.exportRemappedJar(progress);
183 jar.write(path, progress);
184 });
141 } 185 }
142 186
143 public Token getToken(int pos) { 187 public Token getToken(int pos) {
@@ -167,85 +211,9 @@ public class GuiController {
167 ); 211 );
168 } 212 }
169 213
170 public boolean entryIsInJar(Entry<?> entry) {
171 if (entry == null || deobfuscator == null) return false;
172 return this.deobfuscator.isRenamable(entry);
173 }
174
175 public ClassInheritanceTreeNode getClassInheritance(ClassEntry entry) {
176 Translator translator = this.deobfuscator.getMapper().getDeobfuscator();
177 ClassInheritanceTreeNode rootNode = this.deobfuscator.getIndexTreeBuilder().buildClassInheritance(translator, entry);
178 return ClassInheritanceTreeNode.findNode(rootNode, entry);
179 }
180
181 public ClassImplementationsTreeNode getClassImplementations(ClassEntry entry) {
182 Translator translator = this.deobfuscator.getMapper().getDeobfuscator();
183 return this.deobfuscator.getIndexTreeBuilder().buildClassImplementations(translator, entry);
184 }
185
186 public MethodInheritanceTreeNode getMethodInheritance(MethodEntry entry) {
187 Translator translator = this.deobfuscator.getMapper().getDeobfuscator();
188 MethodInheritanceTreeNode rootNode = this.deobfuscator.getIndexTreeBuilder().buildMethodInheritance(translator, entry);
189 return MethodInheritanceTreeNode.findNode(rootNode, entry);
190 }
191
192 public MethodImplementationsTreeNode getMethodImplementations(MethodEntry entry) {
193 Translator translator = this.deobfuscator.getMapper().getDeobfuscator();
194 List<MethodImplementationsTreeNode> rootNodes = this.deobfuscator.getIndexTreeBuilder().buildMethodImplementations(translator, entry);
195 if (rootNodes.isEmpty()) {
196 return null;
197 }
198 if (rootNodes.size() > 1) {
199 System.err.println("WARNING: Method " + entry + " implements multiple interfaces. Only showing first one.");
200 }
201 return MethodImplementationsTreeNode.findNode(rootNodes.get(0), entry);
202 }
203
204 public ClassReferenceTreeNode getClassReferences(ClassEntry entry) {
205 Translator deobfuscator = this.deobfuscator.getMapper().getDeobfuscator();
206 ClassReferenceTreeNode rootNode = new ClassReferenceTreeNode(deobfuscator, entry);
207 rootNode.load(this.deobfuscator.getJarIndex(), true);
208 return rootNode;
209 }
210
211 public FieldReferenceTreeNode getFieldReferences(FieldEntry entry) {
212 Translator translator = this.deobfuscator.getMapper().getDeobfuscator();
213 FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode(translator, entry);
214 rootNode.load(this.deobfuscator.getJarIndex(), true);
215 return rootNode;
216 }
217
218 public MethodReferenceTreeNode getMethodReferences(MethodEntry entry, boolean recursive) {
219 Translator translator = this.deobfuscator.getMapper().getDeobfuscator();
220 MethodReferenceTreeNode rootNode = new MethodReferenceTreeNode(translator, entry);
221 rootNode.load(this.deobfuscator.getJarIndex(), true, recursive);
222 return rootNode;
223 }
224
225 public void rename(EntryReference<Entry<?>, Entry<?>> reference, String newName, boolean refreshClassTree) {
226 this.deobfuscator.rename(reference.getNameableEntry(), newName);
227
228 if (refreshClassTree && reference.entry instanceof ClassEntry && !((ClassEntry) reference.entry).isInnerClass())
229 this.gui.moveClassTree(reference, newName);
230 refreshCurrentClass(reference);
231 }
232
233 public void removeMapping(EntryReference<Entry<?>, Entry<?>> reference) {
234 this.deobfuscator.removeMapping(reference.getNameableEntry());
235 if (reference.entry instanceof ClassEntry)
236 this.gui.moveClassTree(reference, false, true);
237 refreshCurrentClass(reference);
238 }
239
240 public void markAsDeobfuscated(EntryReference<Entry<?>, Entry<?>> reference) {
241 this.deobfuscator.markAsDeobfuscated(reference.getNameableEntry());
242 if (reference.entry instanceof ClassEntry && !((ClassEntry) reference.entry).isInnerClass())
243 this.gui.moveClassTree(reference, true, false);
244 refreshCurrentClass(reference);
245 }
246
247 /** 214 /**
248 * Navigates to the declaration with respect to navigation history 215 * Navigates to the declaration with respect to navigation history
216 *
249 * @param entry the entry whose declaration will be navigated to 217 * @param entry the entry whose declaration will be navigated to
250 */ 218 */
251 public void openDeclaration(Entry<?> entry) { 219 public void openDeclaration(Entry<?> entry) {
@@ -257,6 +225,7 @@ public class GuiController {
257 225
258 /** 226 /**
259 * Navigates to the reference with respect to navigation history 227 * Navigates to the reference with respect to navigation history
228 *
260 * @param reference the reference 229 * @param reference the reference
261 */ 230 */
262 public void openReference(EntryReference<Entry<?>, Entry<?>> reference) { 231 public void openReference(EntryReference<Entry<?>, Entry<?>> reference) {
@@ -275,12 +244,13 @@ public class GuiController {
275 244
276 /** 245 /**
277 * Navigates to the reference without modifying history. If the class is not currently loaded, it will be loaded. 246 * Navigates to the reference without modifying history. If the class is not currently loaded, it will be loaded.
247 *
278 * @param reference the reference 248 * @param reference the reference
279 */ 249 */
280 private void setReference(EntryReference<Entry<?>, Entry<?>> reference) { 250 private void setReference(EntryReference<Entry<?>, Entry<?>> reference) {
281 // get the reference target class 251 // get the reference target class
282 ClassEntry classEntry = reference.getLocationClassEntry(); 252 ClassEntry classEntry = reference.getLocationClassEntry();
283 if (!this.deobfuscator.isRenamable(classEntry)) { 253 if (!project.isRenamable(classEntry)) {
284 throw new IllegalArgumentException("Obfuscated class " + classEntry + " was not found in the jar!"); 254 throw new IllegalArgumentException("Obfuscated class " + classEntry + " was not found in the jar!");
285 } 255 }
286 256
@@ -294,6 +264,7 @@ public class GuiController {
294 264
295 /** 265 /**
296 * Navigates to the reference without modifying history. Assumes the class is loaded. 266 * Navigates to the reference without modifying history. Assumes the class is loaded.
267 *
297 * @param reference 268 * @param reference
298 */ 269 */
299 private void showReference(EntryReference<Entry<?>, Entry<?>> reference) { 270 private void showReference(EntryReference<Entry<?>, Entry<?>> reference) {
@@ -307,7 +278,7 @@ public class GuiController {
307 } 278 }
308 279
309 public Collection<Token> getTokensForReference(EntryReference<Entry<?>, Entry<?>> reference) { 280 public Collection<Token> getTokensForReference(EntryReference<Entry<?>, Entry<?>> reference) {
310 EntryRemapper mapper = this.deobfuscator.getMapper(); 281 EntryRemapper mapper = this.project.getMapper();
311 282
312 SourceIndex index = this.currentSource.getIndex(); 283 SourceIndex index = this.currentSource.getIndex();
313 return mapper.getObfResolver().resolveReference(reference, ResolutionStrategy.RESOLVE_CLOSEST) 284 return mapper.getObfResolver().resolveReference(reference, ResolutionStrategy.RESOLVE_CLOSEST)
@@ -337,7 +308,7 @@ public class GuiController {
337 } 308 }
338 309
339 public void navigateTo(Entry<?> entry) { 310 public void navigateTo(Entry<?> entry) {
340 if (!entryIsInJar(entry)) { 311 if (!project.isRenamable(entry)) {
341 // entry is not in the jar. Ignore it 312 // entry is not in the jar. Ignore it
342 return; 313 return;
343 } 314 }
@@ -345,7 +316,7 @@ public class GuiController {
345 } 316 }
346 317
347 public void navigateTo(EntryReference<Entry<?>, Entry<?>> reference) { 318 public void navigateTo(EntryReference<Entry<?>, Entry<?>> reference) {
348 if (!entryIsInJar(reference.getLocationClassEntry())) { 319 if (!project.isRenamable(reference.getLocationClassEntry())) {
349 return; 320 return;
350 } 321 }
351 openReference(reference); 322 openReference(reference);
@@ -354,11 +325,38 @@ public class GuiController {
354 private void refreshClasses() { 325 private void refreshClasses() {
355 List<ClassEntry> obfClasses = Lists.newArrayList(); 326 List<ClassEntry> obfClasses = Lists.newArrayList();
356 List<ClassEntry> deobfClasses = Lists.newArrayList(); 327 List<ClassEntry> deobfClasses = Lists.newArrayList();
357 this.deobfuscator.getSeparatedClasses(obfClasses, deobfClasses); 328 this.addSeparatedClasses(obfClasses, deobfClasses);
358 this.gui.setObfClasses(obfClasses); 329 this.gui.setObfClasses(obfClasses);
359 this.gui.setDeobfClasses(deobfClasses); 330 this.gui.setDeobfClasses(deobfClasses);
360 } 331 }
361 332
333 public void addSeparatedClasses(List<ClassEntry> obfClasses, List<ClassEntry> deobfClasses) {
334 EntryRemapper mapper = project.getMapper();
335
336 Collection<ClassEntry> classes = project.getJarIndex().getEntryIndex().getClasses();
337 Stream<ClassEntry> visibleClasses = classes.stream()
338 .filter(entry -> !entry.isInnerClass());
339
340 visibleClasses.forEach(entry -> {
341 ClassEntry deobfEntry = mapper.deobfuscate(entry);
342
343 Optional<ObfuscationTestService> obfService = enigma.getServices().get(ObfuscationTestService.TYPE);
344 boolean obfuscated = deobfEntry.equals(entry);
345
346 if (obfuscated && obfService.isPresent()) {
347 if (obfService.get().testDeobfuscated(entry)) {
348 obfuscated = false;
349 }
350 }
351
352 if (obfuscated) {
353 obfClasses.add(entry);
354 } else {
355 deobfClasses.add(entry);
356 }
357 });
358 }
359
362 public void refreshCurrentClass() { 360 public void refreshCurrentClass() {
363 refreshCurrentClass(null); 361 refreshCurrentClass(null);
364 } 362 }
@@ -384,10 +382,10 @@ public class GuiController {
384 DECOMPILER_SERVICE.submit(() -> { 382 DECOMPILER_SERVICE.submit(() -> {
385 try { 383 try {
386 if (requiresDecompile) { 384 if (requiresDecompile) {
387 currentSource = decompileSource(targetClass, deobfuscator.getObfSourceProvider()); 385 currentSource = decompileSource(targetClass);
388 } 386 }
389 387
390 remapSource(deobfuscator.getMapper().getDeobfuscator()); 388 remapSource(project.getMapper().getDeobfuscator());
391 callback.run(); 389 callback.run();
392 } catch (Throwable t) { 390 } catch (Throwable t) {
393 System.err.println("An exception was thrown while decompiling class " + classEntry.getFullName()); 391 System.err.println("An exception was thrown while decompiling class " + classEntry.getFullName());
@@ -396,7 +394,7 @@ public class GuiController {
396 }); 394 });
397 } 395 }
398 396
399 private DecompiledClassSource decompileSource(ClassEntry targetClass, SourceProvider sourceProvider) { 397 private DecompiledClassSource decompileSource(ClassEntry targetClass) {
400 try { 398 try {
401 CompilationUnit sourceTree = sourceProvider.getSources(targetClass.getFullName()); 399 CompilationUnit sourceTree = sourceProvider.getSources(targetClass.getFullName());
402 if (sourceTree == null) { 400 if (sourceTree == null) {
@@ -410,7 +408,7 @@ public class GuiController {
410 String sourceString = sourceProvider.writeSourceToString(sourceTree); 408 String sourceString = sourceProvider.writeSourceToString(sourceTree);
411 409
412 SourceIndex index = SourceIndex.buildIndex(sourceString, sourceTree, true); 410 SourceIndex index = SourceIndex.buildIndex(sourceString, sourceTree, true);
413 index.resolveReferences(deobfuscator.getMapper().getObfResolver()); 411 index.resolveReferences(project.getMapper().getObfResolver());
414 412
415 return new DecompiledClassSource(targetClass, index); 413 return new DecompiledClassSource(targetClass, index);
416 } catch (Throwable t) { 414 } catch (Throwable t) {
@@ -426,20 +424,105 @@ public class GuiController {
426 return; 424 return;
427 } 425 }
428 426
429 currentSource.remapSource(deobfuscator, translator); 427 currentSource.remapSource(project, translator);
430 428
431 gui.setEditorTheme(Config.getInstance().lookAndFeel); 429 gui.setEditorTheme(Config.getInstance().lookAndFeel);
432 gui.setSource(currentSource); 430 gui.setSource(currentSource);
433 } 431 }
434 432
435 public Deobfuscator getDeobfuscator() {
436 return deobfuscator;
437 }
438
439 public void modifierChange(ItemEvent event) { 433 public void modifierChange(ItemEvent event) {
440 if (event.getStateChange() == ItemEvent.SELECTED) { 434 if (event.getStateChange() == ItemEvent.SELECTED) {
441 deobfuscator.changeModifier(gui.cursorReference.entry, (AccessModifier) event.getItem()); 435 EntryRemapper mapper = project.getMapper();
436 Entry<?> entry = gui.cursorReference.entry;
437 AccessModifier modifier = (AccessModifier) event.getItem();
438
439 EntryMapping mapping = mapper.getDeobfMapping(entry);
440 if (mapping != null) {
441 mapper.mapFromObf(entry, new EntryMapping(mapping.getTargetName(), modifier));
442 } else {
443 mapper.mapFromObf(entry, new EntryMapping(entry.getName(), modifier));
444 }
445
442 refreshCurrentClass(); 446 refreshCurrentClass();
443 } 447 }
444 } 448 }
449
450 public ClassInheritanceTreeNode getClassInheritance(ClassEntry entry) {
451 Translator translator = project.getMapper().getDeobfuscator();
452 ClassInheritanceTreeNode rootNode = indexTreeBuilder.buildClassInheritance(translator, entry);
453 return ClassInheritanceTreeNode.findNode(rootNode, entry);
454 }
455
456 public ClassImplementationsTreeNode getClassImplementations(ClassEntry entry) {
457 Translator translator = project.getMapper().getDeobfuscator();
458 return this.indexTreeBuilder.buildClassImplementations(translator, entry);
459 }
460
461 public MethodInheritanceTreeNode getMethodInheritance(MethodEntry entry) {
462 Translator translator = project.getMapper().getDeobfuscator();
463 MethodInheritanceTreeNode rootNode = indexTreeBuilder.buildMethodInheritance(translator, entry);
464 return MethodInheritanceTreeNode.findNode(rootNode, entry);
465 }
466
467 public MethodImplementationsTreeNode getMethodImplementations(MethodEntry entry) {
468 Translator translator = project.getMapper().getDeobfuscator();
469 List<MethodImplementationsTreeNode> rootNodes = indexTreeBuilder.buildMethodImplementations(translator, entry);
470 if (rootNodes.isEmpty()) {
471 return null;
472 }
473 if (rootNodes.size() > 1) {
474 System.err.println("WARNING: Method " + entry + " implements multiple interfaces. Only showing first one.");
475 }
476 return MethodImplementationsTreeNode.findNode(rootNodes.get(0), entry);
477 }
478
479 public ClassReferenceTreeNode getClassReferences(ClassEntry entry) {
480 Translator deobfuscator = project.getMapper().getDeobfuscator();
481 ClassReferenceTreeNode rootNode = new ClassReferenceTreeNode(deobfuscator, entry);
482 rootNode.load(project.getJarIndex(), true);
483 return rootNode;
484 }
485
486 public FieldReferenceTreeNode getFieldReferences(FieldEntry entry) {
487 Translator translator = project.getMapper().getDeobfuscator();
488 FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode(translator, entry);
489 rootNode.load(project.getJarIndex(), true);
490 return rootNode;
491 }
492
493 public MethodReferenceTreeNode getMethodReferences(MethodEntry entry, boolean recursive) {
494 Translator translator = project.getMapper().getDeobfuscator();
495 MethodReferenceTreeNode rootNode = new MethodReferenceTreeNode(translator, entry);
496 rootNode.load(project.getJarIndex(), true, recursive);
497 return rootNode;
498 }
499
500 public void rename(EntryReference<Entry<?>, Entry<?>> reference, String newName, boolean refreshClassTree) {
501 Entry<?> entry = reference.getNameableEntry();
502 project.getMapper().mapFromObf(entry, new EntryMapping(newName));
503
504 if (refreshClassTree && reference.entry instanceof ClassEntry && !((ClassEntry) reference.entry).isInnerClass())
505 this.gui.moveClassTree(reference, newName);
506
507 refreshCurrentClass(reference);
508 }
509
510 public void removeMapping(EntryReference<Entry<?>, Entry<?>> reference) {
511 project.getMapper().removeByObf(reference.getNameableEntry());
512
513 if (reference.entry instanceof ClassEntry)
514 this.gui.moveClassTree(reference, false, true);
515 refreshCurrentClass(reference);
516 }
517
518 public void markAsDeobfuscated(EntryReference<Entry<?>, Entry<?>> reference) {
519 EntryRemapper mapper = project.getMapper();
520 Entry<?> entry = reference.getNameableEntry();
521 mapper.mapFromObf(entry, new EntryMapping(mapper.deobfuscate(entry).getName()));
522
523 if (reference.entry instanceof ClassEntry && !((ClassEntry) reference.entry).isInnerClass())
524 this.gui.moveClassTree(reference, true, false);
525
526 refreshCurrentClass(reference);
527 }
445} 528}