Files
CodeChickenCore/codechicken/lib/asm/ObfMapping.java
T

257 lines
8.0 KiB
Java
Raw Normal View History

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
}
}