Skip to content

Commit

Permalink
disable LWJGL manager when using Pojav (#271)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wyvest authored Jul 1, 2023
1 parent 669a994 commit d2d1dd7
Showing 1 changed file with 92 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class LwjglManagerImpl
extends URLClassLoader
implements LwjglManager {

private static final boolean isPojav = checkPojav();

private static final Object unsafeInstance;
private static final Method defineClassMethod;
private static final Map<String, String> remappingMap;
Expand All @@ -70,45 +72,45 @@ public class LwjglManagerImpl

public LwjglManagerImpl() throws ReflectiveOperationException {
super(new URL[]{jarFile}, LwjglManager.class.getClassLoader());
// Internal accessors
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.FontHelperImpl");
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.ScissorHelperImpl");
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.NanoVGHelperImpl");
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.AssetHelperImpl");
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.TinyFDImpl");
// Provider
classLoaderInclude.add(LWJGL_FUNCTION_PROVIDER);
// Lwjgl
Arrays.asList("nanovg", "actually3"
//#if MC<=11202
, "stb", "util.tinyfd", "system"
//#endif
).forEach(it -> classLoaderInclude.add("org.lwjgl." + it + "."));
classLoaderInclude.add("org.lwjgl.Version"); // won't work when remapped

ClassLoader classLoader =
this
;

//#if MC<=11202
// Keep the path somewhere for LWJGL2 after initializing LWJGL3
// (this is read in the Lwjgl2FunctionProvider class)
String libraryPath = System.getProperty("org.lwjgl.librarypath", "");
if (!libraryPath.isEmpty()) {
System.setProperty("oneconfig.lwjgl2.librarypath", libraryPath);
}
ClassLoader classLoader = isPojav ? getClass().getClassLoader() : this;
if (!isPojav) {
// Internal accessors
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.FontHelperImpl");
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.ScissorHelperImpl");
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.NanoVGHelperImpl");
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.AssetHelperImpl");
classLoaderInclude.add("cc.polyfrost.oneconfig.internal.renderer.TinyFDImpl");
// Provider
classLoaderInclude.add(LWJGL_FUNCTION_PROVIDER);
// Lwjgl
Arrays.asList("nanovg", "actually3"
//#if MC<=11202
, "stb", "util.tinyfd", "system"
//#endif
).forEach(it -> classLoaderInclude.add("org.lwjgl." + it + "."));
classLoaderInclude.add("org.lwjgl.Version"); // won't work when remapped

//#if MC<=11202
// Keep the path somewhere for LWJGL2 after initializing LWJGL3
// (this is read in the Lwjgl2FunctionProvider class)
String libraryPath = System.getProperty("org.lwjgl.librarypath", "");
if (!libraryPath.isEmpty()) {
System.setProperty("oneconfig.lwjgl2.librarypath", libraryPath);
}

// Setup LW3 config
Class<?> configClass = Class.forName("org.lwjgl.system.Configuration", true, classLoader);
Method setMethod = configClass.getMethod("set", Object.class);
// Setup LW3 config
Class<?> configClass = Class.forName("org.lwjgl.system.Configuration", true, classLoader);
Method setMethod = configClass.getMethod("set", Object.class);

Object extractDirField = configClass.getField("SHARED_LIBRARY_EXTRACT_DIRECTORY").get(null);
setMethod.invoke(extractDirField, new File("./OneConfig/temp").getAbsolutePath());
Object extractDirField = configClass.getField("SHARED_LIBRARY_EXTRACT_DIRECTORY").get(null);
setMethod.invoke(extractDirField, new File("./OneConfig/temp").getAbsolutePath());

// stop trying to Class.forName("true") ffs
Object debugStreamField = configClass.getField("DEBUG_STREAM").get(null);
setMethod.invoke(debugStreamField, System.err);
//#endif
// stop trying to Class.forName("true") ffs
Object debugStreamField = configClass.getField("DEBUG_STREAM").get(null);
setMethod.invoke(debugStreamField, System.err);
//#endif
}

// Initialize helper instances
try {
Expand All @@ -134,7 +136,7 @@ private boolean canBeSharedWithMc(String name) {

@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (!canBeSharedWithMc(name)) {
if (!canBeSharedWithMc(name) && !isPojav) {
synchronized (getClassLoadingLock(name)) {
Class<?> cls = findLoadedClass(name);
if (cls == null) {
Expand All @@ -151,6 +153,9 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (isPojav) {
return getParent().loadClass(name);
}
String remappedName = remappingMap.getOrDefault(
name.replace('.', '/'),
name
Expand Down Expand Up @@ -293,51 +298,58 @@ private void transform(ClassNode node) {
static {
registerAsParallelCapable();

remappingMap = new HashMap<>();
//#if MC<=11202
remappingMap.put("org/lwjgl/BufferUtils", "org/lwjgl/actually3/BufferUtils");
remappingMap.put("org/lwjgl/PointerBuffer", "org/lwjgl/actually3/PointerBuffer");
remappingMap.put("org/lwjgl/CLongBuffer", "org/lwjgl/actually3/CLongBuffer");
//#endif
if (!isPojav) {
remappingMap = new HashMap<>();
//#if MC<=11202
remappingMap.put("org/lwjgl/BufferUtils", "org/lwjgl/actually3/BufferUtils");
remappingMap.put("org/lwjgl/PointerBuffer", "org/lwjgl/actually3/PointerBuffer");
remappingMap.put("org/lwjgl/CLongBuffer", "org/lwjgl/actually3/CLongBuffer");
//#endif

Class<?> unsafeClass;
try {
unsafeClass = Class.forName("jdk.internal.misc.Unsafe");
} catch (Throwable throwable) {
Class<?> unsafeClass;
try {
unsafeClass = Class.forName("sun.misc.Unsafe");
} catch (Throwable throwable1) {
throw new RuntimeException("Could not find Unsafe class", throwable);
unsafeClass = Class.forName("jdk.internal.misc.Unsafe");
} catch (Throwable throwable) {
try {
unsafeClass = Class.forName("sun.misc.Unsafe");
} catch (Throwable throwable1) {
throw new RuntimeException("Could not find Unsafe class", throwable);
}
}
}

try {
try {
Deencapsulation.deencapsulate(Object.class);
Deencapsulation.deencapsulate(unsafeClass);
} catch (Throwable ignored) {
}
try {
Deencapsulation.deencapsulate(Object.class);
Deencapsulation.deencapsulate(unsafeClass);
} catch (Throwable ignored) {
}

Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
unsafeInstance = unsafeField.get(null);

defineClassMethod = unsafeClass.getDeclaredMethod(
"defineClass",
String.class,
byte[].class,
int.class,
int.class,
ClassLoader.class,
ProtectionDomain.class
);
defineClassMethod.setAccessible(true);
} catch (ReflectiveOperationException exception) {
throw new RuntimeException("Error while fetching Unsafe instance.", exception);
Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
unsafeInstance = unsafeField.get(null);

defineClassMethod = unsafeClass.getDeclaredMethod(
"defineClass",
String.class,
byte[].class,
int.class,
int.class,
ClassLoader.class,
ProtectionDomain.class
);
defineClassMethod.setAccessible(true);
} catch (ReflectiveOperationException exception) {
throw new RuntimeException("Error while fetching Unsafe instance.", exception);
}
} else {
remappingMap = null;
unsafeInstance = null;
defineClassMethod = null;
}
}

private static synchronized URL getJarFile() {
if (isPojav) return null;
final File tempJar = new File("./OneConfig/temp/" + JAR_NAME);
tempJar.mkdirs();
try {
Expand Down Expand Up @@ -372,6 +384,15 @@ private static synchronized URL getJarFile() {
}
}

private static boolean checkPojav() {
try {
Class.forName("org.lwjgl.glfw.CallbackBridge");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}

@Override
public NanoVGHelper getNanoVGHelper() {
return nanoVGHelper;
Expand Down

0 comments on commit d2d1dd7

Please sign in to comment.