Merge branch 'runtimedeobf' into snapshot15
This commit is contained in:
commit
e4dd3791ef
13 changed files with 426 additions and 27 deletions
|
@ -12,7 +12,7 @@ import cpw.mods.fml.relauncher.IClassTransformer;
|
|||
public class ASMTransformer implements IClassTransformer
|
||||
{
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
public byte[] transform(String name,String transformedName, byte[] bytes)
|
||||
{
|
||||
if ("net.minecraft.src.Block".equals(name))
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ public class ASMTransformer implements IClassTransformer
|
|||
cn.accept(cw);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cpw.mods.fml.common.asm;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.ObjectInputStream.GetField;
|
||||
import java.io.StringReader;
|
||||
|
@ -27,7 +28,8 @@ import org.objectweb.asm.FieldVisitor;
|
|||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import cpw.mods.fml.common.CertificateHelper;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
|
||||
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||
import cpw.mods.fml.relauncher.IFMLCallHook;
|
||||
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
||||
|
||||
|
@ -72,17 +74,17 @@ public class FMLSanityChecker implements IFMLCallHook
|
|||
String fingerprint = CertificateHelper.getFingerprint(cert);
|
||||
if (fingerprint.equals(FMLFINGERPRINT))
|
||||
{
|
||||
FMLLog.info("Found valid fingerprint for FML. Certificate fingerprint %s", fingerprint);
|
||||
FMLRelaunchLog.info("Found valid fingerprint for FML. Certificate fingerprint %s", fingerprint);
|
||||
goodFML = true;
|
||||
}
|
||||
else if (fingerprint.equals(FORGEFINGERPRINT))
|
||||
{
|
||||
FMLLog.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint %s", fingerprint);
|
||||
FMLRelaunchLog.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint %s", fingerprint);
|
||||
goodFML = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("Found invalid fingerprint for FML: %s", fingerprint);
|
||||
FMLRelaunchLog.severe("Found invalid fingerprint for FML: %s", fingerprint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +95,7 @@ public class FMLSanityChecker implements IFMLCallHook
|
|||
}
|
||||
if (!goodFML)
|
||||
{
|
||||
FMLLog.severe("FML appears to be missing any signature data. This is not a good thing");
|
||||
FMLRelaunchLog.severe("FML appears to be missing any signature data. This is not a good thing");
|
||||
}
|
||||
byte[] mlClass = cl.getClassBytes("ModLoader");
|
||||
// Only care in obfuscated env
|
||||
|
@ -124,6 +126,7 @@ public class FMLSanityChecker implements IFMLCallHook
|
|||
public void injectData(Map<String, Object> data)
|
||||
{
|
||||
cl = (RelaunchClassLoader) data.get("classLoader");
|
||||
FMLDeobfuscatingRemapper.INSTANCE.setup((File)data.get("mcLocation"), cl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ public class AccessTransformer implements IClassTransformer
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
public byte[] transform(String name, String transformedName, byte[] bytes)
|
||||
{
|
||||
if (bytes == null) { return null; }
|
||||
if (!modifiers.containsKey(name)) { return bytes; }
|
||||
|
@ -375,7 +375,7 @@ public class AccessTransformer implements IClassTransformer
|
|||
|
||||
for (AccessTransformer trans : transformers)
|
||||
{
|
||||
entryData = trans.transform(name, entryData);
|
||||
entryData = trans.transform(name, name, entryData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.commons.RemappingClassAdapter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
|
||||
import cpw.mods.fml.common.asm.transformers.deobf.FMLRemappingAdapter;
|
||||
import cpw.mods.fml.relauncher.IClassNameTransformer;
|
||||
import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
|
||||
public class DeobfuscationTransformer implements IClassTransformer, IClassNameTransformer {
|
||||
|
||||
@Override
|
||||
public byte[] transform(String name, String transformedName, byte[] bytes)
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ClassReader classReader = new ClassReader(bytes);
|
||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
RemappingClassAdapter remapAdapter = new FMLRemappingAdapter(classWriter);
|
||||
classReader.accept(remapAdapter, ClassReader.EXPAND_FRAMES);
|
||||
return classWriter.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String remapClassName(String name)
|
||||
{
|
||||
return FMLDeobfuscatingRemapper.INSTANCE.map(name.replace('.','/')).replace('/', '.');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String unmapClassName(String name)
|
||||
{
|
||||
return FMLDeobfuscatingRemapper.INSTANCE.unmap(name.replace('.', '/')).replace('/','.');
|
||||
}
|
||||
|
||||
}
|
|
@ -87,7 +87,7 @@ public class MarkerTransformer implements IClassTransformer
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
public byte[] transform(String name, String transformedName, byte[] bytes)
|
||||
{
|
||||
if (bytes == null) { return null; }
|
||||
if (!markers.containsKey(name)) { return bytes; }
|
||||
|
@ -240,7 +240,7 @@ public class MarkerTransformer implements IClassTransformer
|
|||
|
||||
for (MarkerTransformer trans : transformers)
|
||||
{
|
||||
entryData = trans.transform(name, entryData);
|
||||
entryData = trans.transform(name, name, entryData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ public class SideTransformer implements IClassTransformer
|
|||
private static final boolean DEBUG = false;
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
public byte[] transform(String name, String transformedName, byte[] bytes)
|
||||
{
|
||||
if (bytes == null) { return null; }
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class SideTransformer implements IClassTransformer
|
|||
classNode.accept(writer);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
private boolean remove(List<AnnotationNode> anns, String side)
|
||||
{
|
||||
if (anns == null)
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
package cpw.mods.fml.common.asm.transformers.deobf;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.ImmutableBiMap.Builder;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.common.io.InputSupplier;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
||||
|
||||
public class FMLDeobfuscatingRemapper extends Remapper {
|
||||
public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper();
|
||||
|
||||
private BiMap<String, String> classNameBiMap;
|
||||
private Map<String,Map<String,String>> rawFieldMaps;
|
||||
private Map<String,Map<String,String>> rawMethodMaps;
|
||||
|
||||
private Map<String,Map<String,String>> fieldNameMaps;
|
||||
private Map<String,Map<String,String>> methodNameMaps;
|
||||
|
||||
private RelaunchClassLoader classLoader;
|
||||
|
||||
private FMLDeobfuscatingRemapper()
|
||||
{
|
||||
}
|
||||
|
||||
public void setup(File mcDir, RelaunchClassLoader classLoader)
|
||||
{
|
||||
this.classLoader = classLoader;
|
||||
try
|
||||
{
|
||||
File libDir = new File(mcDir, "lib");
|
||||
File mapData = new File(libDir, "deobfuscation_data.zip");
|
||||
ZipFile mapZip = new ZipFile(mapData);
|
||||
ZipEntry classData = mapZip.getEntry("joined.srg");
|
||||
ZipInputSupplier zis = new ZipInputSupplier(mapZip, classData);
|
||||
InputSupplier<InputStreamReader> srgSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8);
|
||||
List<String> srgList = CharStreams.readLines(srgSupplier);
|
||||
rawMethodMaps = Maps.newHashMap();
|
||||
rawFieldMaps = Maps.newHashMap();
|
||||
Builder<String, String> builder = ImmutableBiMap.<String,String>builder();
|
||||
Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults();
|
||||
for (String line : srgList)
|
||||
{
|
||||
String[] parts = Iterables.toArray(splitter.split(line),String.class);
|
||||
String typ = parts[0];
|
||||
if ("CL".equals(typ))
|
||||
{
|
||||
parseClass(builder, parts);
|
||||
}
|
||||
else if ("MD".equals(typ))
|
||||
{
|
||||
parseMethod(parts);
|
||||
}
|
||||
else if ("FD".equals(typ))
|
||||
{
|
||||
parseField(parts);
|
||||
}
|
||||
}
|
||||
classNameBiMap = builder.build();
|
||||
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
FMLRelaunchLog.log(Level.SEVERE, ioe, "An error occurred loading the deobfuscation map data");
|
||||
}
|
||||
methodNameMaps = Maps.newHashMapWithExpectedSize(rawMethodMaps.size());
|
||||
fieldNameMaps = Maps.newHashMapWithExpectedSize(rawFieldMaps.size());
|
||||
}
|
||||
private void parseField(String[] parts)
|
||||
{
|
||||
String oldSrg = parts[1];
|
||||
int lastOld = oldSrg.lastIndexOf('/');
|
||||
String cl = oldSrg.substring(0,lastOld);
|
||||
String oldName = oldSrg.substring(lastOld+1);
|
||||
String newSrg = parts[2];
|
||||
int lastNew = newSrg.lastIndexOf('/');
|
||||
String newName = newSrg.substring(lastNew+1);
|
||||
if (!rawFieldMaps.containsKey(cl))
|
||||
{
|
||||
rawFieldMaps.put(cl, Maps.<String,String>newHashMap());
|
||||
}
|
||||
rawFieldMaps.get(cl).put(oldName, newName);
|
||||
}
|
||||
|
||||
private void parseClass(Builder<String, String> builder, String[] parts)
|
||||
{
|
||||
builder.put(parts[1],parts[2]);
|
||||
}
|
||||
|
||||
private void parseMethod(String[] parts)
|
||||
{
|
||||
String oldSrg = parts[1];
|
||||
int lastOld = oldSrg.lastIndexOf('/');
|
||||
String cl = oldSrg.substring(0,lastOld);
|
||||
String oldName = oldSrg.substring(lastOld+1);
|
||||
String sig = parts[2];
|
||||
String newSrg = parts[3];
|
||||
int lastNew = newSrg.lastIndexOf('/');
|
||||
String newName = newSrg.substring(lastNew+1);
|
||||
if (!rawMethodMaps.containsKey(cl))
|
||||
{
|
||||
rawMethodMaps.put(cl, Maps.<String,String>newHashMap());
|
||||
}
|
||||
rawMethodMaps.get(cl).put(oldName+sig, newName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapFieldName(String owner, String name, String desc)
|
||||
{
|
||||
if (classNameBiMap == null)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
Map<String, String> fieldMap = getFieldMap(owner);
|
||||
return fieldMap!=null && fieldMap.containsKey(name) ? fieldMap.get(name) : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String map(String typeName)
|
||||
{
|
||||
if (classNameBiMap == null)
|
||||
{
|
||||
return typeName;
|
||||
}
|
||||
|
||||
String result = classNameBiMap.containsKey(typeName) ? classNameBiMap.get(typeName) : typeName;
|
||||
return result;
|
||||
}
|
||||
|
||||
public String unmap(String typeName)
|
||||
{
|
||||
if (classNameBiMap == null)
|
||||
{
|
||||
return typeName;
|
||||
}
|
||||
return classNameBiMap.containsValue(typeName) ? classNameBiMap.inverse().get(typeName) : typeName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String mapMethodName(String owner, String name, String desc)
|
||||
{
|
||||
if (classNameBiMap==null)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
Map<String, String> methodMap = getMethodMap(owner);
|
||||
String methodDescriptor = name+desc;
|
||||
return methodMap!=null && methodMap.containsKey(methodDescriptor) ? methodMap.get(methodDescriptor) : name;
|
||||
}
|
||||
|
||||
private Map<String,String> getFieldMap(String className)
|
||||
{
|
||||
if (!fieldNameMaps.containsKey(className))
|
||||
{
|
||||
findAndMergeSuperMaps(className);
|
||||
}
|
||||
return fieldNameMaps.get(className);
|
||||
}
|
||||
|
||||
private Map<String,String> getMethodMap(String className)
|
||||
{
|
||||
if (!methodNameMaps.containsKey(className))
|
||||
{
|
||||
findAndMergeSuperMaps(className);
|
||||
}
|
||||
return methodNameMaps.get(className);
|
||||
}
|
||||
|
||||
private void findAndMergeSuperMaps(String name)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] classBytes = classLoader.getClassBytes(name);
|
||||
if (classBytes == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ClassReader cr = new ClassReader(classBytes);
|
||||
String superName = cr.getSuperName();
|
||||
String[] interfaces = cr.getInterfaces();
|
||||
if (interfaces == null)
|
||||
{
|
||||
interfaces = new String[0];
|
||||
}
|
||||
mergeSuperMaps(name, superName, interfaces);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void mergeSuperMaps(String name, String superName, String[] interfaces)
|
||||
{
|
||||
if (classNameBiMap == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<String> allParents = ImmutableList.<String>builder().add(superName).addAll(Arrays.asList(interfaces)).build();
|
||||
for (String parentThing : allParents)
|
||||
{
|
||||
if (superName != null && classNameBiMap.containsKey(superName) && !methodNameMaps.containsKey(superName))
|
||||
{
|
||||
findAndMergeSuperMaps(superName);
|
||||
}
|
||||
}
|
||||
Map<String, String> methodMap = Maps.<String,String>newHashMap();
|
||||
Map<String, String> fieldMap = Maps.<String,String>newHashMap();
|
||||
for (String parentThing : allParents)
|
||||
{
|
||||
if (methodNameMaps.containsKey(parentThing))
|
||||
{
|
||||
methodMap.putAll(methodNameMaps.get(parentThing));
|
||||
}
|
||||
if (fieldNameMaps.containsKey(parentThing))
|
||||
{
|
||||
fieldMap.putAll(fieldNameMaps.get(parentThing));
|
||||
}
|
||||
}
|
||||
if (rawMethodMaps.containsKey(name))
|
||||
{
|
||||
methodMap.putAll(rawMethodMaps.get(name));
|
||||
}
|
||||
if (rawFieldMaps.containsKey(name))
|
||||
{
|
||||
fieldMap.putAll(rawFieldMaps.get(name));
|
||||
}
|
||||
methodNameMaps.put(name, ImmutableMap.copyOf(methodMap));
|
||||
fieldNameMaps.put(name, ImmutableMap.copyOf(fieldMap));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package cpw.mods.fml.common.asm.transformers.deobf;
|
||||
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
import org.objectweb.asm.commons.RemappingClassAdapter;
|
||||
|
||||
public class FMLRemappingAdapter extends RemappingClassAdapter {
|
||||
public FMLRemappingAdapter(ClassVisitor cv)
|
||||
{
|
||||
super(cv, FMLDeobfuscatingRemapper.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
if (interfaces == null)
|
||||
{
|
||||
interfaces = new String[0];
|
||||
}
|
||||
FMLDeobfuscatingRemapper.INSTANCE.mergeSuperMaps(name, superName, interfaces);
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package cpw.mods.fml.common.asm.transformers.deobf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import com.google.common.io.InputSupplier;
|
||||
|
||||
public class ZipInputSupplier implements InputSupplier<InputStream> {
|
||||
private ZipFile zipFile;
|
||||
private ZipEntry zipEntry;
|
||||
|
||||
public ZipInputSupplier(ZipFile zip, ZipEntry entry)
|
||||
{
|
||||
this.zipFile = zip;
|
||||
this.zipEntry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInput() throws IOException
|
||||
{
|
||||
return zipFile.getInputStream(zipEntry);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,9 +13,11 @@ public class FMLCorePlugin implements IFMLLoadingPlugin
|
|||
@Override
|
||||
public String[] getASMTransformerClass()
|
||||
{
|
||||
return new String[] {"cpw.mods.fml.common.asm.transformers.AccessTransformer",
|
||||
return new String[] {
|
||||
"cpw.mods.fml.common.asm.transformers.AccessTransformer",
|
||||
"cpw.mods.fml.common.asm.transformers.MarkerTransformer",
|
||||
"cpw.mods.fml.common.asm.transformers.SideTransformer"
|
||||
"cpw.mods.fml.common.asm.transformers.SideTransformer",
|
||||
"cpw.mods.fml.common.asm.transformers.DeobfuscationTransformer",
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package cpw.mods.fml.relauncher;
|
||||
|
||||
public interface IClassNameTransformer {
|
||||
public String remapClassName(String name);
|
||||
|
||||
public String unmapClassName(String name);
|
||||
}
|
|
@ -2,5 +2,5 @@ package cpw.mods.fml.relauncher;
|
|||
|
||||
public interface IClassTransformer
|
||||
{
|
||||
public byte[] transform(String name, byte[] bytes);
|
||||
public byte[] transform(String name, String transformedName, byte[] bytes);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
private Set<String> classLoaderExceptions = new HashSet<String>();
|
||||
private Set<String> transformerExceptions = new HashSet<String>();
|
||||
private Map<Package,Manifest> packageManifests = new HashMap<Package,Manifest>();
|
||||
private IClassNameTransformer renameTransformer;
|
||||
|
||||
private static Manifest EMPTY = new Manifest();
|
||||
|
||||
|
@ -68,15 +69,23 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
|
||||
// standard transformer exclusions
|
||||
addTransformerExclusion("javax.");
|
||||
addTransformerExclusion("argo.");
|
||||
addTransformerExclusion("org.objectweb.asm.");
|
||||
addTransformerExclusion("com.google.common.");
|
||||
addTransformerExclusion("org.bouncycastle.");
|
||||
addTransformerExclusion("cpw.mods.fml.common.asm.transformers.deobf.");
|
||||
}
|
||||
|
||||
public void registerTransformer(String transformerClassName)
|
||||
{
|
||||
try
|
||||
{
|
||||
transformers.add((IClassTransformer) loadClass(transformerClassName).newInstance());
|
||||
IClassTransformer transformer = (IClassTransformer) loadClass(transformerClassName).newInstance();
|
||||
transformers.add(transformer);
|
||||
if (transformer instanceof IClassNameTransformer && renameTransformer == null)
|
||||
{
|
||||
renameTransformer = (IClassNameTransformer) transformer;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -124,9 +133,11 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
try
|
||||
{
|
||||
CodeSigner[] signers = null;
|
||||
int lastDot = name.lastIndexOf('.');
|
||||
String pkgname = lastDot == -1 ? "" : name.substring(0, lastDot);
|
||||
String fName = name.replace('.', '/').concat(".class");
|
||||
String transformedName = transformName(name);
|
||||
String untransformedName = untransformName(name);
|
||||
int lastDot = untransformedName.lastIndexOf('.');
|
||||
String pkgname = lastDot == -1 ? "" : untransformedName.substring(0, lastDot);
|
||||
String fName = untransformedName.replace('.', '/').concat(".class");
|
||||
String pkgPath = pkgname.replace('.', '/');
|
||||
URLConnection urlConnection = findCodeSourceConnectionFor(fName);
|
||||
if (urlConnection instanceof JarURLConnection && lastDot > -1)
|
||||
|
@ -138,7 +149,7 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
Manifest mf = jf.getManifest();
|
||||
JarEntry ent = jf.getJarEntry(fName);
|
||||
Package pkg = getPackage(pkgname);
|
||||
getClassBytes(name);
|
||||
getClassBytes(untransformedName);
|
||||
signers = ent.getCodeSigners();
|
||||
if (pkg == null)
|
||||
{
|
||||
|
@ -171,10 +182,10 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
FMLLog.severe("The URL %s is defining elements for sealed path %s", urlConnection.getURL(), pkgname);
|
||||
}
|
||||
}
|
||||
byte[] basicClass = getClassBytes(name);
|
||||
byte[] transformedClass = runTransformers(name, basicClass);
|
||||
Class<?> cl = defineClass(name, transformedClass, 0, transformedClass.length, new CodeSource(urlConnection.getURL(), signers));
|
||||
cachedClasses.put(name, cl);
|
||||
byte[] basicClass = getClassBytes(untransformedName);
|
||||
byte[] transformedClass = runTransformers(untransformedName, transformedName, basicClass);
|
||||
Class<?> cl = defineClass(transformedName, transformedClass, 0, transformedClass.length, new CodeSource(urlConnection.getURL(), signers));
|
||||
cachedClasses.put(transformedName, cl);
|
||||
return cl;
|
||||
}
|
||||
catch (Throwable e)
|
||||
|
@ -188,6 +199,30 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
}
|
||||
}
|
||||
|
||||
private String untransformName(String name)
|
||||
{
|
||||
if (renameTransformer != null)
|
||||
{
|
||||
return renameTransformer.unmapClassName(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
private String transformName(String name)
|
||||
{
|
||||
if (renameTransformer != null)
|
||||
{
|
||||
return renameTransformer.remapClassName(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSealed(String path, Manifest man)
|
||||
{
|
||||
Attributes attr = man.getAttributes(path);
|
||||
|
@ -223,11 +258,11 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
}
|
||||
}
|
||||
|
||||
private byte[] runTransformers(String name, byte[] basicClass)
|
||||
private byte[] runTransformers(String name, String transformedName, byte[] basicClass)
|
||||
{
|
||||
for (IClassTransformer transformer : transformers)
|
||||
{
|
||||
basicClass = transformer.transform(name, basicClass);
|
||||
basicClass = transformer.transform(name, transformedName, basicClass);
|
||||
}
|
||||
return basicClass;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue