diff --git a/app_pojavlauncher/src/main/assets/arc_dns_injector.jar b/app_pojavlauncher/src/main/assets/arc_dns_injector.jar index 3c9ddd6bf..fe94aba81 100644 Binary files a/app_pojavlauncher/src/main/assets/arc_dns_injector.jar and b/app_pojavlauncher/src/main/assets/arc_dns_injector.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/jsr305.jar b/app_pojavlauncher/src/main/assets/components/lwjgl3/jsr305.jar deleted file mode 100644 index 59222d9ca..000000000 Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/jsr305.jar and /dev/null differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar b/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar index 1d6427430..3c0e31737 100644 Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar and b/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/version b/app_pojavlauncher/src/main/assets/components/lwjgl3/version index 60ad0a61a..0f2502ae2 100644 --- a/app_pojavlauncher/src/main/assets/components/lwjgl3/version +++ b/app_pojavlauncher/src/main/assets/components/lwjgl3/version @@ -1 +1 @@ -1647645869468 \ No newline at end of file +1652206097040 \ No newline at end of file diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java index 88ecb7e4a..0f32bebb1 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java @@ -73,6 +73,12 @@ public class JMinecraftVersionList { public static class ArgRules { public String action; public String features; + public ArgOS os; + + public static class ArgOS { + public String name; + public String version; + } } } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java index 82749dae8..0a4f878a0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java @@ -58,16 +58,22 @@ import net.kdt.pojavlaunch.value.PerVersionConfig; import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile; +import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.io.FileUtils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Locale; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; public class PojavLoginActivity extends BaseActivity { private final Object mLockStoragePerm = new Object(); @@ -261,8 +267,7 @@ public class PojavLoginActivity extends BaseActivity { PojavProfile.setCurrentProfile(this, null); } - - private void unpackComponent(AssetManager am, String component) throws IOException { + private boolean unpackComponent(AssetManager am, String component) throws IOException { File versionFile = new File(Tools.DIR_GAME_HOME + "/" + component + "/version"); InputStream is = am.open("components/" + component + "/version"); if(!versionFile.exists()) { @@ -292,8 +297,10 @@ public class PojavLoginActivity extends BaseActivity { } } else { Log.i("UnpackPrep", component + ": Pack is up-to-date with the launcher, continuing..."); + return false; } } + return true; } public static void disableSplash(String dir) { mkdirs(dir + "/config"); @@ -340,7 +347,11 @@ public class PojavLoginActivity extends BaseActivity { AssetManager am = this.getAssets(); unpackComponent(am, "caciocavallo"); + + // Since the Java module system doesn't allow multiple JARs to declare the same module, + // we repack them to a single file here unpackComponent(am, "lwjgl3"); + if(!installRuntimeAutomatically(am,MultiRTUtils.getRuntimes().size() > 0)) { MultiRTConfigDialog.openRuntimeSelector(this, MultiRTConfigDialog.MULTIRT_PICK_RUNTIME_STARTUP); synchronized (mLockSelectJRE) { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index 08af84e28..c4313da66 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -130,7 +130,7 @@ public final class Tools { LauncherPreferences.PREF_CUSTOM_JAVA_ARGS = minecraftProfile.javaArgs; } PojavLoginActivity.disableSplash(gamedirPath); - String[] launchArgs = getMinecraftArgs(profile, versionInfo, gamedirPath); + String[] launchArgs = getMinecraftClientArgs(profile, versionInfo, gamedirPath); // Select the appropriate openGL version OldVersionsUtils.selectOpenGlVersion(versionInfo); @@ -165,6 +165,7 @@ public final class Tools { if (versionInfo.logging != null) { javaArgList.add("-Dlog4j.configurationFile=" + Tools.DIR_GAME_NEW + "/" + versionInfo.logging.client.file.id); } + javaArgList.addAll(Arrays.asList(getMinecraftJVMArgs(versionName, gamedirPath))); javaArgList.add("-cp"); javaArgList.add(getLWJGL3ClassPath() + ":" + launchClassPath); @@ -198,7 +199,47 @@ public final class Tools { javaArgList.add(cacioClasspath.toString()); } - public static String[] getMinecraftArgs(MinecraftAccount profile, JMinecraftVersionList.Version versionInfo, String strGameDir) { + public static String[] getMinecraftJVMArgs(String versionName, String strGameDir) { + JMinecraftVersionList.Version versionInfo = Tools.getVersionInfo(null, versionName, true); + // Parse Forge 1.17+ additional JVM Arguments + if (versionInfo.inheritsFrom == null || versionInfo.arguments == null || versionInfo.arguments.jvm == null) { + return new String[0]; + } + + Map varArgMap = new ArrayMap<>(); + varArgMap.put("classpath_separator", ":"); + varArgMap.put("library_directory", strGameDir + "/libraries"); + varArgMap.put("version_name", versionInfo.id); + + List minecraftArgs = new ArrayList(); + if (versionInfo.arguments != null) { + for (Object arg : versionInfo.arguments.jvm) { + if (arg instanceof String) { + minecraftArgs.add((String) arg); + } else { + /* + JMinecraftVersionList.Arguments.ArgValue argv = (JMinecraftVersionList.Arguments.ArgValue) arg; + if (argv.values != null) { + minecraftArgs.add(argv.values[0]); + } else { + + for (JMinecraftVersionList.Arguments.ArgValue.ArgRules rule : arg.rules) { + // rule.action = allow + // TODO implement this + } + + } + */ + } + } + } + + String[] argsFromJson = JSONUtils.insertJSONValueList(minecraftArgs.toArray(new String[0]), varArgMap); + // Tools.dialogOnUiThread(this, "Result args", Arrays.asList(argsFromJson).toString()); + return argsFromJson; + } + + public static String[] getMinecraftClientArgs(MinecraftAccount profile, JMinecraftVersionList.Version versionInfo, String strGameDir) { String username = profile.username; String versionName = versionInfo.id; if (versionInfo.inheritsFrom != null) { @@ -521,11 +562,19 @@ public final class Tools { Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); act.startActivity(browserIntent); } - + private static boolean checkRules(JMinecraftVersionList.Arguments.ArgValue.ArgRules[] rules) { + if(rules == null) return true; // always allow + for (JMinecraftVersionList.Arguments.ArgValue.ArgRules rule : rules) { + if (rule.action.equals("allow") && rule.os != null && rule.os.name.equals("osx")) { + return false; //disallow + } + } + return true; // allow if none match + } public static String[] generateLibClasspath(JMinecraftVersionList.Version info) { List libDir = new ArrayList(); - for (DependentLibrary libItem: info.libraries) { + if(!checkRules(libItem.rules)) continue; String[] libInfos = libItem.name.split(":"); libDir.add(Tools.DIR_HOME_LIBRARY + "/" + Tools.artifactToPath(libInfos[0], libInfos[1], libInfos[2])); } @@ -533,6 +582,10 @@ public final class Tools { } public static JMinecraftVersionList.Version getVersionInfo(BaseLauncherActivity bla, String versionName) { + return getVersionInfo(bla, versionName, false); + } + + public static JMinecraftVersionList.Version getVersionInfo(BaseLauncherActivity bla, String versionName, boolean skipInheriting) { try { JMinecraftVersionList.Version customVer = Tools.GLOBAL_GSON.fromJson(read(DIR_HOME_VERSION + "/" + versionName + "/" + versionName + ".json"), JMinecraftVersionList.Version.class); for (DependentLibrary lib : customVer.libraries) { @@ -540,7 +593,7 @@ public final class Tools { customVer.optifineLib = lib; } } - if (customVer.inheritsFrom == null || customVer.inheritsFrom.equals(customVer.id)) { + if (skipInheriting || customVer.inheritsFrom == null || customVer.inheritsFrom.equals(customVer.id)) { return customVer; } else { JMinecraftVersionList.Version inheritsVer = null; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/DependentLibrary.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/DependentLibrary.java index 812a57234..5df6b410e 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/DependentLibrary.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/DependentLibrary.java @@ -1,11 +1,13 @@ package net.kdt.pojavlaunch.value; import androidx.annotation.Keep; +import net.kdt.pojavlaunch.JMinecraftVersionList.Arguments.ArgValue.ArgRules; @Keep public class DependentLibrary { + public ArgRules[] rules; public String name; - public LibraryDownloads downloads; + public LibraryDownloads downloads; public String url; @Keep diff --git a/app_pojavlauncher/src/main/jni/input_bridge_v3.c b/app_pojavlauncher/src/main/jni/input_bridge_v3.c index 12069bffb..94ac62724 100644 --- a/app_pojavlauncher/src/main/jni/input_bridge_v3.c +++ b/app_pojavlauncher/src/main/jni/input_bridge_v3.c @@ -114,18 +114,6 @@ jboolean attachThread(bool isAndroid, JNIEnv** secondJNIEnvPtr) { return JNI_FALSE; } -void getJavaInputBridge(jclass* clazz, jmethodID* method) { -#ifdef DEBUG - LOGD("Debug: Initializing input bridge, method.isNull=%d, jnienv.isNull=%d\n", *method == NULL, runtimeJNIEnvPtr_ANDROID == NULL); -#endif - if (*method == NULL && runtimeJNIEnvPtr_ANDROID != NULL) { - *clazz = (*runtimeJNIEnvPtr_ANDROID)->FindClass(runtimeJNIEnvPtr_ANDROID, "org/lwjgl/glfw/CallbackBridge"); - assert(*clazz != NULL); - *method = (*runtimeJNIEnvPtr_ANDROID)->GetStaticMethodID(runtimeJNIEnvPtr_ANDROID, *clazz, "receiveCallback", "(IIIII)V"); - assert(*method != NULL); - } -} - void sendData(int type, int i1, int i2, int i3, int i4) { #ifdef DEBUG LOGD("Debug: Send data, jnienv.isNull=%d\n", runtimeJNIEnvPtr_ANDROID == NULL); @@ -134,6 +122,7 @@ void sendData(int type, int i1, int i2, int i3, int i4) { LOGE("BUG: Input is ready but thread is not attached yet."); return; } + if(inputBridgeClass_ANDROID == NULL) return; (*runtimeJNIEnvPtr_ANDROID)->CallStaticVoidMethod( runtimeJNIEnvPtr_ANDROID, inputBridgeClass_ANDROID, @@ -183,8 +172,6 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThread if (isUseStackQueueCall && isAndroid && result) { isPrepareGrabPos = true; } - getJavaInputBridge(&inputBridgeClass_ANDROID, &inputBridgeMethod_ANDROID); - return result; } @@ -392,3 +379,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetWindowAttrib( (jlong) showingWindow, attrib, value ); } + +JNIEXPORT void JNICALL +Java_org_lwjgl_glfw_CallbackBridge_setClass(JNIEnv *env, jclass clazz) { + inputBridgeMethod_ANDROID = (*env)->GetStaticMethodID(env, clazz, "receiveCallback", "(IIIII)V"); + inputBridgeClass_ANDROID = (*env)->NewGlobalRef(env, clazz); +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/build.gradle b/jre_lwjgl3glfw/build.gradle index 52c7dde56..85aaec96c 100644 --- a/jre_lwjgl3glfw/build.gradle +++ b/jre_lwjgl3glfw/build.gradle @@ -14,6 +14,12 @@ jar { // Auto update the version with a timestamp so the project jar gets updated by Pojav File versionFile = file("../app_pojavlauncher/src/main/assets/components/lwjgl3/version") versionFile.write(String.valueOf(new Date().getTime())) + from { + configurations.default.collect { + println(it.getName()) + it.isDirectory() ? it : zipTree(it) + } + } } java { diff --git a/jre_lwjgl3glfw/libs/lwjgl-core-3.2.3.jar b/jre_lwjgl3glfw/libs/lwjgl-core-3.2.3.jar deleted file mode 100644 index 756d423fd..000000000 Binary files a/jre_lwjgl3glfw/libs/lwjgl-core-3.2.3.jar and /dev/null differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-jemalloc.jar b/jre_lwjgl3glfw/libs/lwjgl-jemalloc.jar similarity index 91% rename from app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-jemalloc.jar rename to jre_lwjgl3glfw/libs/lwjgl-jemalloc.jar index 07029fc00..9b2bbcdb9 100644 Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-jemalloc.jar and b/jre_lwjgl3glfw/libs/lwjgl-jemalloc.jar differ diff --git a/jre_lwjgl3glfw/libs/lwjgl-openal-3.2.3.jar b/jre_lwjgl3glfw/libs/lwjgl-openal-3.2.3.jar deleted file mode 100644 index 9ccbc2e10..000000000 Binary files a/jre_lwjgl3glfw/libs/lwjgl-openal-3.2.3.jar and /dev/null differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-openal.jar b/jre_lwjgl3glfw/libs/lwjgl-openal.jar similarity index 92% rename from app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-openal.jar rename to jre_lwjgl3glfw/libs/lwjgl-openal.jar index 01cc3a3fa..b715ea92d 100644 Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-openal.jar and b/jre_lwjgl3glfw/libs/lwjgl-openal.jar differ diff --git a/jre_lwjgl3glfw/libs/lwjgl-opengl-3.2.3.jar b/jre_lwjgl3glfw/libs/lwjgl-opengl-3.2.3.jar deleted file mode 100644 index 6b0f45982..000000000 Binary files a/jre_lwjgl3glfw/libs/lwjgl-opengl-3.2.3.jar and /dev/null differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-opengl.jar b/jre_lwjgl3glfw/libs/lwjgl-opengl.jar similarity index 100% rename from app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-opengl.jar rename to jre_lwjgl3glfw/libs/lwjgl-opengl.jar diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-stb.jar b/jre_lwjgl3glfw/libs/lwjgl-stb.jar similarity index 95% rename from app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-stb.jar rename to jre_lwjgl3glfw/libs/lwjgl-stb.jar index d16fa38a9..00170036b 100644 Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-stb.jar and b/jre_lwjgl3glfw/libs/lwjgl-stb.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-tinyfd.jar b/jre_lwjgl3glfw/libs/lwjgl-tinyfd.jar similarity index 84% rename from app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-tinyfd.jar rename to jre_lwjgl3glfw/libs/lwjgl-tinyfd.jar index ac6d03635..60d2cb4ba 100644 Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-tinyfd.jar and b/jre_lwjgl3glfw/libs/lwjgl-tinyfd.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl.jar b/jre_lwjgl3glfw/libs/lwjgl.jar similarity index 96% rename from app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl.jar rename to jre_lwjgl3glfw/libs/lwjgl.jar index bb4d4693c..291a93dea 100644 Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl.jar and b/jre_lwjgl3glfw/libs/lwjgl.jar differ diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/CallbackBridge.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/CallbackBridge.java index 4cad05bf4..a72fee84b 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/CallbackBridge.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/CallbackBridge.java @@ -1,7 +1,5 @@ package org.lwjgl.glfw; -import java.io.*; import java.util.*; -import android.util.*; public class CallbackBridge { public static final int CLIPBOARD_COPY = 2000; @@ -51,9 +49,8 @@ public class CallbackBridge { GLFW.mGLFWIsGrabbing = grab; nativeSetGrabbing(grab, xset, yset); } - // Called from Android side - public static void receiveCallback(int type, int i1, int i2, int i3, int i4) { + public static void receiveCallback(int type, int i1, int i2, int i3, int i4) { /* if (INPUT_DEBUG_ENABLED) { System.out.println("LWJGL GLFW Callback received type=" + Integer.toString(type) + ", data=" + i1 + ", " + i2 + ", " + i3 + ", " + i4); @@ -67,17 +64,16 @@ public class CallbackBridge { PENDING_EVENT_LIST.add(new Integer[]{type, (int) i1, (int)i2, i3, i4}); } } // else System.out.println("Event input is not ready yet!"); - } + } public static void sendData(int type, String data) { nativeSendData(false, type, data); } - public static native void nativeSendData(boolean isAndroid, int type, String data); public static native boolean nativeSetInputReady(boolean ready); public static native String nativeClipboard(int action, String copy); public static native void nativeAttachThreadToOther(boolean isAndroid, boolean isUseStackQueueBool); - private static native void nativeSetGrabbing(boolean grab, int xset, int yset); + public static native void setClass(); } diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index 327a865fe..e751afe0b 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -12,7 +12,6 @@ import java.nio.*; import javax.annotation.*; import org.lwjgl.*; -import org.lwjgl.opengl.GL; import org.lwjgl.system.*; import static org.lwjgl.system.APIUtil.*; @@ -524,7 +523,7 @@ public class GLFW } catch (UnsatisfiedLinkError e) { e.printStackTrace(); } - + CallbackBridge.setClass(); mGLFWErrorCallback = GLFWErrorCallback.createPrint(); mGLFWKeyCodes = new ArrayMap<>(); @@ -1067,21 +1066,13 @@ public class GLFW mGLFWIsInputReady = true; mGLFWIsUseStackQueue = CallbackBridge.nativeSetInputReady(true); } - - if (!CallbackBridge.PENDING_EVENT_READY) { + if(!CallbackBridge.PENDING_EVENT_READY) { CallbackBridge.PENDING_EVENT_READY = true; - // nglfwSetInputReady(); } // Indirect event while (CallbackBridge.PENDING_EVENT_LIST.size() > 0) { Integer[] dataArr = CallbackBridge.PENDING_EVENT_LIST.remove(0); - - if (dataArr == null) { // It should not be null, but still should be catched - // System.out.println("GLFW: popped callback is null, skipping"); - continue; - } - for (Long ptr : mGLFWWindowMap.keySet()) { try { switch (dataArr[0]) {