[WIP] Mojang auth

This commit is contained in:
Duy Tran Khanh committed 2021-02-10 20:58:43 +07:00
1 parent c2e4e993ab
commit aef99100ef
15 files changed
+178 -129

No files matched your search

@@ -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();
@@ -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);
}
}
@@ -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);
@@ -8,37 +8,24 @@ import java.util.*;
import net.kdt.pojavlaunch.*;
import net.kdt.pojavlaunch.value.*;
public class InvalidateTokenTask extends AsyncTask<String, Void, Throwable> {
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();
}
}
@@ -6,17 +6,11 @@ import java.io.*;
import java.util.*;
import net.kdt.pojavlaunch.*;
public class LoginTask extends AsyncTask<String, Void, String[]>
{
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<String, Void, String[]>
}
@Override
protected String[] doInBackground(String[] args) {
protected String[] run(String username, String password) {
ArrayList<String> str = new ArrayList<String>();
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<String, Void, String[]>
}
return str.toArray(new String[0]);
}
@Override
protected void onPostExecute(String[] result) {
listener.onLoginDone(result);
super.onPostExecute(result);
}
}
@@ -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<String, Void, Throwable> {
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<String, Void, Throwable> {
return e;
}
}
@Override
public void onPostExecute(Throwable result) {
build.dismiss();
if (result == null) {
listener.onSuccess(null);
} else {
listener.onFailed(result);
}
}
}
@@ -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");
}
}
@@ -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
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -1,7 +1,7 @@
#import <UIKit/UIKit.h>
@interface LoginViewController : UIViewController
- (void)enterLauncher;
@end
@interface LoginListViewController : UITableViewController
+15
View File
@@ -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 () {
}
+1 -1
View File
@@ -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
+33
View File
@@ -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;
-3
View File
@@ -1,3 +0,0 @@
#pragma once
-4
View File
@@ -1,4 +0,0 @@
#include "jni.h"
#include "login_bridge.h"