Forge 1.17 support

This commit is contained in:
ArtDev 2022-05-12 22:17:48 +03:00 committed by GitHub
commit 40aa51f78f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 99 additions and 41 deletions

View File

@ -1 +1 @@
1647645869468
1652206097040

View File

@ -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;
}
}
}
}

View File

@ -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) {

View File

@ -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<String, String> varArgMap = new ArrayMap<>();
varArgMap.put("classpath_separator", ":");
varArgMap.put("library_directory", strGameDir + "/libraries");
varArgMap.put("version_name", versionInfo.id);
List<String> minecraftArgs = new ArrayList<String>();
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<String> libDir = new ArrayList<String>();
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;

View File

@ -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

View File

@ -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);
}

View File

@ -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 {

View File

@ -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();
}

View File

@ -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]) {