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