Add debugging for deobfuscation
Add negative caching for field and method maps. Should shortcut some work Fix handling the case where a class doesn't exist, but still needs deobf Ask the patch manager for the bytes for the class, not the classLoader Fix up some more places where we should look for a patched class Fix problem with empty source classes and runtime deobfuscation
This commit is contained in:
parent
c1623cb8e3
commit
96d9c3b8bc
4 changed files with 57 additions and 22 deletions
|
@ -241,8 +241,8 @@ public class FMLSanityChecker implements IFMLCallHook
|
|||
cl = (LaunchClassLoader) data.get("classLoader");
|
||||
File mcDir = (File)data.get("mcLocation");
|
||||
fmlLocation = (File)data.get("coremodLocation");
|
||||
FMLDeobfuscatingRemapper.INSTANCE.setup(mcDir, cl, (String) data.get("deobfuscationFileName"));
|
||||
ClassPatchManager.INSTANCE.setup(FMLLaunchHandler.side());
|
||||
FMLDeobfuscatingRemapper.INSTANCE.setup(mcDir, cl, (String) data.get("deobfuscationFileName"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ import com.google.common.io.CharStreams;
|
|||
import com.google.common.io.InputSupplier;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.patcher.ClassPatchManager;
|
||||
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
|
@ -71,6 +72,11 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
|||
|
||||
private LaunchClassLoader classLoader;
|
||||
|
||||
|
||||
private static final boolean DEBUG_REMAPPING = Boolean.parseBoolean(System.getProperty("fml.remappingDebug", "false"));
|
||||
private static final boolean DUMP_FIELD_MAPS = Boolean.parseBoolean(System.getProperty("fml.remappingDebug.dumpFieldMaps", "false")) && DEBUG_REMAPPING;
|
||||
private static final boolean DUMP_METHOD_MAPS = Boolean.parseBoolean(System.getProperty("fml.remappingDebug.dumpMethodMaps", "false")) && DEBUG_REMAPPING;
|
||||
|
||||
private FMLDeobfuscatingRemapper()
|
||||
{
|
||||
classNameBiMap=ImmutableBiMap.of();
|
||||
|
@ -202,6 +208,10 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
|||
*/
|
||||
private Map<String,Map<String,String>> fieldDescriptions = Maps.newHashMap();
|
||||
|
||||
// Cache null values so we don't waste time trying to recompute classes with no field or method maps
|
||||
private Set<String> negativeCacheMethods = Sets.newHashSet();
|
||||
private Set<String> negativeCacheFields = Sets.newHashSet();
|
||||
|
||||
private String getFieldType(String owner, String name)
|
||||
{
|
||||
if (fieldDescriptions.containsKey(owner))
|
||||
|
@ -212,7 +222,7 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
|||
{
|
||||
try
|
||||
{
|
||||
byte[] classBytes = classLoader.getClassBytes(owner);
|
||||
byte[] classBytes = ClassPatchManager.INSTANCE.getPatchedResource(owner, map(owner).replace('/', '.'), classLoader);
|
||||
if (classBytes == null)
|
||||
{
|
||||
return null;
|
||||
|
@ -288,7 +298,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
|||
|
||||
String result = classNameBiMap.containsKey(realType) ? classNameBiMap.get(realType) : mcpNameBiMap.containsKey(realType) ? mcpNameBiMap.get(realType) : realType;
|
||||
result = dollarIdx > -1 ? result+"$"+subType : result;
|
||||
// System.out.printf("Mapping %s=>%s\n",typeName,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -305,7 +314,6 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
|||
|
||||
String result = classNameBiMap.containsValue(realType) ? classNameBiMap.inverse().get(realType) : mcpNameBiMap.containsValue(realType) ? mcpNameBiMap.inverse().get(realType) : realType;
|
||||
result = dollarIdx > -1 ? result+"$"+subType : result;
|
||||
// System.out.printf("Unmapping %s=>%s\n",typeName,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -324,18 +332,36 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
|||
|
||||
private Map<String,String> getFieldMap(String className)
|
||||
{
|
||||
if (!fieldNameMaps.containsKey(className))
|
||||
if (!fieldNameMaps.containsKey(className) && !negativeCacheFields.contains(className))
|
||||
{
|
||||
findAndMergeSuperMaps(className);
|
||||
if (!fieldNameMaps.containsKey(className))
|
||||
{
|
||||
negativeCacheFields.add(className);
|
||||
}
|
||||
|
||||
if (DUMP_FIELD_MAPS)
|
||||
{
|
||||
FMLRelaunchLog.finest("Field map for %s : %s", className, fieldNameMaps.get(className));
|
||||
}
|
||||
}
|
||||
return fieldNameMaps.get(className);
|
||||
}
|
||||
|
||||
private Map<String,String> getMethodMap(String className)
|
||||
{
|
||||
if (!methodNameMaps.containsKey(className))
|
||||
if (!methodNameMaps.containsKey(className) && !negativeCacheMethods.contains(className))
|
||||
{
|
||||
findAndMergeSuperMaps(className);
|
||||
if (!methodNameMaps.containsKey(className))
|
||||
{
|
||||
negativeCacheMethods.add(className);
|
||||
}
|
||||
if (DUMP_METHOD_MAPS)
|
||||
{
|
||||
FMLRelaunchLog.finest("Method map for %s : %s", className, methodNameMaps.get(className));
|
||||
}
|
||||
|
||||
}
|
||||
return methodNameMaps.get(className);
|
||||
}
|
||||
|
@ -344,17 +370,14 @@ public class FMLDeobfuscatingRemapper extends Remapper {
|
|||
{
|
||||
try
|
||||
{
|
||||
byte[] classBytes = classLoader.getClassBytes(name);
|
||||
if (classBytes == null)
|
||||
String superName = null;
|
||||
String[] interfaces = new String[0];
|
||||
byte[] classBytes = ClassPatchManager.INSTANCE.getPatchedResource(name, map(name), classLoader);
|
||||
if (classBytes != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ClassReader cr = new ClassReader(classBytes);
|
||||
String superName = cr.getSuperName();
|
||||
String[] interfaces = cr.getInterfaces();
|
||||
if (interfaces == null)
|
||||
{
|
||||
interfaces = new String[0];
|
||||
ClassReader cr = new ClassReader(classBytes);
|
||||
superName = cr.getSuperName();
|
||||
interfaces = cr.getInterfaces();
|
||||
}
|
||||
mergeSuperMaps(name, superName, interfaces);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.security.CodeSource;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarInputStream;
|
||||
|
@ -19,6 +20,8 @@ import java.util.jar.Pack200;
|
|||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
|
||||
import LZMA.LzmaInputStream;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
@ -26,6 +29,7 @@ import com.google.common.base.Strings;
|
|||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
@ -44,6 +48,7 @@ public class ClassPatchManager {
|
|||
private GDiffPatcher patcher = new GDiffPatcher();
|
||||
private ListMultimap<String, ClassPatch> patches;
|
||||
|
||||
private Map<String,byte[]> patchedClasses = Maps.newHashMap();
|
||||
private File tempDir;
|
||||
private ClassPatchManager()
|
||||
{
|
||||
|
@ -54,12 +59,22 @@ public class ClassPatchManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public byte[] getPatchedResource(String name, String mappedName, LaunchClassLoader loader) throws IOException
|
||||
{
|
||||
byte[] rawClassBytes = loader.getClassBytes(name);
|
||||
return applyPatch(name, mappedName, rawClassBytes);
|
||||
}
|
||||
public byte[] applyPatch(String name, String mappedName, byte[] inputData)
|
||||
{
|
||||
if (patches == null)
|
||||
{
|
||||
return inputData;
|
||||
}
|
||||
if (patchedClasses.containsKey(name))
|
||||
{
|
||||
return patchedClasses.get(name);
|
||||
}
|
||||
List<ClassPatch> list = patches.get(name);
|
||||
if (list.isEmpty())
|
||||
{
|
||||
|
@ -69,7 +84,7 @@ public class ClassPatchManager {
|
|||
FMLRelaunchLog.fine("Runtime patching class %s (input size %d), found %d patch%s", mappedName, (inputData == null ? 0 : inputData.length), list.size(), list.size()!=1 ? "es" : "");
|
||||
for (ClassPatch patch: list)
|
||||
{
|
||||
if (!patch.targetClassName.equals(mappedName))
|
||||
if (!patch.targetClassName.equals(mappedName) && !patch.sourceClassName.equals(name))
|
||||
{
|
||||
FMLRelaunchLog.warning("Binary patch found %s for wrong class %s", patch.targetClassName, mappedName);
|
||||
}
|
||||
|
@ -128,6 +143,7 @@ public class ClassPatchManager {
|
|||
FMLRelaunchLog.log(Level.SEVERE, e, "Failed to write %s to %s", mappedName, tempDir.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
patchedClasses.put(name,inputData);
|
||||
return inputData;
|
||||
}
|
||||
|
||||
|
@ -185,6 +201,7 @@ public class ClassPatchManager {
|
|||
} while (true);
|
||||
FMLRelaunchLog.fine("Read %d binary patches", patches.size());
|
||||
FMLRelaunchLog.fine("Patch list :\n\t%s", Joiner.on("\t\n").join(patches.asMap().entrySet()));
|
||||
patchedClasses.clear();
|
||||
}
|
||||
|
||||
private ClassPatch readPatch(JarEntry patchEntry, JarInputStream jis)
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
package cpw.mods.fml.common.patcher;
|
||||
|
||||
public class ClassPatchingTransformer {
|
||||
|
||||
}
|
Loading…
Reference in a new issue