Skip to content

Commit a53927c

Browse files
committed
Fix remaining incompatibilities with Forge
1 parent 32c8b63 commit a53927c

File tree

2 files changed

+65
-19
lines changed

2 files changed

+65
-19
lines changed

src/main/java/net/minecraft/launchwrapper/LaunchClassLoader.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class LaunchClassLoader extends org.mcphackers.launchwrapper.loader.Launc
2020
private final Map<String, byte[]> resourceCache = Collections.<String, byte[]>emptyMap();
2121
private final Set<String> invalidClasses = new HashSet<String>();
2222
private final Set<String> classLoaderExceptions;
23-
private final Set<String> transformerExceptions = new HashSet<String>();
23+
private final Set<String> transformerExceptions;
2424
private final List<IClassTransformer> transformers = new ArrayList<IClassTransformer>();
2525
private IClassNameTransformer renameTransformer;
2626

@@ -36,8 +36,12 @@ public LaunchClassLoader(URL[] sources) {
3636
}
3737
public LaunchClassLoader(URL[] sources, ClassLoader parent) {
3838
super(sources, parent);
39+
for (URL source : sources) {
40+
this.sources.add(source);
41+
}
3942
useDummyCert = false; // Forge only works with Certificate array that isn't 0-sized or if certificates are null
4043
classLoaderExceptions = exclusions;
44+
transformerExceptions = transformerExclusions;
4145
addClassLoaderExclusion("org.lwjgl.");
4246
addClassLoaderExclusion("org.apache.logging.");
4347
addClassLoaderExclusion("net.minecraft.launchwrapper.");
@@ -115,11 +119,6 @@ protected byte[] getTransformedClass(String name) throws IOException {
115119
String untransformedName = untransformName(name);
116120
String transformedName = transformName(name);
117121
byte[] classData = getClassBytes(untransformedName);
118-
for (final String exception : transformerExceptions) {
119-
if (name.startsWith(exception)) {
120-
return classData;
121-
}
122-
}
123122
return runTrasformers(untransformedName, transformedName, classData);
124123
}
125124

src/main/java/org/mcphackers/launchwrapper/loader/LaunchClassLoader.java

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,24 @@
77
import java.io.IOException;
88
import java.io.InputStream;
99
import java.lang.reflect.InvocationTargetException;
10+
import java.net.JarURLConnection;
1011
import java.net.MalformedURLException;
1112
import java.net.URL;
1213
import java.net.URLClassLoader;
14+
import java.net.URLConnection;
15+
import java.security.CodeSigner;
1316
import java.security.CodeSource;
1417
import java.security.ProtectionDomain;
15-
import java.security.cert.Certificate;
1618
import java.util.ArrayList;
1719
import java.util.Enumeration;
1820
import java.util.HashMap;
1921
import java.util.HashSet;
2022
import java.util.List;
2123
import java.util.Map;
2224
import java.util.Set;
25+
import java.util.jar.JarEntry;
26+
import java.util.jar.JarFile;
27+
import java.util.jar.Manifest;
2328

2429
import org.mcphackers.launchwrapper.Launch;
2530
import org.mcphackers.launchwrapper.tweak.Tweaker;
@@ -44,6 +49,7 @@ public class LaunchClassLoader extends URLClassLoader implements ClassNodeSource
4449
protected HighPriorityClassLoader urlClassLoader;
4550
protected List<Tweaker> tweaks;
4651
protected Set<String> exclusions = new HashSet<String>();
52+
protected Set<String> transformerExclusions = new HashSet<String>();
4753
/**
4854
* Keys should contain dots
4955
*/
@@ -221,6 +227,12 @@ public Class<?> findClass(String name) throws ClassNotFoundException {
221227
return parent.loadClass(name);
222228
}
223229
}
230+
231+
for (String prefix : transformerExclusions) {
232+
if (name.startsWith(prefix)) {
233+
return super.findClass(name);
234+
}
235+
}
224236
return redefineClass(name);
225237
}
226238

@@ -330,7 +342,7 @@ protected Class<?> redefineClass(String name) throws ClassNotFoundException {
330342
if (data == null) {
331343
throw new ClassNotFoundException(transformedName);
332344
}
333-
return defineClass(transformedName, data);
345+
return defineClass(transformedName, data, getProtectionDomain(name));
334346
} catch (IOException e) {
335347
throw new ClassNotFoundException(transformedName, e);
336348
}
@@ -376,44 +388,79 @@ public void setLoaderTweakers(List<Tweaker> classLoaderTweaks) {
376388
}
377389

378390
private Class<?> defineClass(String name, byte[] classData) {
391+
return defineClass(name, classData, getProtectionDomain(name));
392+
}
393+
394+
private Class<?> defineClass(String name, byte[] classData, ProtectionDomain protectionDomain) {
379395
int i = name.lastIndexOf('.');
380396
if (i != -1) {
381397
String pkgName = name.substring(0, i);
382398
if (getPackage(pkgName) == null) {
383399
definePackage(pkgName, null, null, null, null, null, null, null);
384400
}
385401
}
386-
return defineClass(name, classData, 0, classData.length, getProtectionDomain(name));
402+
return defineClass(name, classData, 0, classData.length, protectionDomain);
387403
}
388404

389405
private ProtectionDomain getProtectionDomain(String name) {
390406
final URL resource = getResource(classResourceName(name));
391407
if (resource == null) {
392408
return null;
393409
}
394-
CodeSource codeSource = null;
395-
Certificate[] certificates = useDummyCert ? new Certificate[0] : null;
410+
411+
CodeSigner[] signers = null;
412+
int i = name.lastIndexOf('.');
413+
414+
// TODO avoid explicit net.minecraft comparison. Removing this condition breaks forge atm.
415+
if (i != -1 && !name.startsWith("net.minecraft.")) {
416+
try {
417+
URLConnection urlConnection = resource.openConnection();
418+
if (urlConnection instanceof JarURLConnection) {
419+
final JarURLConnection jarURLConnection = (JarURLConnection)urlConnection;
420+
JarFile jarFile;
421+
jarFile = jarURLConnection.getJarFile();
422+
423+
if (jarFile != null && jarFile.getManifest() != null) {
424+
final Manifest manifest = jarFile.getManifest();
425+
final JarEntry entry = jarFile.getJarEntry(classResourceName(name));
426+
String pkgName = name.substring(0, i);
427+
428+
Package pkg = getPackage(pkgName);
429+
// getClassBytes(name);
430+
if (entry != null) {
431+
signers = entry.getCodeSigners();
432+
}
433+
if (pkg == null) {
434+
pkg = definePackage(pkgName, manifest, jarURLConnection.getJarFileURL());
435+
}
436+
}
437+
}
438+
} catch (IOException e) {
439+
e.printStackTrace();
440+
}
441+
}
442+
URL newResource = resource;
443+
444+
CodeSource codeSource;
445+
// ModLoader fix
396446
if (resource.getProtocol().equals("jar")) {
397447
String path = resource.getPath();
398448
if (path.startsWith("file:")) {
399449
path = path.substring("file:".length());
400-
int i = path.lastIndexOf('!');
401-
if (i != -1) {
402-
path = path.substring(0, i);
450+
int j = path.lastIndexOf('!');
451+
if (j != -1) {
452+
path = path.substring(0, j);
403453
}
404454
}
405455
if (overridenSource.containsKey(name)) {
406456
path = overridenSource.get(name);
407457
}
408458
try {
409-
URL newResource = new URL("file", "", path);
410-
codeSource = new CodeSource(newResource, certificates);
459+
newResource = new URL("file", "", path);
411460
} catch (MalformedURLException e) {
412-
codeSource = new CodeSource(resource, certificates);
413461
}
414-
} else {
415-
codeSource = new CodeSource(resource, certificates);
416462
}
463+
codeSource = new CodeSource(newResource, signers);
417464
return new ProtectionDomain(codeSource, null);
418465
}
419466

0 commit comments

Comments
 (0)