diff options
| author | 2014-08-20 01:21:52 -0400 | |
|---|---|---|
| committer | 2014-08-20 01:21:52 -0400 | |
| commit | a85529d1ce6ec533809575ec84572de855464b36 (patch) | |
| tree | 8f1894c272edf0e7eb22aec2f3af41f6bd19c092 /src/cuchaz/enigma/gui/GuiController.java | |
| parent | started new reference navigation system (diff) | |
| download | enigma-fork-a85529d1ce6ec533809575ec84572de855464b36.tar.gz enigma-fork-a85529d1ce6ec533809575ec84572de855464b36.tar.xz enigma-fork-a85529d1ce6ec533809575ec84572de855464b36.zip | |
finished reference navigation system. Still need to debug and polish it, but the basic idea seems to work. =)
Diffstat (limited to 'src/cuchaz/enigma/gui/GuiController.java')
| -rw-r--r-- | src/cuchaz/enigma/gui/GuiController.java | 106 |
1 files changed, 56 insertions, 50 deletions
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index f80bec7..dfa2557 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java | |||
| @@ -14,10 +14,11 @@ import java.io.File; | |||
| 14 | import java.io.FileReader; | 14 | import java.io.FileReader; |
| 15 | import java.io.FileWriter; | 15 | import java.io.FileWriter; |
| 16 | import java.io.IOException; | 16 | import java.io.IOException; |
| 17 | import java.util.Deque; | ||
| 17 | import java.util.List; | 18 | import java.util.List; |
| 18 | import java.util.Stack; | ||
| 19 | 19 | ||
| 20 | import com.google.common.collect.Lists; | 20 | import com.google.common.collect.Lists; |
| 21 | import com.google.common.collect.Queues; | ||
| 21 | 22 | ||
| 22 | import cuchaz.enigma.Deobfuscator; | 23 | import cuchaz.enigma.Deobfuscator; |
| 23 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; | 24 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; |
| @@ -30,7 +31,6 @@ import cuchaz.enigma.analysis.Token; | |||
| 30 | import cuchaz.enigma.mapping.BehaviorEntry; | 31 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 31 | import cuchaz.enigma.mapping.ClassEntry; | 32 | import cuchaz.enigma.mapping.ClassEntry; |
| 32 | import cuchaz.enigma.mapping.Entry; | 33 | import cuchaz.enigma.mapping.Entry; |
| 33 | import cuchaz.enigma.mapping.EntryPair; | ||
| 34 | import cuchaz.enigma.mapping.FieldEntry; | 34 | import cuchaz.enigma.mapping.FieldEntry; |
| 35 | import cuchaz.enigma.mapping.MappingParseException; | 35 | import cuchaz.enigma.mapping.MappingParseException; |
| 36 | import cuchaz.enigma.mapping.MappingsReader; | 36 | import cuchaz.enigma.mapping.MappingsReader; |
| @@ -43,18 +43,18 @@ public class GuiController | |||
| 43 | private Deobfuscator m_deobfuscator; | 43 | private Deobfuscator m_deobfuscator; |
| 44 | private Gui m_gui; | 44 | private Gui m_gui; |
| 45 | private SourceIndex m_index; | 45 | private SourceIndex m_index; |
| 46 | private ClassEntry m_currentClass; | 46 | private ClassEntry m_currentObfClass; |
| 47 | private boolean m_isDirty; | 47 | private boolean m_isDirty; |
| 48 | private Stack<Entry> m_locationStack; // TODO: make a location class, can be either Entry or EntryReference | 48 | private Deque<EntryReference<Entry,Entry>> m_referenceStack; // TODO: make a location class, can be either Entry or EntryReference |
| 49 | 49 | ||
| 50 | public GuiController( Gui gui ) | 50 | public GuiController( Gui gui ) |
| 51 | { | 51 | { |
| 52 | m_gui = gui; | 52 | m_gui = gui; |
| 53 | m_deobfuscator = null; | 53 | m_deobfuscator = null; |
| 54 | m_index = null; | 54 | m_index = null; |
| 55 | m_currentClass = null; | 55 | m_currentObfClass = null; |
| 56 | m_isDirty = false; | 56 | m_isDirty = false; |
| 57 | m_locationStack = new Stack<Entry>(); | 57 | m_referenceStack = Queues.newArrayDeque(); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | public boolean isDirty( ) | 60 | public boolean isDirty( ) |
| @@ -112,22 +112,16 @@ public class GuiController | |||
| 112 | return null; | 112 | return null; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | return m_index.getToken( pos ); | 115 | return m_index.getReferenceToken( pos ); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | public EntryPair<Entry> getEntryPair( Token token ) | 118 | public EntryReference<Entry,Entry> getDeobfReference( Token token ) |
| 119 | { | 119 | { |
| 120 | if( m_index == null ) | 120 | if( m_index == null ) |
| 121 | { | 121 | { |
| 122 | return null; | 122 | return null; |
| 123 | } | 123 | } |
| 124 | 124 | return m_index.getDeobfReference( token ); | |
| 125 | Entry deobfEntry = m_index.getEntry( token ); | ||
| 126 | if( deobfEntry == null ) | ||
| 127 | { | ||
| 128 | return null; | ||
| 129 | } | ||
| 130 | return new EntryPair<Entry>( m_deobfuscator.obfuscateEntry( deobfEntry ), deobfEntry ); | ||
| 131 | } | 125 | } |
| 132 | 126 | ||
| 133 | public boolean entryHasMapping( Entry deobfEntry ) | 127 | public boolean entryHasMapping( Entry deobfEntry ) |
| @@ -178,54 +172,63 @@ public class GuiController | |||
| 178 | return rootNode; | 172 | return rootNode; |
| 179 | } | 173 | } |
| 180 | 174 | ||
| 181 | public void rename( Entry obfEntry, String newName ) | 175 | public void rename( EntryReference<Entry,Entry> deobfReference, String newName ) |
| 182 | { | 176 | { |
| 183 | m_deobfuscator.rename( obfEntry, newName ); | 177 | EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference( deobfReference ); |
| 178 | m_deobfuscator.rename( obfReference.entry, newName ); | ||
| 184 | m_isDirty = true; | 179 | m_isDirty = true; |
| 185 | refreshClasses(); | 180 | refreshClasses(); |
| 186 | refreshCurrentClass( obfEntry ); | 181 | refreshCurrentClass( obfReference ); |
| 187 | } | 182 | } |
| 188 | 183 | ||
| 189 | public void openDeclaration( Entry entry ) | 184 | public void openDeclaration( Entry entry ) |
| 190 | { | 185 | { |
| 191 | // go to the entry | 186 | if( entry == null ) |
| 192 | Entry obfEntry = m_deobfuscator.obfuscateEntry( entry ); | ||
| 193 | if( m_currentClass == null || !m_currentClass.equals( obfEntry.getClassEntry() ) ) | ||
| 194 | { | 187 | { |
| 195 | m_currentClass = new ClassEntry( obfEntry.getClassEntry() ); | 188 | throw new IllegalArgumentException( "Entry cannot be null!" ); |
| 196 | deobfuscate( m_currentClass, obfEntry ); | ||
| 197 | } | 189 | } |
| 198 | else | 190 | openReference( new EntryReference<Entry,Entry>( entry ) ); |
| 191 | } | ||
| 192 | |||
| 193 | public void openReference( EntryReference<Entry,Entry> deobfReference ) | ||
| 194 | { | ||
| 195 | if( deobfReference == null ) | ||
| 199 | { | 196 | { |
| 200 | m_gui.showToken( m_index.getDeclarationToken( m_deobfuscator.deobfuscateEntry( obfEntry ) ) ); | 197 | throw new IllegalArgumentException( "Reference cannot be null!" ); |
| 201 | } | 198 | } |
| 202 | 199 | ||
| 203 | if( m_locationStack.isEmpty() || !m_locationStack.peek().equals( obfEntry ) ) | 200 | // get the reference target class |
| 201 | EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference( deobfReference ); | ||
| 202 | ClassEntry obfClassEntry = obfReference.getClassEntry().getOuterClassEntry(); | ||
| 203 | if( m_currentObfClass == null || !m_currentObfClass.equals( obfClassEntry ) ) | ||
| 204 | { | ||
| 205 | // deobfuscate the class, then navigate to the reference | ||
| 206 | m_currentObfClass = obfClassEntry; | ||
| 207 | deobfuscate( m_currentObfClass, obfReference ); | ||
| 208 | } | ||
| 209 | else | ||
| 204 | { | 210 | { |
| 205 | // update the stack | 211 | // the class file is already open, just navigate to the reference |
| 206 | m_locationStack.push( obfEntry ); | 212 | m_gui.showToken( m_index.getReferenceToken( deobfReference ) ); |
| 207 | } | 213 | } |
| 208 | } | 214 | } |
| 209 | 215 | ||
| 210 | public void openReference( EntryReference<Entry> reference ) | 216 | public void savePreviousReference( EntryReference<Entry,Entry> deobfReference ) |
| 211 | { | 217 | { |
| 212 | // TODO: find out how to load the n-th reference in a caller | 218 | m_referenceStack.push( m_deobfuscator.obfuscateReference( deobfReference ) ); |
| 213 | // TEMP: just go to the caller for now | ||
| 214 | openDeclaration( reference.caller ); | ||
| 215 | } | 219 | } |
| 216 | 220 | ||
| 217 | public void openPreviousLocation( ) | 221 | public void openPreviousReference( ) |
| 218 | { | 222 | { |
| 219 | if( hasPreviousLocation() ) | 223 | if( hasPreviousLocation() ) |
| 220 | { | 224 | { |
| 221 | m_locationStack.pop(); | 225 | openReference( m_deobfuscator.deobfuscateReference( m_referenceStack.pop() ) ); |
| 222 | openDeclaration( m_locationStack.peek() ); | ||
| 223 | } | 226 | } |
| 224 | } | 227 | } |
| 225 | 228 | ||
| 226 | public boolean hasPreviousLocation( ) | 229 | public boolean hasPreviousLocation( ) |
| 227 | { | 230 | { |
| 228 | return m_locationStack.size() > 1; | 231 | return !m_referenceStack.isEmpty(); |
| 229 | } | 232 | } |
| 230 | 233 | ||
| 231 | private void refreshClasses( ) | 234 | private void refreshClasses( ) |
| @@ -242,15 +245,15 @@ public class GuiController | |||
| 242 | refreshCurrentClass( null ); | 245 | refreshCurrentClass( null ); |
| 243 | } | 246 | } |
| 244 | 247 | ||
| 245 | private void refreshCurrentClass( Entry obfEntryToShow ) | 248 | private void refreshCurrentClass( EntryReference<Entry,Entry> obfReferenceToShow ) |
| 246 | { | 249 | { |
| 247 | if( m_currentClass != null ) | 250 | if( m_currentObfClass != null ) |
| 248 | { | 251 | { |
| 249 | deobfuscate( m_currentClass, obfEntryToShow ); | 252 | deobfuscate( m_currentObfClass, obfReferenceToShow ); |
| 250 | } | 253 | } |
| 251 | } | 254 | } |
| 252 | 255 | ||
| 253 | private void deobfuscate( final ClassEntry classEntry, final Entry obfEntryToShow ) | 256 | private void deobfuscate( final ClassEntry classEntry, final EntryReference<Entry,Entry> obfReferenceToShow ) |
| 254 | { | 257 | { |
| 255 | m_gui.setSource( "(deobfuscating...)" ); | 258 | m_gui.setSource( "(deobfuscating...)" ); |
| 256 | 259 | ||
| @@ -263,29 +266,32 @@ public class GuiController | |||
| 263 | // decompile,deobfuscate the bytecode | 266 | // decompile,deobfuscate the bytecode |
| 264 | m_index = m_deobfuscator.getSource( classEntry.getClassName() ); | 267 | m_index = m_deobfuscator.getSource( classEntry.getClassName() ); |
| 265 | m_gui.setSource( m_index.getSource() ); | 268 | m_gui.setSource( m_index.getSource() ); |
| 266 | if( obfEntryToShow != null ) | 269 | if( obfReferenceToShow != null ) |
| 267 | { | 270 | { |
| 268 | Entry deobfEntryToShow = m_deobfuscator.deobfuscateEntry( obfEntryToShow ); | 271 | EntryReference<Entry,Entry> deobfReferenceToShow = m_deobfuscator.deobfuscateReference( obfReferenceToShow ); |
| 269 | Token token = m_index.getDeclarationToken( deobfEntryToShow ); | 272 | Token token = m_index.getReferenceToken( deobfReferenceToShow ); |
| 270 | if( token == null ) | 273 | if( token == null ) |
| 271 | { | 274 | { |
| 272 | // TEMP | 275 | // DEBUG |
| 273 | System.out.println( "WARNING: can't find token for " + obfEntryToShow + " -> " + deobfEntryToShow ); | 276 | System.out.println( "WARNING: can't find token for " + obfReferenceToShow + " -> " + deobfReferenceToShow ); |
| 277 | } | ||
| 278 | else | ||
| 279 | { | ||
| 280 | m_gui.showToken( token ); | ||
| 274 | } | 281 | } |
| 275 | m_gui.showToken( token ); | ||
| 276 | } | 282 | } |
| 277 | 283 | ||
| 278 | // set the highlighted tokens | 284 | // set the highlighted tokens |
| 279 | List<Token> obfuscatedTokens = Lists.newArrayList(); | 285 | List<Token> obfuscatedTokens = Lists.newArrayList(); |
| 280 | List<Token> deobfuscatedTokens = Lists.newArrayList(); | 286 | List<Token> deobfuscatedTokens = Lists.newArrayList(); |
| 281 | for( Token token : m_index.tokens() ) | 287 | for( Token token : m_index.referenceTokens() ) |
| 282 | { | 288 | { |
| 283 | Entry entry = m_index.getEntry( token ); | 289 | EntryReference<Entry,Entry> reference = m_index.getDeobfReference( token ); |
| 284 | if( entryHasMapping( entry ) ) | 290 | if( entryHasMapping( reference.entry ) ) |
| 285 | { | 291 | { |
| 286 | deobfuscatedTokens.add( token ); | 292 | deobfuscatedTokens.add( token ); |
| 287 | } | 293 | } |
| 288 | else if( entryIsObfuscatedIdenfitier( entry ) ) | 294 | else if( entryIsObfuscatedIdenfitier( reference.entry ) ) |
| 289 | { | 295 | { |
| 290 | obfuscatedTokens.add( token ); | 296 | obfuscatedTokens.add( token ); |
| 291 | } | 297 | } |