diff options
| author | 2014-09-28 16:48:54 -0400 | |
|---|---|---|
| committer | 2014-09-28 16:48:54 -0400 | |
| commit | 3e9960f8a712e8590b3ab3126d823504027516da (patch) | |
| tree | 3a437ef90fcfde1eaa8bf3e8ab3b4f946aa1bab2 | |
| parent | argument names now default to the names chosen by Procyon (diff) | |
| download | enigma-3e9960f8a712e8590b3ab3126d823504027516da.tar.gz enigma-3e9960f8a712e8590b3ab3126d823504027516da.tar.xz enigma-3e9960f8a712e8590b3ab3126d823504027516da.zip | |
added jar export
| -rw-r--r-- | src/cuchaz/enigma/Deobfuscator.java | 67 | ||||
| -rw-r--r-- | src/cuchaz/enigma/TranslatingTypeLoader.java | 59 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/Gui.java | 37 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/GuiController.java | 37 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/ProgressDialog.java | 36 |
5 files changed, 177 insertions, 59 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index ff83d21a..9235cf74 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java | |||
| @@ -12,14 +12,18 @@ | |||
| 12 | package cuchaz.enigma; | 12 | package cuchaz.enigma; |
| 13 | 13 | ||
| 14 | import java.io.File; | 14 | import java.io.File; |
| 15 | import java.io.FileOutputStream; | ||
| 15 | import java.io.FileWriter; | 16 | import java.io.FileWriter; |
| 16 | import java.io.IOException; | 17 | import java.io.IOException; |
| 17 | import java.io.StringWriter; | 18 | import java.io.StringWriter; |
| 18 | import java.util.List; | 19 | import java.util.List; |
| 19 | import java.util.Map; | 20 | import java.util.Map; |
| 20 | import java.util.Set; | 21 | import java.util.Set; |
| 22 | import java.util.jar.JarEntry; | ||
| 21 | import java.util.jar.JarFile; | 23 | import java.util.jar.JarFile; |
| 24 | import java.util.jar.JarOutputStream; | ||
| 22 | 25 | ||
| 26 | import javassist.CtClass; | ||
| 23 | import javassist.bytecode.Descriptor; | 27 | import javassist.bytecode.Descriptor; |
| 24 | 28 | ||
| 25 | import com.google.common.collect.Lists; | 29 | import com.google.common.collect.Lists; |
| @@ -36,11 +40,11 @@ import com.strobel.decompiler.languages.java.ast.CompilationUnit; | |||
| 36 | import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor; | 40 | import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor; |
| 37 | 41 | ||
| 38 | import cuchaz.enigma.analysis.EntryReference; | 42 | import cuchaz.enigma.analysis.EntryReference; |
| 43 | import cuchaz.enigma.analysis.JarClassIterator; | ||
| 39 | import cuchaz.enigma.analysis.JarIndex; | 44 | import cuchaz.enigma.analysis.JarIndex; |
| 40 | import cuchaz.enigma.analysis.SourceIndex; | 45 | import cuchaz.enigma.analysis.SourceIndex; |
| 41 | import cuchaz.enigma.analysis.SourceIndexVisitor; | 46 | import cuchaz.enigma.analysis.SourceIndexVisitor; |
| 42 | import cuchaz.enigma.analysis.Token; | 47 | import cuchaz.enigma.analysis.Token; |
| 43 | import cuchaz.enigma.analysis.TreeDumpVisitor; | ||
| 44 | import cuchaz.enigma.mapping.ArgumentEntry; | 48 | import cuchaz.enigma.mapping.ArgumentEntry; |
| 45 | import cuchaz.enigma.mapping.BehaviorEntry; | 49 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 46 | import cuchaz.enigma.mapping.BehaviorEntryFactory; | 50 | import cuchaz.enigma.mapping.BehaviorEntryFactory; |
| @@ -61,7 +65,7 @@ public class Deobfuscator | |||
| 61 | { | 65 | { |
| 62 | public interface ProgressListener | 66 | public interface ProgressListener |
| 63 | { | 67 | { |
| 64 | void init( int totalWork ); | 68 | void init( int totalWork, String title ); |
| 65 | void onProgress( int numDone, String message ); | 69 | void onProgress( int numDone, String message ); |
| 66 | } | 70 | } |
| 67 | 71 | ||
| @@ -393,7 +397,7 @@ public class Deobfuscator | |||
| 393 | 397 | ||
| 394 | if( progress != null ) | 398 | if( progress != null ) |
| 395 | { | 399 | { |
| 396 | progress.init( classEntries.size() ); | 400 | progress.init( classEntries.size(), "Decompiling classes..." ); |
| 397 | } | 401 | } |
| 398 | 402 | ||
| 399 | // DEOBFUSCATE ALL THE THINGS!! @_@ | 403 | // DEOBFUSCATE ALL THE THINGS!! @_@ |
| @@ -424,9 +428,60 @@ public class Deobfuscator | |||
| 424 | throw new Error( "Unable to deobfuscate class " + deobfClassEntry.toString() + " (" + obfClassEntry.toString() + ")", t ); | 428 | throw new Error( "Unable to deobfuscate class " + deobfClassEntry.toString() + " (" + obfClassEntry.toString() + ")", t ); |
| 425 | } | 429 | } |
| 426 | } | 430 | } |
| 427 | 431 | if( progress != null ) | |
| 428 | // done! | 432 | { |
| 429 | progress.onProgress( classEntries.size(), "Done!" ); | 433 | progress.onProgress( i, "Done!" ); |
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | public void writeJar( File out, ProgressListener progress ) | ||
| 438 | { | ||
| 439 | try( JarOutputStream outJar = new JarOutputStream( new FileOutputStream( out ) ) ) | ||
| 440 | { | ||
| 441 | if( progress != null ) | ||
| 442 | { | ||
| 443 | progress.init( JarClassIterator.getClassEntries( m_jar ).size(), "Translating classes..." ); | ||
| 444 | } | ||
| 445 | |||
| 446 | // prep the loader | ||
| 447 | TranslatingTypeLoader loader = new TranslatingTypeLoader( | ||
| 448 | m_jar, | ||
| 449 | m_jarIndex, | ||
| 450 | getTranslator( TranslationDirection.Obfuscating ), | ||
| 451 | getTranslator( TranslationDirection.Deobfuscating ) | ||
| 452 | ); | ||
| 453 | |||
| 454 | int i = 0; | ||
| 455 | for( CtClass c : JarClassIterator.classes( m_jar ) ) | ||
| 456 | { | ||
| 457 | if( progress != null ) | ||
| 458 | { | ||
| 459 | progress.onProgress( i++, c.getName() ); | ||
| 460 | } | ||
| 461 | |||
| 462 | try | ||
| 463 | { | ||
| 464 | c = loader.transformClass( c ); | ||
| 465 | outJar.putNextEntry( new JarEntry( c.getName().replace( '.', '/' ) + ".class" ) ); | ||
| 466 | outJar.write( c.toBytecode() ); | ||
| 467 | outJar.closeEntry(); | ||
| 468 | } | ||
| 469 | catch( Throwable t ) | ||
| 470 | { | ||
| 471 | throw new Error( "Unable to deobfuscate class " + c.getName(), t ); | ||
| 472 | } | ||
| 473 | } | ||
| 474 | if( progress != null ) | ||
| 475 | { | ||
| 476 | progress.onProgress( i, "Done!" ); | ||
| 477 | } | ||
| 478 | |||
| 479 | outJar.close(); | ||
| 480 | } | ||
| 481 | catch( IOException ex ) | ||
| 482 | { | ||
| 483 | throw new Error( "Unable to write to Jar file!" ); | ||
| 484 | } | ||
| 430 | } | 485 | } |
| 431 | 486 | ||
| 432 | public <T extends Entry> T obfuscateEntry( T deobfEntry ) | 487 | public <T extends Entry> T obfuscateEntry( T deobfEntry ) |
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java index 8b969857..6179879a 100644 --- a/src/cuchaz/enigma/TranslatingTypeLoader.java +++ b/src/cuchaz/enigma/TranslatingTypeLoader.java | |||
| @@ -13,7 +13,6 @@ package cuchaz.enigma; | |||
| 13 | import java.io.ByteArrayOutputStream; | 13 | import java.io.ByteArrayOutputStream; |
| 14 | import java.io.IOException; | 14 | import java.io.IOException; |
| 15 | import java.io.InputStream; | 15 | import java.io.InputStream; |
| 16 | import java.util.Arrays; | ||
| 17 | import java.util.Map; | 16 | import java.util.Map; |
| 18 | import java.util.jar.JarEntry; | 17 | import java.util.jar.JarEntry; |
| 19 | import java.util.jar.JarFile; | 18 | import java.util.jar.JarFile; |
| @@ -157,12 +156,13 @@ public class TranslatingTypeLoader implements ITypeLoader | |||
| 157 | // otherwise, just use the class name (ie for classes in packages) | 156 | // otherwise, just use the class name (ie for classes in packages) |
| 158 | classFileName = obfClassEntry.getName(); | 157 | classFileName = obfClassEntry.getName(); |
| 159 | } | 158 | } |
| 159 | |||
| 160 | JarEntry entry = m_jar.getJarEntry( classFileName + ".class" ); | 160 | JarEntry entry = m_jar.getJarEntry( classFileName + ".class" ); |
| 161 | if( entry == null ) | 161 | if( entry == null ) |
| 162 | { | 162 | { |
| 163 | return null; | 163 | return null; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | try | 166 | try |
| 167 | { | 167 | { |
| 168 | // read the class file into a buffer | 168 | // read the class file into a buffer |
| @@ -188,33 +188,11 @@ public class TranslatingTypeLoader implements ITypeLoader | |||
| 188 | classPool.insertClassPath( new ByteArrayClassPath( javaClassFileName, buf ) ); | 188 | classPool.insertClassPath( new ByteArrayClassPath( javaClassFileName, buf ) ); |
| 189 | CtClass c = classPool.get( javaClassFileName ); | 189 | CtClass c = classPool.get( javaClassFileName ); |
| 190 | 190 | ||
| 191 | // we moved a lot of classes out of the default package into the none package | 191 | c = transformClass( c ); |
| 192 | // make sure all the class references are consistent | ||
| 193 | ClassRenamer.moveAllClassesOutOfDefaultPackage( c, Constants.NonePackage ); | ||
| 194 | |||
| 195 | // reconstruct inner classes | ||
| 196 | new InnerClassWriter( m_jarIndex ).write( c ); | ||
| 197 | |||
| 198 | // re-get the javassist handle since we changed class names | ||
| 199 | String javaClassReconstructedName = Descriptor.toJavaName( obfClassEntry.getName() ); | ||
| 200 | classPool = new ClassPool(); | ||
| 201 | classPool.insertClassPath( new ByteArrayClassPath( javaClassReconstructedName, c.toBytecode() ) ); | ||
| 202 | c = classPool.get( javaClassReconstructedName ); | ||
| 203 | |||
| 204 | // check that the file is correct after inner class reconstruction (ie cause Javassist to fail fast if something is wrong) | ||
| 205 | assertClassName( c, obfClassEntry ); | ||
| 206 | |||
| 207 | // do all kinds of deobfuscating transformations on the class | ||
| 208 | new BridgeFixer( m_jarIndex ).fixBridges( c ); | ||
| 209 | new MethodParameterWriter( m_deobfuscatingTranslator ).writeMethodArguments( c ); | ||
| 210 | new ClassTranslator( m_deobfuscatingTranslator ).translate( c ); | ||
| 211 | 192 | ||
| 212 | // sanity checking | 193 | // sanity checking |
| 213 | assertClassName( c, deobfClassEntry ); | 194 | assertClassName( c, deobfClassEntry ); |
| 214 | 195 | ||
| 215 | // DEBUG | ||
| 216 | //Util.writeClass( c ); | ||
| 217 | |||
| 218 | // we have a transformed class! | 196 | // we have a transformed class! |
| 219 | return c.toBytecode(); | 197 | return c.toBytecode(); |
| 220 | } | 198 | } |
| @@ -223,6 +201,37 @@ public class TranslatingTypeLoader implements ITypeLoader | |||
| 223 | throw new Error( ex ); | 201 | throw new Error( ex ); |
| 224 | } | 202 | } |
| 225 | } | 203 | } |
| 204 | |||
| 205 | public CtClass transformClass( CtClass c ) | ||
| 206 | throws IOException, NotFoundException, CannotCompileException | ||
| 207 | { | ||
| 208 | // we moved a lot of classes out of the default package into the none package | ||
| 209 | // make sure all the class references are consistent | ||
| 210 | ClassRenamer.moveAllClassesOutOfDefaultPackage( c, Constants.NonePackage ); | ||
| 211 | |||
| 212 | // reconstruct inner classes | ||
| 213 | new InnerClassWriter( m_jarIndex ).write( c ); | ||
| 214 | |||
| 215 | // re-get the javassist handle since we changed class names | ||
| 216 | ClassEntry obfClassEntry = new ClassEntry( Descriptor.toJvmName( c.getName() ) ); | ||
| 217 | String javaClassReconstructedName = Descriptor.toJavaName( obfClassEntry.getName() ); | ||
| 218 | ClassPool classPool = new ClassPool(); | ||
| 219 | classPool.insertClassPath( new ByteArrayClassPath( javaClassReconstructedName, c.toBytecode() ) ); | ||
| 220 | c = classPool.get( javaClassReconstructedName ); | ||
| 221 | |||
| 222 | // check that the file is correct after inner class reconstruction (ie cause Javassist to fail fast if something is wrong) | ||
| 223 | assertClassName( c, obfClassEntry ); | ||
| 224 | |||
| 225 | // do all kinds of deobfuscating transformations on the class | ||
| 226 | new BridgeFixer( m_jarIndex ).fixBridges( c ); | ||
| 227 | new MethodParameterWriter( m_deobfuscatingTranslator ).writeMethodArguments( c ); | ||
| 228 | new ClassTranslator( m_deobfuscatingTranslator ).translate( c ); | ||
| 229 | |||
| 230 | // DEBUG | ||
| 231 | //Util.writeClass( c ); | ||
| 232 | |||
| 233 | return c; | ||
| 234 | } | ||
| 226 | 235 | ||
| 227 | private void assertClassName( CtClass c, ClassEntry obfClassEntry ) | 236 | private void assertClassName( CtClass c, ClassEntry obfClassEntry ) |
| 228 | { | 237 | { |
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java index 920bc0b9..dbfcba83 100644 --- a/src/cuchaz/enigma/gui/Gui.java +++ b/src/cuchaz/enigma/gui/Gui.java | |||
| @@ -123,12 +123,15 @@ public class Gui | |||
| 123 | private JMenuItem m_showCallsMenu; | 123 | private JMenuItem m_showCallsMenu; |
| 124 | private JMenuItem m_showImplementationsMenu; | 124 | private JMenuItem m_showImplementationsMenu; |
| 125 | private JMenuItem m_toggleMappingMenu; | 125 | private JMenuItem m_toggleMappingMenu; |
| 126 | private JMenuItem m_exportSourceMenu; | ||
| 127 | private JMenuItem m_exportJarMenu; | ||
| 126 | 128 | ||
| 127 | // state | 129 | // state |
| 128 | private EntryReference<Entry,Entry> m_reference; | 130 | private EntryReference<Entry,Entry> m_reference; |
| 129 | private JFileChooser m_jarFileChooser; | 131 | private JFileChooser m_jarFileChooser; |
| 130 | private JFileChooser m_mappingsFileChooser; | 132 | private JFileChooser m_mappingsFileChooser; |
| 131 | private JFileChooser m_exportFileChooser; | 133 | private JFileChooser m_exportSourceFileChooser; |
| 134 | private JFileChooser m_exportJarFileChooser; | ||
| 132 | 135 | ||
| 133 | public Gui( ) | 136 | public Gui( ) |
| 134 | { | 137 | { |
| @@ -157,8 +160,9 @@ public class Gui | |||
| 157 | // init file choosers | 160 | // init file choosers |
| 158 | m_jarFileChooser = new JFileChooser(); | 161 | m_jarFileChooser = new JFileChooser(); |
| 159 | m_mappingsFileChooser = new JFileChooser(); | 162 | m_mappingsFileChooser = new JFileChooser(); |
| 160 | m_exportFileChooser = new JFileChooser(); | 163 | m_exportSourceFileChooser = new JFileChooser(); |
| 161 | m_exportFileChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY ); | 164 | m_exportSourceFileChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY ); |
| 165 | m_exportJarFileChooser = new JFileChooser(); | ||
| 162 | 166 | ||
| 163 | // init obfuscated classes list | 167 | // init obfuscated classes list |
| 164 | m_obfClasses = new ClassSelector( ClassSelector.ObfuscatedClassEntryComparator ); | 168 | m_obfClasses = new ClassSelector( ClassSelector.ObfuscatedClassEntryComparator ); |
| @@ -663,19 +667,36 @@ public class Gui | |||
| 663 | } | 667 | } |
| 664 | menu.addSeparator(); | 668 | menu.addSeparator(); |
| 665 | { | 669 | { |
| 666 | JMenuItem item = new JMenuItem( "Export..." ); | 670 | JMenuItem item = new JMenuItem( "Export Source..." ); |
| 667 | menu.add( item ); | 671 | menu.add( item ); |
| 668 | item.addActionListener( new ActionListener( ) | 672 | item.addActionListener( new ActionListener( ) |
| 669 | { | 673 | { |
| 670 | @Override | 674 | @Override |
| 671 | public void actionPerformed( ActionEvent event ) | 675 | public void actionPerformed( ActionEvent event ) |
| 672 | { | 676 | { |
| 673 | if( m_exportFileChooser.showSaveDialog( m_frame ) == JFileChooser.APPROVE_OPTION ) | 677 | if( m_exportSourceFileChooser.showSaveDialog( m_frame ) == JFileChooser.APPROVE_OPTION ) |
| 674 | { | 678 | { |
| 675 | m_controller.export( m_exportFileChooser.getSelectedFile() ); | 679 | m_controller.exportSource( m_exportSourceFileChooser.getSelectedFile() ); |
| 676 | } | 680 | } |
| 677 | } | 681 | } |
| 678 | } ); | 682 | } ); |
| 683 | m_exportSourceMenu = item; | ||
| 684 | } | ||
| 685 | { | ||
| 686 | JMenuItem item = new JMenuItem( "Export Jar..." ); | ||
| 687 | menu.add( item ); | ||
| 688 | item.addActionListener( new ActionListener( ) | ||
| 689 | { | ||
| 690 | @Override | ||
| 691 | public void actionPerformed( ActionEvent event ) | ||
| 692 | { | ||
| 693 | if( m_exportJarFileChooser.showSaveDialog( m_frame ) == JFileChooser.APPROVE_OPTION ) | ||
| 694 | { | ||
| 695 | m_controller.exportJar( m_exportJarFileChooser.getSelectedFile() ); | ||
| 696 | } | ||
| 697 | } | ||
| 698 | } ); | ||
| 699 | m_exportJarMenu = item; | ||
| 679 | } | 700 | } |
| 680 | menu.addSeparator(); | 701 | menu.addSeparator(); |
| 681 | { | 702 | { |
| @@ -762,6 +783,8 @@ public class Gui | |||
| 762 | m_saveMappingsMenu.setEnabled( false ); | 783 | m_saveMappingsMenu.setEnabled( false ); |
| 763 | m_saveMappingsAsMenu.setEnabled( true ); | 784 | m_saveMappingsAsMenu.setEnabled( true ); |
| 764 | m_closeMappingsMenu.setEnabled( true ); | 785 | m_closeMappingsMenu.setEnabled( true ); |
| 786 | m_exportSourceMenu.setEnabled( true ); | ||
| 787 | m_exportJarMenu.setEnabled( true ); | ||
| 765 | 788 | ||
| 766 | redraw(); | 789 | redraw(); |
| 767 | } | 790 | } |
| @@ -781,6 +804,8 @@ public class Gui | |||
| 781 | m_saveMappingsMenu.setEnabled( false ); | 804 | m_saveMappingsMenu.setEnabled( false ); |
| 782 | m_saveMappingsAsMenu.setEnabled( false ); | 805 | m_saveMappingsAsMenu.setEnabled( false ); |
| 783 | m_closeMappingsMenu.setEnabled( false ); | 806 | m_closeMappingsMenu.setEnabled( false ); |
| 807 | m_exportSourceMenu.setEnabled( false ); | ||
| 808 | m_exportJarMenu.setEnabled( false ); | ||
| 784 | 809 | ||
| 785 | redraw(); | 810 | redraw(); |
| 786 | } | 811 | } |
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index c7efbce6..2862ebed 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java | |||
| @@ -23,6 +23,7 @@ import com.google.common.collect.Queues; | |||
| 23 | import com.strobel.decompiler.languages.java.ast.CompilationUnit; | 23 | import com.strobel.decompiler.languages.java.ast.CompilationUnit; |
| 24 | 24 | ||
| 25 | import cuchaz.enigma.Deobfuscator; | 25 | import cuchaz.enigma.Deobfuscator; |
| 26 | import cuchaz.enigma.Deobfuscator.ProgressListener; | ||
| 26 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; | 27 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; |
| 27 | import cuchaz.enigma.analysis.ClassImplementationsTreeNode; | 28 | import cuchaz.enigma.analysis.ClassImplementationsTreeNode; |
| 28 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; | 29 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; |
| @@ -32,6 +33,7 @@ import cuchaz.enigma.analysis.MethodImplementationsTreeNode; | |||
| 32 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; | 33 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; |
| 33 | import cuchaz.enigma.analysis.SourceIndex; | 34 | import cuchaz.enigma.analysis.SourceIndex; |
| 34 | import cuchaz.enigma.analysis.Token; | 35 | import cuchaz.enigma.analysis.Token; |
| 36 | import cuchaz.enigma.gui.ProgressDialog.ProgressRunnable; | ||
| 35 | import cuchaz.enigma.mapping.BehaviorEntry; | 37 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 36 | import cuchaz.enigma.mapping.ClassEntry; | 38 | import cuchaz.enigma.mapping.ClassEntry; |
| 37 | import cuchaz.enigma.mapping.Entry; | 39 | import cuchaz.enigma.mapping.Entry; |
| @@ -110,28 +112,29 @@ public class GuiController | |||
| 110 | refreshCurrentClass(); | 112 | refreshCurrentClass(); |
| 111 | } | 113 | } |
| 112 | 114 | ||
| 113 | public void export( final File dirOut ) | 115 | public void exportSource( final File dirOut ) |
| 114 | { | 116 | { |
| 115 | new Thread( ) | 117 | ProgressDialog.runInThread( m_gui.getFrame(), new ProgressRunnable( ) |
| 116 | { | 118 | { |
| 117 | @Override | 119 | @Override |
| 118 | public void run( ) | 120 | public void run( ProgressListener progress ) |
| 121 | throws Exception | ||
| 119 | { | 122 | { |
| 120 | ProgressDialog progress = new ProgressDialog( m_gui.getFrame() ); | 123 | m_deobfuscator.writeSources( dirOut, progress ); |
| 121 | try | ||
| 122 | { | ||
| 123 | m_deobfuscator.writeSources( dirOut, progress ); | ||
| 124 | } | ||
| 125 | catch( Exception ex ) | ||
| 126 | { | ||
| 127 | throw new Error( ex ); | ||
| 128 | } | ||
| 129 | finally | ||
| 130 | { | ||
| 131 | progress.close(); | ||
| 132 | } | ||
| 133 | } | 124 | } |
| 134 | }.start(); | 125 | } ); |
| 126 | } | ||
| 127 | |||
| 128 | public void exportJar( final File fileOut ) | ||
| 129 | { | ||
| 130 | ProgressDialog.runInThread( m_gui.getFrame(), new ProgressRunnable( ) | ||
| 131 | { | ||
| 132 | @Override | ||
| 133 | public void run( ProgressListener progress ) | ||
| 134 | { | ||
| 135 | m_deobfuscator.writeJar( fileOut, progress ); | ||
| 136 | } | ||
| 137 | } ); | ||
| 135 | } | 138 | } |
| 136 | 139 | ||
| 137 | public Token getToken( int pos ) | 140 | public Token getToken( int pos ) |
diff --git a/src/cuchaz/enigma/gui/ProgressDialog.java b/src/cuchaz/enigma/gui/ProgressDialog.java index 40ac6a69..7f954314 100644 --- a/src/cuchaz/enigma/gui/ProgressDialog.java +++ b/src/cuchaz/enigma/gui/ProgressDialog.java | |||
| @@ -25,22 +25,24 @@ import javax.swing.WindowConstants; | |||
| 25 | import cuchaz.enigma.Constants; | 25 | import cuchaz.enigma.Constants; |
| 26 | import cuchaz.enigma.Deobfuscator.ProgressListener; | 26 | import cuchaz.enigma.Deobfuscator.ProgressListener; |
| 27 | 27 | ||
| 28 | public class ProgressDialog implements ProgressListener | 28 | public class ProgressDialog implements ProgressListener, AutoCloseable |
| 29 | { | 29 | { |
| 30 | private JFrame m_frame; | 30 | private JFrame m_frame; |
| 31 | private JLabel m_title; | ||
| 31 | private JLabel m_text; | 32 | private JLabel m_text; |
| 32 | private JProgressBar m_progress; | 33 | private JProgressBar m_progress; |
| 33 | 34 | ||
| 34 | public ProgressDialog( JFrame parent ) | 35 | public ProgressDialog( JFrame parent ) |
| 35 | { | 36 | { |
| 36 | // init frame | 37 | // init frame |
| 37 | m_frame = new JFrame( Constants.Name + " - Export" ); | 38 | m_frame = new JFrame( Constants.Name + " - Operation in progress" ); |
| 38 | final Container pane = m_frame.getContentPane(); | 39 | final Container pane = m_frame.getContentPane(); |
| 39 | FlowLayout layout = new FlowLayout(); | 40 | FlowLayout layout = new FlowLayout(); |
| 40 | layout.setAlignment( FlowLayout.LEFT ); | 41 | layout.setAlignment( FlowLayout.LEFT ); |
| 41 | pane.setLayout( layout ); | 42 | pane.setLayout( layout ); |
| 42 | 43 | ||
| 43 | pane.add( new JLabel( "Decompiling classes..." ) ); | 44 | m_title = new JLabel(); |
| 45 | pane.add( m_title ); | ||
| 44 | 46 | ||
| 45 | // set up the progress bar | 47 | // set up the progress bar |
| 46 | JPanel panel = new JPanel(); | 48 | JPanel panel = new JPanel(); |
| @@ -68,9 +70,9 @@ public class ProgressDialog implements ProgressListener | |||
| 68 | } | 70 | } |
| 69 | 71 | ||
| 70 | @Override | 72 | @Override |
| 71 | public void init( int totalWork ) | 73 | public void init( int totalWork, String title ) |
| 72 | { | 74 | { |
| 73 | m_text.setText( "Decompiling " + totalWork + " classes..." ); | 75 | m_title.setText( title ); |
| 74 | m_progress.setMinimum( 0 ); | 76 | m_progress.setMinimum( 0 ); |
| 75 | m_progress.setMaximum( totalWork ); | 77 | m_progress.setMaximum( totalWork ); |
| 76 | m_progress.setValue( 0 ); | 78 | m_progress.setValue( 0 ); |
| @@ -86,4 +88,28 @@ public class ProgressDialog implements ProgressListener | |||
| 86 | m_frame.validate(); | 88 | m_frame.validate(); |
| 87 | m_frame.repaint(); | 89 | m_frame.repaint(); |
| 88 | } | 90 | } |
| 91 | |||
| 92 | public static interface ProgressRunnable | ||
| 93 | { | ||
| 94 | void run( ProgressListener listener ) throws Exception; | ||
| 95 | } | ||
| 96 | |||
| 97 | public static void runInThread( final JFrame parent, final ProgressRunnable runnable ) | ||
| 98 | { | ||
| 99 | new Thread( ) | ||
| 100 | { | ||
| 101 | @Override | ||
| 102 | public void run( ) | ||
| 103 | { | ||
| 104 | try( ProgressDialog progress = new ProgressDialog( parent ) ) | ||
| 105 | { | ||
| 106 | runnable.run( progress ); | ||
| 107 | } | ||
| 108 | catch( Exception ex ) | ||
| 109 | { | ||
| 110 | throw new Error( ex ); | ||
| 111 | } | ||
| 112 | } | ||
| 113 | }.start(); | ||
| 114 | } | ||
| 89 | } | 115 | } |