diff --git a/Natives/FileListViewController.h b/Natives/FileListViewController.h index 3b2972c3..61a2c8d8 100644 --- a/Natives/FileListViewController.h +++ b/Natives/FileListViewController.h @@ -3,6 +3,7 @@ @interface FileListViewController : UITableViewController @property NSString* listPath; +@property (nonatomic, copy) void (^whenDelete)(NSString* name); @property(nonatomic, copy) void (^whenItemSelected)(NSString* name); @end diff --git a/Natives/FileListViewController.m b/Natives/FileListViewController.m index a1bb967b..4fb074cd 100644 --- a/Natives/FileListViewController.m +++ b/Natives/FileListViewController.m @@ -69,7 +69,11 @@ NSString *str = [self.fileList objectAtIndex:indexPath.row]; NSFileManager *fm = [NSFileManager defaultManager]; - [fm removeItemAtPath:[NSString stringWithFormat:@"%@/%@.json", self.listPath, str] error:nil]; + NSString *path = [NSString stringWithFormat:@"%@/%@.json", self.listPath, str]; + if (self.whenDelete != nil) { + self.whenDelete(path); + } + [fm removeItemAtPath:path error:nil]; [self.fileList removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; } diff --git a/Natives/LauncherViewController.m b/Natives/LauncherViewController.m index 7363cfa6..df2c2787 100644 --- a/Natives/LauncherViewController.m +++ b/Natives/LauncherViewController.m @@ -96,6 +96,7 @@ int versionSelectedAt = 0; [scrollView addSubview:install_progress_bar]; install_button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; + install_button.enabled = NO; [install_button setTitle:@"Play" forState:UIControlStateNormal]; install_button.frame = CGRectMake(10.0, height - 54.0, 100.0, 50.0); [install_button addTarget:self action:@selector(launchMinecraft:) forControlEvents:UIControlEventTouchUpInside]; @@ -205,6 +206,7 @@ int versionSelectedAt = 0; [versionPickerView reloadAllComponents]; [versionPickerView selectRow:versionSelectedAt inComponent:0 animated:NO]; } + install_button.enabled = YES; }); }]; [getDataTask resume]; @@ -286,7 +288,8 @@ int versionSelectedAt = 0; } - (void)launchMinecraft:(UIButton *)sender { - [sender setEnabled:NO]; + sender.enabled = NO; + [self.navigationItem setHidesBackButton:YES animated:YES]; NSObject *object = [versionList objectAtIndex:[versionPickerView selectedRowInComponent:0]]; NSString *result; diff --git a/Natives/LoginViewController.m b/Natives/LoginViewController.m index e13f6416..1c147859 100644 --- a/Natives/LoginViewController.m +++ b/Natives/LoginViewController.m @@ -182,38 +182,58 @@ } - (void)loginAccountInput:(int)type data:(NSString *)data { - JNIEnv *env; - (*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, &env, NULL); + __block BOOL shouldDismiss = NO; + UIAlertController *alert; - jstring jdata = (*env)->NewStringUTF(env, data.UTF8String); - assert(jdata); - - jclass clazz = (*env)->FindClass(env, "net/kdt/pojavlaunch/uikit/AccountJNI"); - assert(clazz); - - jmethodID method = (*env)->GetStaticMethodID(env, clazz, "loginAccount", "(ILjava/lang/String;)Ljava/lang/String;"); - assert(method); - - jstring result = (*env)->CallStaticObjectMethod(env, clazz, method, type, jdata); - - if (![NSThread isMainThread]) { - (*runtimeJavaVMPtr)->DetachCurrentThread(runtimeJavaVMPtr); + if (type == TYPE_SELECTACC) { + NSError *error; + NSString *fileContent = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%s/accounts/%@.json", getenv("POJAV_HOME"), data] encoding:NSUTF8StringEncoding error:&error]; + shouldDismiss = [fileContent rangeOfString:@"\"accessToken\": \"0\","].location != NSNotFound; + } + + if (type != TYPE_OFFLINE && !shouldDismiss) { + alert = createLoadingAlert(@"Logging in"); + [self presentViewController:alert animated:YES completion:^{ + if (shouldDismiss) { + [alert dismissViewControllerAnimated:YES completion:^{ + LauncherViewController *vc = [[LauncherViewController alloc] init]; + [self.navigationController pushViewController:vc animated:YES]; + }]; + } + }]; } - if (result != NULL) { - const char *username = (*env)->GetStringUTFChars(env, result, 0); - setenv("POJAV_INTERNAL_SELECTED_ACCOUNT", username, 1); - (*env)->ReleaseStringUTFChars(env, result, username); - if ([NSThread isMainThread]) { - LauncherViewController *vc = [[LauncherViewController alloc] init]; - [self.navigationController pushViewController:vc animated:YES]; - } else { + dispatch_async(dispatch_get_global_queue(0, 0), ^{ + JNIEnv *env; + (*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, &env, NULL); + + jstring jdata = (*env)->NewStringUTF(env, data.UTF8String); + assert(jdata); + + jclass clazz = (*env)->FindClass(env, "net/kdt/pojavlaunch/uikit/AccountJNI"); + assert(clazz); + + jmethodID method = (*env)->GetStaticMethodID(env, clazz, "loginAccount", "(ILjava/lang/String;)Ljava/lang/String;"); + assert(method); + + jstring result = (*env)->CallStaticObjectMethod(env, clazz, method, type, jdata); + + if (result != NULL) { + const char *username = (*env)->GetStringUTFChars(env, result, 0); + setenv("POJAV_INTERNAL_SELECTED_ACCOUNT", username, 1); + (*env)->ReleaseStringUTFChars(env, result, username); dispatch_async(dispatch_get_main_queue(), ^{ + if (!shouldDismiss) { + shouldDismiss = YES; + [alert dismissViewControllerAnimated:YES completion:nil]; + } LauncherViewController *vc = [[LauncherViewController alloc] init]; [self.navigationController pushViewController:vc animated:YES]; }); } - } + + (*runtimeJavaVMPtr)->DetachCurrentThread(runtimeJavaVMPtr); + }); } - (void)loginUsername:(int)type { @@ -275,9 +295,7 @@ if ([urlString containsString:@"/auth/?code="] == YES) { NSArray *components = [urlString componentsSeparatedByString:@"/auth/?code="]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ - [self loginAccountInput:TYPE_MICROSOFT data:components[1]]; - }); + [self loginAccountInput:TYPE_MICROSOFT data:components[1]]; } else { NSArray *components = [urlString componentsSeparatedByString:@"/auth/?error="]; if ([components[1] hasPrefix:@"access_denied"] == NO) { @@ -336,6 +354,11 @@ - (void)loginAccount:(UIButton *)sender { FileListViewController *vc = [[FileListViewController alloc] init]; vc.listPath = [NSString stringWithFormat:@"%s/accounts", getenv("POJAV_HOME")]; +/* + vc.whenDelete = ^void(NSString* name) { + UIAlertController* alert = showLoadingDialog(vc, @"Logging out..."); + }; +*/ vc.whenItemSelected = ^void(NSString* name) { [self loginAccountInput:TYPE_SELECTACC data:name]; }; @@ -350,13 +373,15 @@ } - (void)loginMojangWithUsername:(NSString*)input_username password:(NSString*)input_password { + UIAlertController *alert = createLoadingAlert(@"Logging in"); + [self presentViewController:alert animated:YES completion:nil]; + NSString *input_uuid = [[NSUUID UUID] UUIDString]; NSURLSession *session = [NSURLSession sharedSession]; NSURL *url = [NSURL URLWithString:@"https://authserver.mojang.com/authenticate"]; NSMutableURLRequest *request = - [[NSMutableURLRequest alloc] initWithURL:[NSURL - URLWithString:@"https://authserver.mojang.com/authenticate"]]; + [[NSMutableURLRequest alloc] initWithURL:url]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; @@ -376,6 +401,7 @@ NSError *jsonError = nil; NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError]; + [alert dismissViewControllerAnimated:YES completion:^{ if (jsonError != nil) { NSLog(@"Error parsing JSON: %@", jsonError.localizedDescription); showDialog(self, @"Error parsing JSON", jsonError.localizedDescription); @@ -385,13 +411,6 @@ // NSLog(@"DBG: can't login demo account!"); showDialog(self, @"Error", @"Can't login a demo account!"); } else { -/* - NSString *out_accessToken = [jsonArray valueForKey:@"accessToken"]; - NSString *out_clientToken = [jsonArray valueForKey:@"clientToken"]; - NSString *out_profileID = [selectedProfile valueForKey:@"id"]; - NSString *out_username = [selectedProfile valueForKey:@"name"]; - NSLog(@"DBG: Login succeed: %@, %@, %@, %@", out_accessToken, out_clientToken, out_profileID, out_username); -*/ NSAssert(dataStr != nil, @"account data should not be null"); [self loginAccountInput:TYPE_MOJANG data:dataStr]; } @@ -401,6 +420,7 @@ // NSLog(@"DBG Error: %@: %@", err_title, err_msg); showDialog(self, err_title, err_msg); } + }]; }]; [postDataTask resume]; } diff --git a/Natives/ios_uikit_bridge.h b/Natives/ios_uikit_bridge.h index 86bfbecc..7d890b29 100644 --- a/Natives/ios_uikit_bridge.h +++ b/Natives/ios_uikit_bridge.h @@ -3,6 +3,7 @@ #include "jni.h" void showDialog(UIViewController *viewController, NSString* title, NSString* message); +UIAlertController* createLoadingAlert(NSString* message); jstring UIKit_accessClipboard(JNIEnv* env, jint action, jstring copySrc); void UIKit_updateProgress(float progress, const char* message); void UIKit_launchJarFile(const char* filepath); diff --git a/Natives/ios_uikit_bridge.m b/Natives/ios_uikit_bridge.m index 518f8307..642c8601 100644 --- a/Natives/ios_uikit_bridge.m +++ b/Natives/ios_uikit_bridge.m @@ -42,6 +42,17 @@ void showDialog(UIViewController *viewController, NSString* title, NSString* mes } } +UIAlertController* createLoadingAlert(NSString* message) { + UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(10, 5, 50, 50)]; + indicator.hidesWhenStopped = YES; + [indicator startAnimating]; + UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil + message:message + preferredStyle:UIAlertControllerStyleAlert]; + [alert.view addSubview:indicator]; + return alert; +} + JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_uikit_UIKit_showError(JNIEnv* env, jclass clazz, jstring title, jstring message, jboolean exitIfOk) { const char *title_c = (*env)->GetStringUTFChars(env, title, 0); const char *message_c = (*env)->GetStringUTFChars(env, message, 0);