From be1646c8ce9897887009addf7ddc494bff5b62a4 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh Date: Fri, 2 Jul 2021 20:05:59 +0700 Subject: [PATCH] Now this can be installed as an IPA :trollface: --- .../java/net/kdt/pojavlaunch/PLaunchApp.java | 16 ++-- .../main/java/net/kdt/pojavlaunch/Tools.java | 4 +- .../prefs/LauncherPreferences.java | 2 +- Natives/AboutLauncherViewController.m | 4 +- Natives/AppDelegate.m | 9 +++ Natives/JavaLauncher.c | 80 ++++++++++++++----- Natives/LauncherViewController.m | 19 ++--- Natives/LoginViewController.m | 8 +- Natives/SurfaceViewController.m | 4 +- Natives/main.c | 7 +- 10 files changed, 103 insertions(+), 50 deletions(-) diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java index 8db85125..c4c80eeb 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java @@ -20,11 +20,11 @@ public class PLaunchApp { public static void main(String[] args) throws Throwable { // User might remove the minecraft folder, this can cause crashes, safety re-create it try { - File mcDir = new File("/var/mobile/Documents/minecraft"); + File mcDir = new File(Tools.DIR_GAME_NEW); mcDir.mkdirs(); new File(Tools.DIR_ACCOUNT_NEW).mkdirs(); - if (!new File(mcDir, "config_ver.txt").exists()) { - Tools.write(mcDir.getAbsolutePath() + "/config_ver.txt", "1.16.5"); + if (!new File(Tools.DIR_APP_DATA, "config_ver.txt").exists()) { + Tools.write(Tools.DIR_APP_DATA + "/config_ver.txt", "1.16.5"); Tools.write(mcDir.getAbsolutePath() + "/launcher_profiles.json", Tools.read(Tools.DIR_DATA + "/launcher_profiles.json")); @@ -35,12 +35,8 @@ public class PLaunchApp { e.printStackTrace(); } - if (args[0].startsWith("/Applications/")) { - System.out.println("We are on java now! Starting UI..."); - UIKit.launchUI(args); - } else { - return; - } + System.out.println("We are on java now! Starting UI..."); + UIKit.launchUI(args); } // Called from SurfaceViewController @@ -66,7 +62,7 @@ public class PLaunchApp { String mcver = "1.16.5"; try { - mcver = Tools.read(Tools.DIR_GAME_NEW + "/config_ver.txt"); + mcver = Tools.read(Tools.DIR_APP_DATA + "/config_ver.txt"); } catch (IOException e) { UIKit.updateProgressSafe(0, "config_ver.txt not found, defaulting to Minecraft 1.16.5"); } diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java index 85da8348..4ce1a644 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -53,10 +53,10 @@ public final class Tools public static final Gson GLOBAL_GSON = new GsonBuilder().setPrettyPrinting().create(); public static final String URL_HOME = "https://pojavlauncherteam.github.io/PojavLauncher"; - public static String DIR_DATA = "/Applications/PojavLauncher.app"; + public static String DIR_DATA = System.getenv("BUNDLE_PATH"); public static String CURRENT_ARCHITECTURE; - public static final String DIR_GAME_HOME = "/var/mobile/Documents"; + public static final String DIR_GAME_HOME = System.getenv("HOME") + "/Documents"; public static final String DIR_GAME_NEW = DIR_GAME_HOME + "/minecraft"; public static final String DIR_APP_DATA = DIR_GAME_HOME + "/.pojavlauncher"; diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java index c1508833..e0c4de5a 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java @@ -72,7 +72,7 @@ public class LauncherPreferences } */ - File argsFile = new File(Tools.DIR_GAME_NEW, "overrideargs.txt"); + File argsFile = new File(Tools.DIR_APP_DATA, "overrideargs.txt"); try { if (!argsFile.exists()) { argsFile.createNewFile(); diff --git a/Natives/AboutLauncherViewController.m b/Natives/AboutLauncherViewController.m index 220e6b8b..91d50a40 100644 --- a/Natives/AboutLauncherViewController.m +++ b/Natives/AboutLauncherViewController.m @@ -87,7 +87,9 @@ -(void)latestLogShare { - activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[@"latestlog.txt", [NSURL URLWithString:@"file:///var/mobile/Documents/.pojavlauncher/latestlog.old.txt"]] applicationActivities:nil]; + NSString *latestlogPath = [NSString stringWithFormat:@"file://%s/Documents/.pojavlauncher/latestlog.old.txt", getenv("HOME")]; + activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[@"latestlog.txt", [NSURL URLWithString:latestlogPath]] applicationActivities:nil]; + [self presentViewController:activityViewController animated:YES completion:nil]; } diff --git a/Natives/AppDelegate.m b/Natives/AppDelegate.m index a4041080..9773d76b 100644 --- a/Natives/AppDelegate.m +++ b/Natives/AppDelegate.m @@ -2,6 +2,15 @@ #import "LoginViewController.h" #import "SceneDelegate.h" +// FIXME: local build complains that "__isOSVersionAtLeast" is undefined! +int __isOSVersionAtLeast(int major, int minor, int patch) { + NSOperatingSystemVersion version; + version.majorVersion = major; + version.minorVersion = minor; + version.patchVersion = patch; + return [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]; +} + @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { diff --git a/Natives/JavaLauncher.c b/Natives/JavaLauncher.c index f9ebc97e..a2afa158 100644 --- a/Natives/JavaLauncher.c +++ b/Natives/JavaLauncher.c @@ -1,11 +1,14 @@ +#include #include -#include -#include #include +#include +#include #include -#include -#include #include +#include +#include +#include +#include #include #include @@ -19,9 +22,10 @@ #define FULL_VERSION "1.8.0-internal" #define DOT_VERSION "1.8" -static const char *java_libs_dir = "/Applications/PojavLauncher.app/libs"; -static const char *args_path = "/var/mobile/Documents/.pojavlauncher/overrideargs.txt"; -static const char *log_path = "/var/mobile/Documents/.pojavlauncher/latestlog.txt"; +static char java_libs_path[2048]; +static char args_path[2048]; +static char env_path[2048]; +static char log_path[2048]; extern char **environ; @@ -52,7 +56,7 @@ static int pfd[2]; static pthread_t logger; void init_loadCustomEnv() { - FILE *envFile = fopen("/var/mobile/Documents/.pojavlauncher/custom_env.txt", "r"); + FILE *envFile = fopen(env_path, "r"); debug("[Pre-init] Reading custom environment variables (custom_env.txt), opened=%d\n", envFile != NULL); @@ -98,14 +102,35 @@ void init_loadCustomJvmFlags() { int launchJVM(int argc, char *argv[]) { + if (!started) { + setenv("BUNDLE_PATH", dirname(argv[0]), 1); + + // Are we running on a jailbroken environment? + if (strncmp(argv[0], "/Applications", 13) == 0) { + setenv("HOME", "/var/mobile", 1); + } + } + + char* homeDir = getenv("HOME"); + sprintf((char*) args_path, "%s/Documents/.pojavlauncher/overrideargs.txt", homeDir); + sprintf((char*) env_path, "%s/Documents/.pojavlauncher/custom_env.txt", homeDir); + sprintf((char*) log_path, "%s/Documents/.pojavlauncher/latestlog.txt", homeDir); + sprintf((char*) java_libs_path, "%s/libs", getenv("BUNDLE_PATH")); + + mkdir(dirname(log_path), 755); + if (!started) { debug("[Pre-init] Staring logging STDIO as jrelog:V\n"); // Redirect stdio to latestlog.txt int ret; - char oldname[] = "/var/mobile/Documents/.pojavlauncher/latestlog.txt"; - char newname[] = "/var/mobile/Documents/.pojavlauncher/latestlog.old.txt"; - ret = rename(oldname, newname); + char newname[2048]; + sprintf(newname, "%s/Documents/.pojavlauncher/latestlog.old.txt", homeDir); + ret = rename(log_path, newname); FILE* logFile = fopen(log_path, "w"); + if (!logFile) { + debug("[Pre-init] Error: failed to open %s: %s", log_path, strerror(errno)); + assert(0 && "Failed to open latestlog.txt. Check oslog for more details."); + } int log_fd = fileno(logFile); dup2(log_fd, 1); dup2(log_fd, 2); @@ -126,8 +151,10 @@ int launchJVM(int argc, char *argv[]) { debug("[Pre-init] JAVA_HOME environment variable not set. Defaulting to %s\n", javaHome); } - mkdir("/var/mobile/Documents/.pojavlauncher/controlmap", S_IRWXU | S_IRWXG | S_IRWXO); - chdir("/var/mobile/Documents/minecraft"); + char controlPath[2048]; + sprintf(controlPath, "%s/Documents/.pojavlauncher/controlmap", homeDir); + mkdir(controlPath, S_IRWXU | S_IRWXG | S_IRWXO); + setenv("POJAV_PATH_CONTROL", controlPath, 1); char classpath[10000]; @@ -136,12 +163,12 @@ int launchJVM(int argc, char *argv[]) { // Generate classpath DIR *d; struct dirent *dir; - d = opendir(java_libs_dir); + d = opendir(java_libs_path); int cplen = 0; if (d) { // cplen += sprintf(classpath + cplen, "-Xbootclasspath/a:"); while ((dir = readdir(d)) != NULL) { - cplen += sprintf(classpath + cplen, "%s/%s:", java_libs_dir, dir->d_name); + cplen += sprintf(classpath + cplen, "%s/%s:", java_libs_path, dir->d_name); } closedir(d); } @@ -149,14 +176,23 @@ int launchJVM(int argc, char *argv[]) { // Check if JVM restarts if (!started) { - char *javaPath = calloc(1, 4096); - snprintf(javaPath, 4096, "%s/bin/java", javaHome); + char *frameworkPath = calloc(1, 2048); + char *javaPath = calloc(1, 2048); + char *userDir = calloc(1, 2048); + char *userHome = calloc(1, 2048); + snprintf(frameworkPath, 2048, "-Djava.library.path=%s/Frameworks", getenv("BUNDLE_PATH")); + snprintf(javaPath, 2048, "%s/bin/java", javaHome); + snprintf(userDir, 2048, "-Duser.dir=%s/Documents/minecraft", homeDir); + snprintf(userHome, 2048, "-Duser.home=%s/Documents", homeDir); + + chdir(userDir); + margv[margc++] = javaPath; margv[margc++] = "-XstartOnFirstThread"; margv[margc++] = "-Djava.system.class.loader=net.kdt.pojavlaunch.PojavClassLoader"; - margv[margc++] = "-Djava.library.path=/Applications/PojavLauncher.app/Frameworks"; - margv[margc++] = "-Duser.dir=/var/mobile/Documents/minecraft"; - margv[margc++] = "-Duser.home=/var/mobile/Documents"; + margv[margc++] = frameworkPath; + margv[margc++] = userDir; + margv[margc++] = userHome; margv[margc++] = "-Dorg.lwjgl.opengl.libname=libgl4es_114.dylib"; margv[margc++] = "-Dorg.lwjgl.system.allocator=system"; @@ -189,8 +225,8 @@ int launchJVM(int argc, char *argv[]) { } // Load java - char libjlipath8[4096]; // java 8 - char libjlipath16[4096]; // java 16+ (?) + char libjlipath8[2048]; // java 8 + char libjlipath16[2048]; // java 16+ (?) sprintf(libjlipath8, "%s/lib/jli/libjli.dylib", javaHome); sprintf(libjlipath16, "%s/lib/libjli.dylib", javaHome); void* libjli = dlopen(libjlipath8, RTLD_LAZY | RTLD_GLOBAL); diff --git a/Natives/LauncherViewController.m b/Natives/LauncherViewController.m index af5e6671..29345fdb 100644 --- a/Natives/LauncherViewController.m +++ b/Natives/LauncherViewController.m @@ -12,6 +12,8 @@ @implementation LauncherViewController +NSString* configver_path; + NSArray* versionList; UIPickerView* versionPickerView; UITextField* versionTextField; @@ -26,8 +28,6 @@ int versionSelectedAt = 0; [self setTitle:@"PojavLauncher"]; - FILE *configver_file = fopen("/var/mobile/Documents/minecraft/config_ver.txt", "rw"); - CGRect screenBounds = [[UIScreen mainScreen] bounds]; CGFloat screenScale = [[UIScreen mainScreen] scale]; @@ -45,9 +45,11 @@ int versionSelectedAt = 0; self.view.backgroundColor = [UIColor whiteColor]; } - char configver[1024]; - if (!fgets(configver, 1024, configver_file)) { - NSLog(@"Error: could not read config_ver.txt"); + NSError *error; + configver_path = [NSString stringWithFormat:@"%s/Documents/.pojavlauncher/config_ver.txt", getenv("HOME")]; + NSString *configver = [NSString stringWithContentsOfFile:configver_path encoding:NSUTF8StringEncoding error:&error]; + if (error) { + NSLog(@"Error: could not read config_ver.txt: %@", error.localizedDescription); } UILabel *versionTextView = [[UILabel alloc] initWithFrame:CGRectMake(4.0, 4.0, 0.0, 0.0)]; @@ -59,7 +61,7 @@ int versionSelectedAt = 0; versionTextField = [[UITextField alloc] initWithFrame:CGRectMake(versionTextView.bounds.size.width + 4.0, 4.0, width - versionTextView.bounds.size.width - 8.0, height - 58.0)]; [versionTextField addTarget:versionTextField action:@selector(resignFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit]; versionTextField.placeholder = @"Specify version..."; - versionTextField.text = [NSString stringWithUTF8String:configver]; + versionTextField.text = configver; versionTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; versionTextField.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; @@ -75,7 +77,6 @@ int versionSelectedAt = 0; versionTextField.inputAccessoryView = versionPickToolbar; versionTextField.inputView = versionPickerView; - fclose(configver_file); [scrollView addSubview:versionTextField]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleDone target:self action:@selector(enterPreferences)]; @@ -96,7 +97,7 @@ int versionSelectedAt = 0; - (void)fetchLocalVersionList:(NSMutableArray *)finalVersionList withPreviousIndex:(int)index { NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *versionPath = @"/var/mobile/Documents/minecraft/versions/"; + NSString *versionPath = [NSString stringWithFormat:@"%s/Documents/minecraft/versions", getenv("HOME")]; NSArray *localVersionList = [fileManager contentsOfDirectoryAtPath:versionPath error:Nil]; for (NSString *versionId in localVersionList) { NSString *localPath = [versionPath stringByAppendingString:versionId]; @@ -207,7 +208,7 @@ int versionSelectedAt = 0; #pragma mark - UIPickerView stuff - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { versionTextField.text = [self pickerView:pickerView titleForRow:row forComponent:component]; - [versionTextField.text writeToFile:@"/var/mobile/Documents/minecraft/config_ver.txt" atomically:NO encoding:NSUTF8StringEncoding error:nil]; + [versionTextField.text writeToFile:configver_path atomically:NO encoding:NSUTF8StringEncoding error:nil]; } - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView { diff --git a/Natives/LoginViewController.m b/Natives/LoginViewController.m index d5aaa707..239f714d 100644 --- a/Natives/LoginViewController.m +++ b/Natives/LoginViewController.m @@ -374,7 +374,9 @@ NSMutableArray *accountList; // List accounts DIR *d; struct dirent *dir; - d = opendir("/var/mobile/Documents/.pojavlauncher/accounts"); + char accPath[2048]; + sprintf(accPath, "%s/Documents/.pojavlauncher/accounts", getenv("HOME")); + d = opendir(accPath); if (d) { int i = 0; while ((dir = readdir(d)) != NULL) { @@ -426,8 +428,8 @@ NSMutableArray *accountList; - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { NSString *str = [accountList objectAtIndex:indexPath.row]; - char accPath[1024]; - sprintf(accPath, "/var/mobile/Documents/.pojavlauncher/accounts/%s.json", [str UTF8String]); + char accPath[2048]; + sprintf(accPath, "%s/Documents/.pojavlauncher/accounts/%s.json", getenv("HOME"), [str UTF8String]); remove(accPath); [accountList removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; diff --git a/Natives/SurfaceViewController.m b/Natives/SurfaceViewController.m index 5a0d199d..01553157 100644 --- a/Natives/SurfaceViewController.m +++ b/Natives/SurfaceViewController.m @@ -137,7 +137,9 @@ int notchOffset; // Temporary fallback controls BOOL cc_fallback = YES; - FILE *cc_file = fopen("/var/mobile/Documents/.pojavlauncher/controlmap/default.json", "r"); + char controlFilePath[2048]; + sprintf(controlFilePath, "%s/default.json", getenv("POJAV_PATH_CONTROL")); + FILE *cc_file = fopen(controlFilePath, "r"); // 100kb (might not safe) char cc_data[102400]; diff --git a/Natives/main.c b/Natives/main.c index 41cfd4de..f0445b19 100644 --- a/Natives/main.c +++ b/Natives/main.c @@ -1,5 +1,8 @@ -#include +#include #include +#include +#include +#include #include "JavaLauncher.h" int main(int argc, char * argv[]) { @@ -11,6 +14,8 @@ int main(int argc, char * argv[]) { return -1; } + launchJVM(argc, argv); + return 0; }