2013-07-16 17:58:02 +10:00
package codechicken.lib.asm ;
import java.io.IOException ;
2014-04-07 14:02:47 +10:00
import java.lang.reflect.Field ;
import java.util.HashMap ;
import java.util.Map ;
import java.util.Map.Entry ;
2013-07-16 17:58:02 +10:00
2014-04-07 14:02:47 +10:00
import net.minecraft.launchwrapper.Launch ;
2013-07-16 17:58:02 +10:00
import org.objectweb.asm.MethodVisitor ;
import org.objectweb.asm.commons.Remapper ;
import org.objectweb.asm.tree.AbstractInsnNode ;
import org.objectweb.asm.tree.FieldInsnNode ;
import org.objectweb.asm.tree.FieldNode ;
import org.objectweb.asm.tree.MethodInsnNode ;
import org.objectweb.asm.tree.MethodNode ;
import org.objectweb.asm.tree.TypeInsnNode ;
import com.google.common.base.Objects ;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper ;
public class ObfMapping
{
2014-04-07 14:02:47 +10:00
public static class ObfRemapper extends Remapper
{
private HashMap < String , String > fields = new HashMap < String , String > ();
private HashMap < String , String > funcs = new HashMap < String , String > ();
public ObfRemapper () {
try {
Field rawFieldMapsField = FMLDeobfuscatingRemapper . class . getDeclaredField ( "rawFieldMaps" );
Field rawMethodMapsField = FMLDeobfuscatingRemapper . class . getDeclaredField ( "rawMethodMaps" );
rawFieldMapsField . setAccessible ( true );
rawMethodMapsField . setAccessible ( true );
Map < String , Map < String , String >> rawFieldMaps = ( Map < String , Map < String , String >> ) rawFieldMapsField . get ( FMLDeobfuscatingRemapper . INSTANCE );
Map < String , Map < String , String >> rawMethodMaps = ( Map < String , Map < String , String >> ) rawMethodMapsField . get ( FMLDeobfuscatingRemapper . INSTANCE );
if ( rawFieldMaps == null )
throw new IllegalStateException ( "codechicken.lib.asm.ObfMapping loaded too early. Make sure all references are in or after the asm transformer load stage" );
for ( Map < String , String > map : rawFieldMaps . values ())
for ( Entry < String , String > entry : map . entrySet ())
if ( entry . getValue (). startsWith ( "field" ))
fields . put ( entry . getValue (), entry . getKey (). substring ( 0 , entry . getKey (). indexOf ( ':' )));
for ( Map < String , String > map : rawMethodMaps . values ())
for ( Entry < String , String > entry : map . entrySet ())
if ( entry . getValue (). startsWith ( "func" ))
funcs . put ( entry . getValue (), entry . getKey (). substring ( 0 , entry . getKey (). indexOf ( '(' )));
} catch ( Exception e ) {
throw new RuntimeException ( e );
}
}
@Override
public String mapMethodName ( String owner , String name , String desc ) {
String s = funcs . get ( name );
return s == null ? name : s ;
}
@Override
public String mapFieldName ( String owner , String name , String desc ) {
String s = fields . get ( name );
return s == null ? name : s ;
}
@Override
public String map ( String typeName ) {
return FMLDeobfuscatingRemapper . INSTANCE . unmap ( typeName );
}
}
public static ObfRemapper obfMapper = new ObfRemapper ();
2013-07-16 17:58:02 +10:00
public static Remapper mcpMapper = null ;
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
public static final boolean obfuscated ;
2014-04-07 14:02:47 +10:00
static {
2013-07-16 17:58:02 +10:00
boolean obf = true ;
2014-04-07 14:02:47 +10:00
try {
obf = Launch . classLoader . getClassBytes ( "net.minecraft.world.World" ) == null ;
} catch ( IOException ignored ) {}
2013-07-16 17:58:02 +10:00
obfuscated = obf ;
}
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
public String s_owner ;
public String s_name ;
public String s_desc ;
2014-04-07 14:02:47 +10:00
public ObfMapping ( String owner ) {
2013-07-17 18:18:57 +10:00
this ( owner , "" , "" );
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
public ObfMapping ( String owner , String name , String desc ) {
2013-07-16 17:58:02 +10:00
this . s_owner = owner ;
this . s_name = name ;
this . s_desc = desc ;
2014-04-07 14:02:47 +10:00
if ( s_owner . contains ( "." ))
2013-07-16 17:58:02 +10:00
throw new IllegalArgumentException ( s_owner );
}
2014-04-07 14:02:47 +10:00
public ObfMapping ( ObfMapping descmap , String subclass ) {
2013-07-16 17:58:02 +10:00
this ( subclass , descmap . s_name , descmap . s_desc );
}
2014-04-07 14:02:47 +10:00
public static ObfMapping fromDesc ( String s ) {
2013-07-19 01:00:09 +10:00
int lastDot = s . lastIndexOf ( '.' );
2014-04-07 14:02:47 +10:00
if ( lastDot < 0 )
2013-07-16 17:58:02 +10:00
return new ObfMapping ( s , "" , "" );
int sep = s . indexOf ( '(' ); //methods
int sep_end = sep ;
2014-04-07 14:02:47 +10:00
if ( sep < 0 ) {
2013-07-16 17:58:02 +10:00
sep = s . indexOf ( ' ' ); //some stuffs
2014-04-07 14:02:47 +10:00
sep_end = sep + 1 ;
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
if ( sep < 0 ) {
2013-07-16 17:58:02 +10:00
sep = s . indexOf ( ':' ); //fields
2014-04-07 14:02:47 +10:00
sep_end = sep + 1 ;
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
if ( sep < 0 )
2013-07-16 17:58:02 +10:00
return new ObfMapping ( s . substring ( 0 , lastDot ), s . substring ( lastDot + 1 ), "" );
2014-04-07 14:02:47 +10:00
return new ObfMapping ( s . substring ( 0 , lastDot ), s . substring ( lastDot + 1 , sep ), s . substring ( sep_end ));
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
public ObfMapping subclass ( String subclass ) {
2013-07-16 17:58:02 +10:00
return new ObfMapping ( this , subclass );
}
2014-04-07 14:02:47 +10:00
public boolean matches ( MethodNode node ) {
2013-07-16 17:58:02 +10:00
return s_name . equals ( node . name ) && s_desc . equals ( node . desc );
}
2014-04-07 14:02:47 +10:00
public boolean matches ( MethodInsnNode node ) {
2013-07-16 17:58:02 +10:00
return s_owner . equals ( node . owner ) && s_name . equals ( node . name ) && s_desc . equals ( node . desc );
}
2014-04-07 14:02:47 +10:00
public AbstractInsnNode toInsn ( int opcode ) {
if ( isClass ())
2013-07-16 17:58:02 +10:00
return new TypeInsnNode ( opcode , s_owner );
2014-04-07 14:02:47 +10:00
else if ( isMethod ())
2013-07-16 17:58:02 +10:00
return new MethodInsnNode ( opcode , s_owner , s_name , s_desc );
else
return new FieldInsnNode ( opcode , s_owner , s_name , s_desc );
}
2014-04-07 14:02:47 +10:00
public void visitTypeInsn ( MethodVisitor mv , int opcode ) {
2013-07-16 17:58:02 +10:00
mv . visitTypeInsn ( opcode , s_owner );
}
2014-04-07 14:02:47 +10:00
public void visitMethodInsn ( MethodVisitor mv , int opcode ) {
2013-07-16 17:58:02 +10:00
mv . visitMethodInsn ( opcode , s_owner , s_name , s_desc );
}
2014-04-07 14:02:47 +10:00
public void visitFieldInsn ( MethodVisitor mv , int opcode ) {
2013-07-16 17:58:02 +10:00
mv . visitFieldInsn ( opcode , s_owner , s_name , s_desc );
}
2014-04-07 14:02:47 +10:00
public boolean isClass ( String name ) {
2013-07-16 17:58:02 +10:00
return name . replace ( '.' , '/' ). equals ( s_owner );
}
2014-04-07 14:02:47 +10:00
public boolean matches ( String name , String desc ) {
2013-07-16 17:58:02 +10:00
return s_name . equals ( name ) && s_desc . equals ( desc );
}
2014-04-07 14:02:47 +10:00
public boolean matches ( FieldNode node ) {
2013-07-16 17:58:02 +10:00
return s_name . equals ( node . name ) && s_desc . equals ( node . desc );
}
2014-04-07 14:02:47 +10:00
public boolean matches ( FieldInsnNode node ) {
2013-07-16 17:58:02 +10:00
return s_owner . equals ( node . owner ) && s_name . equals ( node . name ) && s_desc . equals ( node . desc );
}
2014-04-07 14:02:47 +10:00
public String javaClass () {
2013-07-16 17:58:02 +10:00
return s_owner . replace ( '/' , '.' );
}
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
@Override
2014-04-07 14:02:47 +10:00
public boolean equals ( Object obj ) {
if ( ! ( obj instanceof ObfMapping ))
2013-07-16 17:58:02 +10:00
return false ;
2014-04-07 14:02:47 +10:00
ObfMapping desc = ( ObfMapping ) obj ;
2013-07-16 17:58:02 +10:00
return s_owner . equals ( desc . s_owner ) && s_name . equals ( desc . s_name ) && s_desc . equals ( desc . s_desc );
}
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
@Override
2014-04-07 14:02:47 +10:00
public int hashCode () {
2013-07-16 17:58:02 +10:00
return Objects . hashCode ( s_desc , s_name , s_owner );
}
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
@Override
2014-04-07 14:02:47 +10:00
public String toString () {
if ( s_name . length () == 0 )
return "[" + s_owner + "]" ;
if ( s_desc . length () == 0 )
return "[" + s_owner + "." + s_name + "]" ;
return "[" + ( isMethod () ? methodDesc () : fieldDesc ()) + "]" ;
2013-07-19 01:00:09 +10:00
}
2014-04-07 14:02:47 +10:00
public String methodDesc () {
return s_owner + "." + s_name + s_desc ;
2013-07-19 01:00:09 +10:00
}
2014-04-07 14:02:47 +10:00
public String fieldDesc () {
return s_owner + "." + s_name + ":" + s_desc ;
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
public boolean isClass () {
2013-07-16 17:58:02 +10:00
return s_name . length () == 0 ;
}
2014-04-07 14:02:47 +10:00
public boolean isMethod () {
2013-07-16 17:58:02 +10:00
return s_desc . contains ( "(" );
}
2014-04-07 14:02:47 +10:00
public boolean isField () {
2013-07-16 17:58:02 +10:00
return ! isClass () && ! isMethod ();
}
2014-04-07 14:02:47 +10:00
public ObfMapping map ( Remapper mapper ) {
if ( mapper == null )
return this ;
if ( isMethod ())
2013-07-16 17:58:02 +10:00
s_name = mapper . mapMethodName ( s_owner , s_name , s_desc );
2014-04-07 14:02:47 +10:00
else if ( isField ())
2013-07-16 17:58:02 +10:00
s_name = mapper . mapFieldName ( s_owner , s_name , s_desc );
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
s_owner = mapper . mapType ( s_owner );
2014-04-07 14:02:47 +10:00
if ( isMethod ())
2013-07-19 01:00:09 +10:00
s_desc = mapper . mapMethodDesc ( s_desc );
2014-04-07 14:02:47 +10:00
else if ( s_desc . length () > 0 )
2013-07-16 17:58:02 +10:00
s_desc = mapper . mapDesc ( s_desc );
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
return this ;
}
2014-04-07 14:02:47 +10:00
public ObfMapping toRuntime () {
map ( mcpMapper );
2013-07-16 17:58:02 +10:00
return this ;
}
2014-04-07 14:02:47 +10:00
public ObfMapping toClassloading () {
map ( obfuscated ? obfMapper : mcpMapper );
return this ;
}
public ObfMapping copy () {
2013-07-19 01:00:09 +10:00
return new ObfMapping ( s_owner , s_name , s_desc );
2013-07-16 17:58:02 +10:00
}
}