diff --git a/Natives/JavaGUIViewController.m b/Natives/JavaGUIViewController.m index e94748e0..942f45a3 100644 --- a/Natives/JavaGUIViewController.m +++ b/Natives/JavaGUIViewController.m @@ -114,7 +114,7 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { rgbArray = calloc(4, (size_t) (savedWidth * savedHeight)); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - launchJVM(@".LaunchJAR", self.filepath, savedWidth * resolutionScale, savedHeight * resolutionScale); + launchJVM(nil, self.filepath, savedWidth * resolutionScale, savedHeight * resolutionScale, 8); }); } diff --git a/Natives/JavaLauncher.h b/Natives/JavaLauncher.h index 5482b689..c35cea50 100644 --- a/Natives/JavaLauncher.h +++ b/Natives/JavaLauncher.h @@ -17,4 +17,4 @@ typedef jint JLI_Launch_func(int argc, char ** argv, /* main argc, argc */ ); JLI_Launch_func *pJLI_Launch; -int launchJVM(NSString *username, NSString *selectedVersion, int width, int height); +int launchJVM(NSString *username, NSString *selectedVersion, int width, int height, int minVersion); diff --git a/Natives/JavaLauncher.m b/Natives/JavaLauncher.m index 54cad6df..8814d8b6 100644 --- a/Natives/JavaLauncher.m +++ b/Natives/JavaLauncher.m @@ -12,8 +12,9 @@ #include "log.h" #include "utils.h" -#include "JavaLauncher.h" +#import "ios_uikit_bridge.h" +#import "JavaLauncher.h" #import "LauncherPreferences.h" #define fm NSFileManager.defaultManager @@ -59,56 +60,70 @@ void init_loadCustomJvmFlags() { margv[margc] = (char *) [[@"-" stringByAppendingString:jvmarg] UTF8String]; } - NSLog(@"[Pre-init] Added custom JVM flag: %s", margv[margc]); + NSLog(@"[JavaLauncher] Added custom JVM flag: %s", margv[margc]); ++margc; } } -NSString* environmentFailsafes() { - NSString *javaHome_pre; - if (strncmp(getenv("BUNDLE_PATH"), "/Applications", 13) == 0) { - if ([fm fileExistsAtPath:JRE8_HOME_JB]) { - javaHome_pre = JRE8_HOME_JB; - } else if ([fm fileExistsAtPath:JRE16_HOME_JB]) { - regLog("[Pre-init] Java 8 wasn't found on your device. Install Java 8 for more compatibility and the mod installer."); - javaHome_pre = JRE16_HOME_JB; - } else if ([fm fileExistsAtPath:JRE17_HOME_JB]) { - regLog("[Pre-init] Java 8 wasn't found on your device. Install Java 8 for more compatibility and the mod installer."); - javaHome_pre = JRE17_HOME_JB; - } else { - regLog("[Pre-init] FATAL ERROR: Java wasn't found on your device, PojavLauncher cannot continue, aborting."); - abort(); +NSString* environmentFailsafes(int minVersion) { + NSString *javaHome = nil; + if (getenv("POJAV_DETECTEDJB")) { + BOOL foundJava8 = [fm fileExistsAtPath:JRE8_HOME_JB]; + if (!foundJava8) { + regLog("[JavaLauncher] Java 8 wasn't found on your device. Install Java 8 for more compatibility and the mod installer."); } - } else { - javaHome_pre = [NSString stringWithFormat:@"%s/jre", getenv("POJAV_HOME")]; + + if (foundJava8 && minVersion <= 8) { + javaHome = JRE8_HOME_JB; + } else if ([fm fileExistsAtPath:JRE16_HOME_JB] && minVersion <= 16) { + javaHome = JRE16_HOME_JB; + } else if ([fm fileExistsAtPath:JRE17_HOME_JB] && minVersion <= 17) { + javaHome = JRE17_HOME_JB; + } + } else if (minVersion <= 8) { + javaHome = [NSString stringWithFormat:@"%s/jre", getenv("POJAV_HOME")]; } - javaHome = javaHome_pre.UTF8String; - setPreference(@"java_home", javaHome_pre); - return javaHome_pre; + if (javaHome == nil) { + showDialog(viewController, NSLocalizedString(@"Error", nil), [NSString stringWithFormat:@"Minecraft %@ requires Java %d in order to run. Please install it first.", getPreference(@"selected_version"), minVersion]); + } + + return javaHome; } -int launchJVM(NSString *username, NSString *selectedVersion, int width, int height) { +int launchJVM(NSString *username, NSString *selectedVersion, int width, int height, int minVersion) { sprintf((char*) java_libs_path, "%s/libs", getenv("BUNDLE_PATH")); - regLog("[Pre-init] Beginning JVM launch\n"); + regLog("[JavaLauncher] Beginning JVM launch\n"); NSString *javaHome_pre = getPreference(@"java_home"); - javaHome = javaHome_pre.UTF8String; - if (javaHome_pre.length == 0) { - environmentFailsafes(); - regLog("[Pre-init] JAVA_HOME environment variable was not set. Defaulting to %s for future use.\n", javaHome); - } else { + + // We handle unset JAVA_HOME right there + if (username == nil || getSelectedJavaVersion() < minVersion) { + javaHome_pre = environmentFailsafes(minVersion); + NSLog(@"[JavaLauncher] Changed to Java %d for the request", minVersion); + } /* else if (javaHome_pre.length == 0) { + javaHome_pre = environmentFailsafes(minVersion); + setPreference(@"java_home", javaHome_pre); + NSLog(@"[JavaLauncher] JAVA_HOME environment variable was not set. Default to %@ for future use.\n", javaHome_pre); + } */ else { if (![NSFileManager.defaultManager fileExistsAtPath:javaHome_pre]) { - regLog("[Pre-Init] Failed to locate %s. Restoring default value for JAVA_HOME.", javaHome); - environmentFailsafes(); + javaHome_pre = environmentFailsafes(minVersion); + setPreference(@"java_home", javaHome_pre); + NSLog(@"[JavaLauncher] Failed to locate %@. Restored default value for JAVA_HOME.", javaHome_pre); } else { - regLog("[Pre-Init] Restored preference: JAVA_HOME is set to %s\n", javaHome); + NSLog(@"[JavaLauncher] Restored preference: JAVA_HOME is set to %@\n", javaHome_pre); } } + + if (javaHome_pre == nil) { + return 1; + } + + javaHome = javaHome_pre.UTF8String; setenv("JAVA_HOME", javaHome, 1); - if (strncmp(getenv("BUNDLE_PATH"), "/Applications", 13)) { + if (!getenv("POJAV_DETECTEDJB")) { char src[2048], dst[2048]; // Symlink frameworks -> dylibs on jailed environment @@ -200,9 +215,9 @@ int launchJVM(NSString *username, NSString *selectedVersion, int width, int heig renderer_pre = @"libgl4es_114.dylib"; setPreference(@"renderer", renderer_pre); renderer = [renderer_pre cStringUsingEncoding:NSUTF8StringEncoding]; - regLog("[Pre-init] RENDERER environment variable was not set. Defaulting to %s for future use.\n", renderer); + regLog("[JavaLauncher] RENDERER environment variable was not set. Defaulting to %s for future use.\n", renderer); } else { - regLog("[Pre-Init] Restored preference: RENDERER is set to %s\n", renderer); + regLog("[JavaLauncher] Restored preference: RENDERER is set to %s\n", renderer); } setenv("POJAV_RENDERER", renderer, 1); @@ -230,7 +245,7 @@ int launchJVM(NSString *username, NSString *selectedVersion, int width, int heig classpath[cplen-1] = '\0'; closedir(d); } - debugLog("[Pre-init] Classpath generated: %s", classpath); + debugLog("[JavaLauncher] Classpath generated: %s", classpath); // Check if JVM restarts char *frameworkPath, *javaPath, *jnaLibPath, *userDir, *userHome, *memMin, *memMax, *arcDNS; @@ -242,7 +257,7 @@ int launchJVM(NSString *username, NSString *selectedVersion, int width, int heig asprintf(&memMin, "-Xms%sM", allocmem); asprintf(&memMax, "-Xmx%sM", allocmem); asprintf(&arcDNS, "-javaagent:%s/arc_dns_injector.jar=23.95.137.176", java_libs_path); - NSLog(@"[Pre-init] Java executable path: %s", javaPath); + NSLog(@"[JavaLauncher] Java executable path: %s", javaPath); setenv("JAVA_EXT_EXECNAME", javaPath, 1); margv[margc++] = javaPath; @@ -315,7 +330,11 @@ int launchJVM(NSString *username, NSString *selectedVersion, int width, int heig margv[margc++] = classpath; margv[margc++] = "net.kdt.pojavlaunch.PLaunchApp"; - margv[margc++] = (char *)username.UTF8String; + if (username == nil) { + margv[margc++] = ".LaunchJAR"; + } else { + margv[margc++] = (char *)username.UTF8String; + } margv[margc++] = (char *)selectedVersion.UTF8String; margv[margc++] = (char *)[NSString stringWithFormat:@"%dx%d", width, height].UTF8String; diff --git a/Natives/LauncherPreferences.h b/Natives/LauncherPreferences.h index a9d2d15d..5675ab1e 100644 --- a/Natives/LauncherPreferences.h +++ b/Natives/LauncherPreferences.h @@ -7,5 +7,6 @@ void loadPreferences(); id getPreference(NSString* key); NSMutableDictionary* getDictionary(NSString *type); +int getSelectedJavaVersion(); void setDefaultValueForPref(NSMutableDictionary *dict, NSString* key, id value); void setPreference(NSString* key, id value); diff --git a/Natives/LauncherPreferences.m b/Natives/LauncherPreferences.m index cbd27000..b0ccb682 100644 --- a/Natives/LauncherPreferences.m +++ b/Natives/LauncherPreferences.m @@ -46,6 +46,21 @@ NSMutableDictionary *getDictionary(NSString *type) { return nil; } +int getSelectedJavaVersion() { + NSString *java = [getPreference(@"java_home") lastPathComponent]; + if (java.length == 0) { + return 0; + } else if ([java hasPrefix:@"java-"] && [java hasSuffix:@"-openjdk"]) { + return [java substringWithRange:NSMakeRange(5, java.length - 13)].intValue; + } else if ([java isEqualToString:@"jre"]) { + // TODO for jailbroken: jre8 and jre17 + return 8; + } else { + NSLog(@"FIXME: What is the Java version of %@?", java); + return 0; + } +} + void setDefaultValueForPref(NSMutableDictionary *dict, NSString* key, id value) { if (!dict[key]) { dict[key] = value; diff --git a/Natives/LauncherPreferencesViewController.m b/Natives/LauncherPreferencesViewController.m index 9b5dc58d..7dc40ed0 100644 --- a/Natives/LauncherPreferencesViewController.m +++ b/Natives/LauncherPreferencesViewController.m @@ -272,12 +272,10 @@ int tempIndex; JRE8_HOME_SB = [NSString stringWithFormat:@"%s/jre8", getenv("POJAV_HOME")]; if(getenv("POJAV_DETECTEDJB")) { - if ([getPreference(@"java_home") isEqualToString:JRE8_HOME_JB]) { - jhomeTextField.text = JRE8_NAME_JB; - } else if ([getPreference(@"java_home") isEqualToString:JRE16_HOME_JB]) { - jhomeTextField.text = JRE16_NAME_JB; - } else if ([getPreference(@"java_home") isEqualToString:JRE17_HOME_JB]) { - jhomeTextField.text = JRE17_NAME_JB; + switch (getSelectedJavaVersion()) { + case 8: jhomeTextField.text = JRE8_NAME_JB; break; + case 16: jhomeTextField.text = JRE16_NAME_JB; break; + case 17: jhomeTextField.text = JRE17_NAME_JB; break; } } else { jhomeTextField.text = JRE8_NAME_SB; diff --git a/Natives/LauncherViewController.m b/Natives/LauncherViewController.m index 73bacf8a..52df21ff 100644 --- a/Natives/LauncherViewController.m +++ b/Natives/LauncherViewController.m @@ -270,8 +270,9 @@ int versionSelectedAt = 0; - (void)enterModInstaller:(UIBarButtonItem*)sender { NSString *javaVer = getPreference(@"java_home"); - if(![javaVer containsString:(@"java-8-openjdk")] && ![javaVer containsString:(@"jre8")]) { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Cannot use the mod installer" message:@"In order to use the mod installer, you need to install Java 8 and specify it in the Preferences menu." preferredStyle:UIAlertControllerStyleActionSheet]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if(![fileManager fileExistsAtPath:JRE8_HOME_JB] && !getenv("POJAV_DETECTEDJB")) { + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Cannot use the mod installer" message:@"In order to use the mod installer, you need to install Java 8." preferredStyle:UIAlertControllerStyleActionSheet]; if (alert.popoverPresentationController != nil) { alert.popoverPresentationController.sourceView = self.view; alert.popoverPresentationController.sourceRect = CGRectMake(self.view.frame.size.width-10.0, 0, 10, 10); diff --git a/Natives/MinecraftDownloader.m b/Natives/MinecraftDownloader.m index 1cd2f1fb..f5929074 100644 --- a/Natives/MinecraftDownloader.m +++ b/Natives/MinecraftDownloader.m @@ -477,6 +477,7 @@ static AFURLSessionManager* manager; if (!success) return; isUseStackQueueCall = json[@"arguments"] != nil; + minJavaVersion = [json[@"javaVersion"][@"majorVersion"] intValue]; dispatch_async(dispatch_get_main_queue(), ^{ callback(nil, mainProgress, nil); diff --git a/Natives/SurfaceViewController.m b/Natives/SurfaceViewController.m index 679531d1..2e50857c 100644 --- a/Natives/SurfaceViewController.m +++ b/Natives/SurfaceViewController.m @@ -317,7 +317,7 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { // [self setPreferredFramesPerSecond:1000]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - launchJVM(BaseAuthenticator.current.authData[@"username"], getPreference(@"selected_version"), savedWidth * resolutionScale, savedHeight * resolutionScale); + launchJVM(BaseAuthenticator.current.authData[@"username"], getPreference(@"selected_version"), savedWidth * resolutionScale, savedHeight * resolutionScale, minJavaVersion); }); //callback_SurfaceViewController_launchMinecraft(savedWidth * resolutionScale, savedHeight * resolutionScale); } diff --git a/Natives/utils.h b/Natives/utils.h index adbe18aa..f4187280 100644 --- a/Natives/utils.h +++ b/Natives/utils.h @@ -36,32 +36,22 @@ #define SPECIALBTN_SCROLLUP -7 #define SPECIALBTN_SCROLLDOWN -8 -static float resolutionScale = 1.0; -BOOL isControlModifiable; - +int minJavaVersion; +JavaVM* runtimeJavaVMPtr; +JNIEnv* runtimeJNIEnvPtr; UIViewController *viewController; void* gbuffer; // OSMesa framebuffer - -JavaVM* runtimeJavaVMPtr; -JNIEnv* runtimeJNIEnvPtr; - -//JNIEnv* dalvikJNIEnvPtr_ANDROID; -//JNIEnv* dalvikJNIEnvPtr_JRE; - long showingWindow; - -bool isInputReady, isCursorEntered, isPrepareGrabPos, isUseStackQueueCall; - -jboolean isGrabbing; - int savedWidth, savedHeight; - +bool isInputReady, isCursorEntered, isPrepareGrabPos, isUseStackQueueCall; +jboolean isGrabbing; BOOL virtualMouseEnabled; +static float resolutionScale = 1.0; +BOOL isControlModifiable; // Init functions -void init_hookCFRunLoop(); void init_hookFunctions();