From aef99100ef68e519c3ce620362c1e586fc97bf9e Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh Date: Wed, 10 Feb 2021 20:58:43 +0700 Subject: [PATCH] [WIP] Mojang auth --- .../java/net/kdt/pojavlaunch/PLaunchApp.java | 14 +--- ...javProfile.java.todo => PojavProfile.java} | 71 ++++++++++--------- .../main/java/net/kdt/pojavlaunch/Tools.java | 11 +-- ...ask.java.todo => InvalidateTokenTask.java} | 25 ++----- .../{LoginTask.java.todo => LoginTask.java} | 18 +---- ...enTask.java.todo => RefreshTokenTask.java} | 38 +--------- .../net/kdt/pojavlaunch/uikit/AccountJNI.java | 67 +++++++++++++++++ .../java/net/kdt/pojavlaunch/uikit/UIKit.java | 2 + Natives/CMakeLists.txt | 2 +- Natives/LoginViewController.h | 2 +- Natives/LoginViewController.m | 15 ++++ Natives/aminimake.sh | 2 +- Natives/ios_uikit_bridge.m | 33 +++++++++ Natives/login_bridge.h | 3 - Natives/login_bridge.m | 4 -- 15 files changed, 178 insertions(+), 129 deletions(-) rename JavaApp/src/main/java/net/kdt/pojavlaunch/{PojavProfile.java.todo => PojavProfile.java} (50%) rename JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/{InvalidateTokenTask.java.todo => InvalidateTokenTask.java} (58%) rename JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/{LoginTask.java.todo => LoginTask.java} (80%) rename JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/{RefreshTokenTask.java.todo => RefreshTokenTask.java} (60%) create mode 100644 JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/AccountJNI.java delete mode 100644 Natives/login_bridge.h delete mode 100644 Natives/login_bridge.m diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java index 0ecf0c6a..15699cba 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/PLaunchApp.java @@ -15,7 +15,6 @@ public class PLaunchApp { private static float currProgress, maxProgress; public static JMinecraftVersionList mVersionList; - public static volatile MinecraftAccount mAccount; public static volatile JMinecraftVersionList.Version mVersion; public static boolean mIsAssetsProcessing = false; @@ -24,8 +23,7 @@ public class PLaunchApp { try { File mcDir = new File("/var/mobile/Documents/minecraft"); mcDir.mkdirs(); - File pojavDir = new File("/var/mobile/Documents/.pojavlauncher/accounts"); - pojavDir.mkdirs(); + new File(DIR_ACCOUNT_NEW).mkdirs(); if (!new File(mcDir, "config_ver.txt").exists()) { Tools.write(mcDir.getAbsolutePath() + "/config_ver.txt", "1.16.5"); } @@ -51,9 +49,9 @@ public class PLaunchApp { System.out.println("Launching Minecraft " + mVersion.id); try { - Tools.launchMinecraft(mAccount, mVersion); + Tools.launchMinecraft(AccountJNI.CURRENT_ACCOUNT, mVersion); } catch (Throwable th) { - throw new RuntimeException(th); + Tools.showError(th); } } @@ -78,10 +76,6 @@ public class PLaunchApp { Thread.sleep(1000); } catch (InterruptedException e) {} - // dummy account - MinecraftAccount acc = new MinecraftAccount(); - acc.selectedVersion = mcver; - new File(Tools.DIR_HOME_VERSION + "/" + mcver).mkdirs(); JMinecraftVersionList.Version verInfo = null; @@ -175,8 +169,6 @@ public class PLaunchApp { e.printStackTrace(); } - mAccount = acc; - UIKit.launchMinecraftSurface(mVersion.arguments != null); }).start(); diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/PojavProfile.java.todo b/JavaApp/src/main/java/net/kdt/pojavlaunch/PojavProfile.java similarity index 50% rename from JavaApp/src/main/java/net/kdt/pojavlaunch/PojavProfile.java.todo rename to JavaApp/src/main/java/net/kdt/pojavlaunch/PojavProfile.java index a951e265..20969cb0 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/PojavProfile.java.todo +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/PojavProfile.java @@ -9,28 +9,36 @@ import net.kdt.pojavlaunch.value.MinecraftAccount; public class PojavProfile { - private static String PROFILE_PREF = "pojav_profile"; - private static String PROFILE_PREF_FILE = "file"; - private static String PROFILE_PREF_TEMP_CONTENT = "tempContent"; - - private static SharedPreferences getPrefs(Context ctx) { - return ctx.getSharedPreferences(PROFILE_PREF, Context.MODE_PRIVATE); - } - - public static MinecraftAccount getCurrentProfileContent(Context ctx) throws IOException, JsonSyntaxException { - MinecraftAccount build = MinecraftAccount.load(getCurrentProfileName(ctx)); - if (build == null) { - return getTempProfileContent(ctx); + private static final File currAccFile; + static { + try { + File currAccFile = new File(Tools.DIR_APP_DATA, "curr_account.txt"); + currAccFile.getParentFile().mkdir(); + // currAccFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); } - return build; - } + } + public static MinecraftAccount getCurrentProfileContent() throws IOException, JsonSyntaxException { + MinecraftAccount build = MinecraftAccount.load(getCurrentProfileName()); + if (build == null) { + return getTempProfileContent(); + } + return MinecraftAccount.load(getCurrentProfileName()); + } +/* public static MinecraftAccount getTempProfileContent(Context ctx) { return MinecraftAccount.parse(getPrefs(ctx).getString(PROFILE_PREF_TEMP_CONTENT, "")); } - - public static String getCurrentProfileName(Context ctx) { - String name = getPrefs(ctx).getString(PROFILE_PREF_FILE, ""); +*/ + public static String getCurrentProfileName() { + String name = ""; + try { + name = Tools.read(currAccFile.getAbsolutePath()); + } catch (IOException e) { + e.printStackTrace(); + } // A dirty fix if (!name.isEmpty() && name.startsWith(Tools.DIR_ACCOUNT_NEW) && name.endsWith(".json")) { name = name.substring(0, name.length() - 5).replace(Tools.DIR_ACCOUNT_NEW, "").replace(".json", ""); @@ -39,43 +47,36 @@ public class PojavProfile return name; } - public static boolean setCurrentProfile(Context ctx, Object obj) { - SharedPreferences.Editor pref = getPrefs(ctx).edit(); - + public static boolean setCurrentProfile(Object obj) { try { if (obj instanceof MinecraftAccount) { +/* try { MinecraftAccount.saveTempAccount((MinecraftAccount) obj); } catch (IOException e) { Tools.showError(ctx, e); } +*/ + throw new UnsupportedOperationException("Temp account is not supported yet"); } else if (obj instanceof String) { String acc = (String) obj; - pref.putString(PROFILE_PREF_FILE, acc); + Tools.write(currAccFile.getAbsolutePath(), acc); MinecraftAccount.clearTempAccount(); } else if (obj == null) { pref.putString(PROFILE_PREF_FILE, ""); } else { throw new IllegalArgumentException("Profile must be MinecraftAccount.class, String.class or null"); } - } finally { - return pref.commit(); + } catch (IOException e) { + e.printStackTrace(); } } - public static boolean isFileType(Context ctx) { - return new File(Tools.DIR_ACCOUNT_NEW + "/" + PojavProfile.getCurrentProfileName(ctx) + ".json").exists(); + public static boolean isFileType() { + return new File(Tools.DIR_ACCOUNT_NEW + "/" + getCurrentProfileName() + ".json").exists(); } - - public static void launch(Activity ctx, Object o) { - PojavProfile.setCurrentProfile(ctx, o); - - Intent intent = new Intent(ctx, PojavV2ActivityManager.getLauncherRemakeVer(ctx)); //MCLauncherActivity.class); - ctx.startActivity(intent); - } - - public static void updateTokens(final Activity ctx, final String name, RefreshListener listen) throws Exception { - new RefreshTokenTask(ctx, listen).execute(Tools.DIR_ACCOUNT_NEW + "/" + name + ".json"); + public static void updateTokens(final String name, RefreshListener listen) throws Exception { + new RefreshTokenTask(listen).run(name); } } diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java index ab0d5417..f1baa8a3 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -31,12 +31,12 @@ public final class Tools public static String DIR_DATA = "/Applications/PojavLauncher.app"; public static String CURRENT_ARCHITECTURE; - // New since 3.3.1 - public static String DIR_ACCOUNT_NEW; - public static String DIR_ACCOUNT_OLD; public static final String DIR_GAME_HOME = "/var/mobile/Documents"; public static final String DIR_GAME_NEW = DIR_GAME_HOME + "/minecraft"; + public static final String DIR_APP_DATA = DIR_GAME_HOME + "/.pojavlauncher"; + public static final String DIR_ACCOUNT_NEW = DIR_APP_DATA + "/accounts"; + // New since 3.0.0 public static String DIR_HOME_JRE = "/usr/lib/jvm/java-16-openjdk"; public static String DIRNAME_HOME_JRE = "lib"; @@ -94,7 +94,7 @@ public final class Tools System.out.println("It went past main(). Should not reach here!"); } catch (Throwable th) { - throw new RuntimeException(th); + showError(th); } }).start(); @@ -406,6 +406,9 @@ public final class Tools pw.flush(); System.err.println(sw.toString()); + + UIKit.showError(title, sw.toString(), exitIfOk); + /* Platform.getPlatform().runOnUIThread(() -> { WindowAlertController alertController = new WindowAlertController(title, sw.toString(), UIAlertControllerStyle.Alert); diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/InvalidateTokenTask.java.todo b/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/InvalidateTokenTask.java similarity index 58% rename from JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/InvalidateTokenTask.java.todo rename to JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/InvalidateTokenTask.java index dc266025..cf4eb632 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/InvalidateTokenTask.java.todo +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/InvalidateTokenTask.java @@ -8,37 +8,24 @@ import java.util.*; import net.kdt.pojavlaunch.*; import net.kdt.pojavlaunch.value.*; -public class InvalidateTokenTask extends AsyncTask { +public class InvalidateTokenTask { private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator(); //private Gson gson = new Gson(); private MinecraftAccount profilePath; - - private Context ctx; - private String path; - - public InvalidateTokenTask(Context ctx) { - this.ctx = ctx; - } + private String name; @Override - public Throwable doInBackground(String... args) { - path = args[0]; + public Throwable run(String name) { + this.name = name; try { - this.profilePath = MinecraftAccount.load(args[0]); + this.profilePath = MinecraftAccount.load(name); this.authenticator.invalidate(profilePath.accessToken, UUID.fromString(profilePath.isMicrosoft ? profilePath.profileId : profilePath.clientToken /* should be? */)); + new File(Tools.DIR_ACCOUNT_NEW, name + ".json").delete(); return null; } catch (Throwable e) { return e; } } - - @Override - public void onPostExecute(Throwable result) { - if (result != null) { - Tools.showError(ctx, result); - } - new File(path).delete(); - } } diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java.todo b/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java similarity index 80% rename from JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java.todo rename to JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java index 74e292cb..e088e44c 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java.todo +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java @@ -6,17 +6,11 @@ import java.io.*; import java.util.*; import net.kdt.pojavlaunch.*; -public class LoginTask extends AsyncTask -{ +public class LoginTask { private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator(); //private String TAG = "MojangAuth-login"; private LoginListener listener; - public LoginTask setLoginListener(LoginListener listener) { - this.listener = listener; - return this; - } - private UUID getRandomUUID() { return UUID.randomUUID(); } @@ -29,12 +23,12 @@ public class LoginTask extends AsyncTask } @Override - protected String[] doInBackground(String[] args) { + protected String[] run(String username, String password) { ArrayList str = new ArrayList(); str.add("ERROR"); try{ try{ - AuthenticateResponse response = authenticator.authenticate(args[0], args[1], getRandomUUID()); + AuthenticateResponse response = authenticator.authenticate(username, password, getRandomUUID()); if (response.selectedProfile == null) { str.add("Can't login a demo account!\n"); } else { @@ -59,10 +53,4 @@ public class LoginTask extends AsyncTask } return str.toArray(new String[0]); } - - @Override - protected void onPostExecute(String[] result) { - listener.onLoginDone(result); - super.onPostExecute(result); - } } diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java.todo b/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java similarity index 60% rename from JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java.todo rename to JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java index 20992897..523bc4c4 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java.todo +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java @@ -1,41 +1,19 @@ package net.kdt.pojavlaunch.authenticator.mojang; -import android.content.*; -import android.os.*; import com.google.gson.*; import java.util.*; import net.kdt.pojavlaunch.*; import net.kdt.pojavlaunch.authenticator.mojang.yggdrasil.*; -import android.app.*; import net.kdt.pojavlaunch.value.*; -public class RefreshTokenTask extends AsyncTask { +public class RefreshTokenTask { private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator(); - //private Gson gson = new Gson(); - private RefreshListener listener; private MinecraftAccount profilePath; - private Context ctx; - private ProgressDialog build; - - public RefreshTokenTask(Context ctx, RefreshListener listener) { - this.ctx = ctx; - this.listener = listener; - } - @Override - public void onPreExecute() { - build = new ProgressDialog(ctx); - build.setMessage(ctx.getString(R.string.global_waiting)); - build.setProgressStyle(ProgressDialog.STYLE_SPINNER); - build.setCancelable(false); - build.show(); - } - - @Override - public Throwable doInBackground(String... args) { + public Throwable run(String name) { try { - this.profilePath = MinecraftAccount.load(args[0]); + this.profilePath = MinecraftAccount.load(name); int responseCode = 400; responseCode = this.authenticator.validate(profilePath.accessToken).statusCode; if (responseCode >= 200 && responseCode < 300) { @@ -61,15 +39,5 @@ public class RefreshTokenTask extends AsyncTask { return e; } } - - @Override - public void onPostExecute(Throwable result) { - build.dismiss(); - if (result == null) { - listener.onSuccess(null); - } else { - listener.onFailed(result); - } - } } diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/AccountJNI.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/AccountJNI.java new file mode 100644 index 00000000..01b36cbe --- /dev/null +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/AccountJNI.java @@ -0,0 +1,67 @@ +package net.kdt.pojavlaunch.uikit; + +import net.kdt.pojavlaunch.PojavProfile; +import net.kdt.pojavlaunch.authenticator.mojang.*; +import net.kdt.pojavlaunch.value.MinecraftAccount; + +public class AccountJNI { + public static final int TYPE_SELECTACC = 0; + public static final int TYPE_MICROSOFT = 0; + public static final int TYPE_MOJANG = 0; + public static final int TYPE_OFFLINE = 0; + + public static volatile MinecraftAccount CURRENT_ACCOUNT; + + // Call back about account credentials for login + public static boolean loginAccount(int type, + String username, // Mojang or offline username + String password, // Mojang password or Microsoft token + ) { + try { + switch (type) { + case TYPE_SELECTACC: + PojavProfile.updateTokens(username); + CURRENT_ACCOUNT = MinecraftAccount.load(username); + return true; + + case TYPE_MICROSOFT: + // TODO + break; + + case TYPE_MOJANG: + String[] retArr = new LoginTask().run(username, password); + if (!retArr[0].equals("NORMAL")) { + StringBuilder full = new StringBuilder(); + for (int i = 1; i < retArr.length; i++) { + full.append(retArr[i] + "\n"); + } + UIKit.showError("Error", full.toString()); + return false; + } else { + CURRENT_ACCOUNT = new MinecraftAccount(); + CURRENT_ACCOUNT.accessToken = retArr[1]; + CURRENT_ACCOUNT.clientToken = retArr[2]; + CURRENT_ACCOUNT.profileId = retArr[3]; + CURRENT_ACCOUNT.username = retArr[4]; + CURRENT_ACCOUNT.save(); + return true; + } + break; + + case TYPE_OFFLINE: + CURRENT_ACCOUNT = new MinecraftAccount(); + CURRENT_ACCOUNT.username = username; + CURRENT_ACCOUNT.save(); + return true; + } + } catch (Throwable th) { + Tools.showError(th); + } + + return false; + } + + static { + // System.loadLibrary("pojavexec"); + } +} diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/UIKit.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/UIKit.java index ad4fc9f4..6b057082 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/UIKit.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/UIKit.java @@ -76,6 +76,8 @@ public class UIKit { public static native int launchUI(String[] uiArgs); // public static native void runOnUIThread(UIKitCallback callback); + public static native void showError(String title, String message, boolean exitIfOk); + private static native void updateMCGuiScale(int scale); // Update progress diff --git a/Natives/CMakeLists.txt b/Natives/CMakeLists.txt index 51c8c87c..58c94838 100644 --- a/Natives/CMakeLists.txt +++ b/Natives/CMakeLists.txt @@ -13,7 +13,7 @@ set_target_properties(PojavLauncher PROPERTIES MACOSX_FRAMEWORK_IDENTIFIER org.cmake.ExecutableTarget MACOSX_BUNDLE_INFO_PLIST "../Info.plist") -add_library(pojavexec SHARED log.m AppDelegate.m SceneDelegate.m UILauncher.m LauncherViewController.m LoginViewController.m SurfaceViewController.m egl_bridge_ios.m ios_uikit_bridge.m login_bridge.m egl_bridge.c input_bridge_v3.c utils.c) +add_library(pojavexec SHARED log.m AppDelegate.m SceneDelegate.m UILauncher.m LauncherViewController.m LoginViewController.m SurfaceViewController.m egl_bridge_ios.m ios_uikit_bridge.m egl_bridge.c input_bridge_v3.c utils.c) target_link_libraries(pojavexec "-Fresources/Frameworks" "-framework UIKit" diff --git a/Natives/LoginViewController.h b/Natives/LoginViewController.h index 2e475e9a..5ccc2117 100644 --- a/Natives/LoginViewController.h +++ b/Natives/LoginViewController.h @@ -1,7 +1,7 @@ #import @interface LoginViewController : UIViewController - +- (void)enterLauncher; @end @interface LoginListViewController : UITableViewController diff --git a/Natives/LoginViewController.m b/Natives/LoginViewController.m index 7b65ed98..36b48231 100644 --- a/Natives/LoginViewController.m +++ b/Natives/LoginViewController.m @@ -6,6 +6,21 @@ #include "utils.h" +void loginAccount(LoginViewController *controller, int type, char* username_c, char* password_c) { + JNIEnv *env; + (*runtimeJavaVMPtr)->GetEnv(runtimeJavaVMPtr, (void**) &env, JNI_VERSION_1_4); + + jstring username = (*env)->NewStringUTF(env, username_c); + jstring password = (*env)->NewStringUTF(env, password_c); + + jclass clazz = (*env)->FindClass(env, "net/kdt/pojavlaunch/uikit/AccountJNI"); + jmethodID method = (*env)->GetStaticMethodID(env, clazz, "loginAccount", "(ILjava/lang/String;Ljava/lang/String)Z"); + jboolean result = (*env)->CallStaticBooleanMethod(env, clazz, method, type, username, password); + if (result == JNI_TRUE) { + [controller enterLauncher]; + } +} + @interface LoginViewController () { } diff --git a/Natives/aminimake.sh b/Natives/aminimake.sh index 3ae1e2c6..ea1872e6 100644 --- a/Natives/aminimake.sh +++ b/Natives/aminimake.sh @@ -5,7 +5,7 @@ set -e CFLAGS="-fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -Wno-trigraphs -fpascal-strings -O3 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-return-type -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wunused-value -Wno-empty-body -Wno-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-bool-conversion -Wno-enum-conversion -Wno-float-conversion -Wno-non-literal-null-conversion -Wno-objc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof" -clang -Wl,-rpath,/Applications/PojavLauncher.app/Frameworks -fobjc-arc -x objective-c -Fresources/Frameworks -framework UIKit -framework MetalANGLE -framework CoreGraphics -Iresources/Frameworks/MetalANGLE.framework/Headers -dynamiclib -isysroot /var/mobile/theos/sdks/iPhoneOS13.4.sdk $CFLAGS -o libpojavexec.dylib log.m AppDelegate.m SceneDelegate.m UILauncher.m LauncherViewController.m LoginViewController.m SurfaceViewController.m egl_bridge_ios.m ios_uikit_bridge.m login_bridge.m egl_bridge.c input_bridge_v3.c utils.c -DGLES_TESTZ -DUSE_EGLZ +clang -Wl,-rpath,/Applications/PojavLauncher.app/Frameworks -fobjc-arc -x objective-c -Fresources/Frameworks -framework UIKit -framework MetalANGLE -framework CoreGraphics -Iresources/Frameworks/MetalANGLE.framework/Headers -dynamiclib -isysroot /var/mobile/theos/sdks/iPhoneOS13.4.sdk $CFLAGS -o libpojavexec.dylib log.m AppDelegate.m SceneDelegate.m UILauncher.m LauncherViewController.m LoginViewController.m SurfaceViewController.m egl_bridge_ios.m ios_uikit_bridge.m egl_bridge.c input_bridge_v3.c utils.c -DGLES_TESTZ -DUSE_EGLZ ldid -S../entitlements.xml libpojavexec.dylib diff --git a/Natives/ios_uikit_bridge.m b/Natives/ios_uikit_bridge.m index 55b326eb..ca211450 100644 --- a/Natives/ios_uikit_bridge.m +++ b/Natives/ios_uikit_bridge.m @@ -10,6 +10,39 @@ jboolean skipDownloadAssets; +JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_uikit_UIKit_showError(JNIEnv* env_unused, jclass clazz, jstring title, jstring message, jboolean exitIfOk) { +dispatch_async(dispatch_get_main_queue(), ^{ + JNIEnv *env; + (*runtimeJavaVMPtr)->GetEnv(runtimeJavaVMPtr, (void**) &env, JNI_VERSION_1_4); + const char* title_c = (*env)->GetStringUTFChars(env, title, 0); + const char* message_c = (*env)->GetStringUTFChars(env, message, 0); + + UIViewController *viewController = nil; + if (@available(iOS 13.0, *)) { + viewController = UIApplication.sharedApplication.windows.lastObject.rootViewController; + } else { + viewController = [[(AppDelegate*) [[UIApplication sharedApplication]delegate] window] rootViewController]; + } + + UIAlertController* alert = [UIAlertController alertControllerWithTitle:@(title_c) + message:@(message_c) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + if (exitIfOk == JNI_TRUE) { + exit(-1); + } + }]; + + [alert addAction:defaultAction]; + [viewController presentViewController:alert animated:YES completion:nil]; + + (*env)->ReleaseStringUTFChars(env, title, title_c); + (*env)->ReleaseStringUTFChars(env, message, message_c); +}); +} + jboolean UIKit_updateProgress(float progress, const char* message) { dispatch_async(dispatch_get_main_queue(), ^{ install_progress_bar.progress = progress; diff --git a/Natives/login_bridge.h b/Natives/login_bridge.h deleted file mode 100644 index 45dcbb04..00000000 --- a/Natives/login_bridge.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - - diff --git a/Natives/login_bridge.m b/Natives/login_bridge.m deleted file mode 100644 index d0231feb..00000000 --- a/Natives/login_bridge.m +++ /dev/null @@ -1,4 +0,0 @@ -#include "jni.h" -#include "login_bridge.h" - -