diff --git a/app/build.gradle b/app/build.gradle index 457a499..f03f310 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "git.artdeell.skymodloader" minSdk 26 targetSdk 34 - versionCode 38 - versionName "1.5.5" + versionCode 41 + versionName "1.5.7" manifestPlaceholders = [ 'appAuthRedirectScheme': 'com.googleusercontent.apps.704988078112-46vk837uhg8n7qf3lb8dut52o7ugm7v4' ] diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp index a3d877e..ba3ecdb 100644 --- a/app/src/main/cpp/main.cpp +++ b/app/src/main/cpp/main.cpp @@ -270,7 +270,7 @@ Java_git_artdeell_skymodloader_LibrarySelectorListener_onModLibrary( // pthread_create(&pid, nullptr, UserThread, (void *)pUserLib); // Do NOT run in a separate thread. - // Initialize mods BEFORE sky initializes bootloader + // Initialize mods BEFORE sky initializes bootloader UserThread(pUserLib); } @@ -326,5 +326,5 @@ Java_git_artdeell_skymodloader_MainActivity_customServer(JNIEnv *env, jclass cla //?? ?? ?? 52 E2 03 1F AA ?? ?? ?? 94 ?? ?? ?? F9 ?? ?? ?? 52 uintptr_t ssl = (new CipherUtils())->CipherScan("\x00\x00\x00\x52\xE2\x03\x1F\xAA\x00\x00\x00\x94\x00\x00\x00\xF9\x00\x00\x00\x52", "???xxxxx???x???x???x"); LOGD("scanner %p", ssl); - (new CipherPatch())->set_Opcode("01008052")->set_Address(ssl, false)->Fire(); + // (new CipherPatch())->set_Opcode("01008052")->set_Address(ssl, false)->Fire(); } \ No newline at end of file diff --git a/app/src/main/java/com/tgc/sky/GameActivity.java b/app/src/main/java/com/tgc/sky/GameActivity.java index a946148..e8b20fa 100644 --- a/app/src/main/java/com/tgc/sky/GameActivity.java +++ b/app/src/main/java/com/tgc/sky/GameActivity.java @@ -11,6 +11,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.RectF; +import android.hardware.display.DisplayManager; import android.hardware.input.InputManager; import android.media.MediaPlayer; import android.net.Uri; @@ -192,6 +193,9 @@ public void attachBaseContext(Context context) { super.attachBaseContext(context); } + public native void onDisplayChangedNative(); + + private boolean isTextRenderingBrokenForDevice() { if (Build.VERSION.SDK_INT == 31 || Build.VERSION.SDK_INT == 32) { String[] strArr = {"OPD2102", "X21N2", "PFUM10", "TB128FU", "RMX3478", "RMX3471", "RMX3472", "2201116SC", "22101317C"}; @@ -280,7 +284,32 @@ public void onCreate(Bundle bundle) { return windowInsets; } }); + if (Build.VERSION.SDK_INT >= 30) { + //setupDisplayListener(); + } + } + + private void setupDisplayListener() { + final DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE); + displayManager.registerDisplayListener(new DisplayManager.DisplayListener() { // from class: com.tgc.sky.GameActivity.1 + @Override // android.hardware.display.DisplayManager.DisplayListener + public void onDisplayAdded(int i) { + } + + @Override // android.hardware.display.DisplayManager.DisplayListener + public void onDisplayRemoved(int i) { + } + + @Override // android.hardware.display.DisplayManager.DisplayListener + public void onDisplayChanged(int i) { + if (displayManager.getDisplay(i) != null) { + GameActivity.this.onDisplayChangedNative(); + } + } + }, null); + } + public String getDeviceBrand() { return Build.BRAND; } @@ -879,6 +908,10 @@ public float getDesiredMaxLum() { return getWindowManager().getDefaultDisplay().getHdrCapabilities().getDesiredMaxLuminance(); } + public float getDisplayRefreshRate() { + return getWindowManager().getDefaultDisplay().getRefreshRate(); + } + public int getPhysicalMemorySize() { ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); ((ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(memoryInfo); diff --git a/app/src/main/java/com/tgc/sky/SystemAccounts_android.java b/app/src/main/java/com/tgc/sky/SystemAccounts_android.java index ae64c53..b4a5c39 100644 --- a/app/src/main/java/com/tgc/sky/SystemAccounts_android.java +++ b/app/src/main/java/com/tgc/sky/SystemAccounts_android.java @@ -8,6 +8,8 @@ import git.artdeell.skymodloader.auth.Nintendo; import git.artdeell.skymodloader.auth.PSN; import git.artdeell.skymodloader.auth.Steam; +import git.artdeell.skymodloader.auth.Twitch; + import com.tgc.sky.accounts.SystemAccountClientInfo; import com.tgc.sky.accounts.SystemAccountClientRequestState; import com.tgc.sky.accounts.SystemAccountInterface; @@ -15,6 +17,7 @@ import com.tgc.sky.accounts.SystemAccountServerState; import com.tgc.sky.accounts.SystemAccountType; + public class SystemAccounts_android implements SystemAccountInterface.UpdateClientInfoCallback { private static volatile SystemAccounts_android sInstance; private GameActivity m_activity; @@ -26,6 +29,8 @@ public class SystemAccounts_android implements SystemAccountInterface.UpdateClie private Nintendo m_systemAccountNintendo; private PSN m_systemAccountPlaystation; private Steam m_systemAccountSteam; + private Twitch m_systemAccountTwitch; + public native void OnSystemAccount(SystemAccountClientInfo systemAccountClientInfo); @@ -47,6 +52,10 @@ public class SystemAccounts_android implements SystemAccountInterface.UpdateClie m_systemAccountPlaystation.Initialize(gameActivity, this); Steam steam = this.m_systemAccountSteam = new Steam(); steam.Initialize(gameActivity, this); + Twitch twitch = new Twitch(); + this.m_systemAccountTwitch = twitch; + twitch.Initialize(gameActivity, this); + sInstance = this; } @@ -77,7 +86,10 @@ public static SystemAccounts_android getInstance() { INTS[SystemAccountType.kSystemAccountType_Huawei.ordinal()] = 6; INTS[SystemAccountType.kSystemAccountType_PSN.ordinal()] = 7; INTS[SystemAccountType.kSystemAccountType_Steam.ordinal()] = 8; - INTS[SystemAccountType.kSystemAccountType_Local.ordinal()] = 9; + INTS[SystemAccountType.kSystemAccountType_Twitch.ordinal()] = 9; + INTS[SystemAccountType.kSystemAccountType_Local.ordinal()] = 10; + INTS[SystemAccountType.kSystemAccountType_AppleGameCenterVN.ordinal()] = 11; + INTS[SystemAccountType.kSystemAccountType_AppleVN.ordinal()] = 12; } } @@ -99,6 +111,8 @@ public SystemAccountInterface GetSystemAccount(SystemAccountType systemAccountTy return this.m_systemAccountPlaystation; case 8: return this.m_systemAccountSteam; + case 9: + return this.m_systemAccountTwitch; default: return null; } @@ -170,7 +184,13 @@ public static String systemAccountTypeToString(SystemAccountType systemAccountTy case 8: return "Steam"; case 9: + return "Twitch"; + case 10: return "Local"; + case 11: + return "AppleGameCenterVN"; + case 12: + return "AppleVN"; default: return null; } diff --git a/app/src/main/java/git/artdeell/skymodloader/auth/Twitch.java b/app/src/main/java/git/artdeell/skymodloader/auth/Twitch.java new file mode 100644 index 0000000..d43a4f2 --- /dev/null +++ b/app/src/main/java/git/artdeell/skymodloader/auth/Twitch.java @@ -0,0 +1,199 @@ +package git.artdeell.skymodloader.auth; + + +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.pm.ActivityInfo; +import android.os.StrictMode; +import android.view.WindowManager; +import android.webkit.CookieManager; +import android.webkit.ValueCallback; +import android.webkit.WebResourceRequest; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import com.tgc.sky.BuildConfig; + +import com.tgc.sky.GameActivity; +import com.tgc.sky.SystemIO_android; +import com.tgc.sky.accounts.SystemAccountClientInfo; +import com.tgc.sky.accounts.SystemAccountClientRequestState; +import com.tgc.sky.accounts.SystemAccountClientState; +import com.tgc.sky.accounts.SystemAccountInterface; +import com.tgc.sky.accounts.SystemAccountServerInfo; +import com.tgc.sky.accounts.SystemAccountType; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import org.json.JSONException; +import org.json.JSONObject; + + +public class Twitch implements SystemAccountInterface { + volatile boolean dialogCancelled; + String loginUrl; + private SystemAccountClientInfo m_accountClientInfo; + private SystemAccountServerInfo m_accountServerInfo; + private GameActivity m_activity; + private SystemAccountInterface.UpdateClientInfoCallback m_callback; + private int m_previousOrientation; + String redirectUrl; + + @Override // com.tgc.sky.accounts.SystemAccountInterface + public void Initialize(GameActivity gameActivity, SystemAccountInterface.UpdateClientInfoCallback updateClientInfoCallback) { + this.m_activity = gameActivity; + this.m_callback = updateClientInfoCallback; + SystemAccountClientInfo systemAccountClientInfo = new SystemAccountClientInfo(); + this.m_accountClientInfo = systemAccountClientInfo; + systemAccountClientInfo.accountType = SystemAccountType.kSystemAccountType_Twitch; + this.m_accountClientInfo.state = SystemAccountClientState.kSystemAccountClientState_SignedOut; + this.m_callback.UpdateClientInfo(this.m_accountClientInfo); + } + + @Override // com.tgc.sky.accounts.SystemAccountInterface + public SystemAccountClientInfo GetClientInfo() { + return this.m_accountClientInfo; + } + + public SystemAccountServerInfo GetServerInfo() { + return this.m_accountServerInfo; + } + + @Override // com.tgc.sky.accounts.SystemAccountInterface + public void SignIn() { + this.m_accountClientInfo.state = SystemAccountClientState.kSystemAccountClientState_SigningIn; + this.m_activity.runOnUiThread(new Runnable() { // from class: com.tgc.sky.accounts.Twitch.1 + @Override // java.lang.Runnable + public void run() { + Twitch.this.m_callback.UpdateClientInfo(Twitch.this.m_accountClientInfo); + Twitch.this.StartFlow(); + } + }); + } + + @Override // com.tgc.sky.accounts.SystemAccountInterface + public void SignOut() { + this.m_accountClientInfo.state = SystemAccountClientState.kSystemAccountClientState_SigningOut; + this.m_activity.runOnUiThread(new Runnable() { // from class: com.tgc.sky.accounts.Twitch.2 + @Override // java.lang.Runnable + public void run() { + Twitch.this.m_callback.UpdateClientInfo(Twitch.this.m_accountClientInfo); + CookieManager.getInstance().removeAllCookies(new ValueCallback() { // from class: com.tgc.sky.accounts.Twitch.2.1 + @Override // android.webkit.ValueCallback + public void onReceiveValue(Boolean bool) { + Twitch.this.m_accountClientInfo.state = SystemAccountClientState.kSystemAccountClientState_SignedOut; + Twitch.this.m_callback.UpdateClientInfo(Twitch.this.m_accountClientInfo); + } + }); + } + }); + } + + public void RefreshCredentials(SystemAccountClientRequestState systemAccountClientRequestState) { + SignIn(); + } + + /* JADX INFO: Access modifiers changed from: private */ + public void OnAccountSuccess(final String str, final String str2, final String str3, final String str4) { + this.m_activity.runOnUiThread(new Runnable() { // from class: com.tgc.sky.accounts.Twitch.3 + @Override // java.lang.Runnable + public void run() { + if (!str4.isEmpty() || str.isEmpty() || str3.isEmpty()) { + Twitch.this.m_accountClientInfo.state = SystemAccountClientState.kSystemAccountClientState_SignedOut; + } else { + Twitch.this.m_accountClientInfo.accountId = str; + Twitch.this.m_accountClientInfo.alias = str2; + Twitch.this.m_accountClientInfo.signature = str3; + Twitch.this.m_accountClientInfo.state = SystemAccountClientState.kSystemAccountClientState_SignedIn; + } + Twitch.this.m_callback.UpdateClientInfo(Twitch.this.m_accountClientInfo); + } + }); + } + + + public void StartFlow() { + //this.m_activity.portraitOnResume = true; + //this.m_previousOrientation = this.m_activity.getRequestedOrientation(); + //this.m_activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); + final Dialog dialog = new Dialog(this.m_activity); + WebView webView = new WebView(this.m_activity); + dialog.setContentView(webView); + webView.getSettings().setJavaScriptEnabled(true); + webView.getSettings().setUseWideViewPort(true); + String GetPushNotificationToken = SystemIO_android.getInstance().GetPushNotificationToken(); + if (GetPushNotificationToken == null) { + GetPushNotificationToken = ""; + } + try { + GetPushNotificationToken = URLEncoder.encode(GetPushNotificationToken, StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + this.loginUrl = String.format("https://%s/account/auth/oauth_signin?type=Twitch&token=cKN45n7UTSKHNoyzdugWNE:APA91bFg8MGDK26uj-RjRrRSANDGST4AqE29kh3ygCzN0IZWLgGis2K16aD9JoYXnaRBD2LgghA18Bc0ZG76AuWEzr3eAMTSRen8SsBPjtPftUVnuXECrjVfhd9z_WeDbx9MaHUO7GS9", BuildConfig.SKY_SERVER_HOSTNAME, GetPushNotificationToken); + this.redirectUrl = String.format("https://%s/account/auth/oauth_redirect", BuildConfig.SKY_SERVER_HOSTNAME); + webView.loadUrl(this.loginUrl); + webView.setWebViewClient(new WebViewClient() { // from class: com.tgc.sky.accounts.Twitch.4 + @Override // android.webkit.WebViewClient + public boolean shouldOverrideUrlLoading(WebView webView2, WebResourceRequest webResourceRequest) { + String uri = webResourceRequest.getUrl().toString(); + if (uri.startsWith(Twitch.this.redirectUrl)) { + StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build()); + try { + HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(uri).openConnection(); + BufferedInputStream bufferedInputStream = new BufferedInputStream(httpURLConnection.getInputStream()); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] bArr = new byte[1024]; + while (true) { + int read = bufferedInputStream.read(bArr, 0, 1024); + if (read == -1) { + break; + } + byteArrayOutputStream.write(bArr, 0, read); + } + byteArrayOutputStream.flush(); + String str = new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8); + httpURLConnection.disconnect(); + JSONObject jSONObject = new JSONObject(str); + Twitch.this.OnAccountSuccess(jSONObject.optString("id"), jSONObject.optString("alias"), jSONObject.optString("token"), ""); + } catch (MalformedURLException e2) { + e2.printStackTrace(); + Twitch.this.OnAccountSuccess("", "", "", "url error"); + } catch (IOException e3) { + e3.printStackTrace(); + Twitch.this.OnAccountSuccess("", "", "", "io error"); + } catch (JSONException e4) { + e4.printStackTrace(); + Twitch.this.OnAccountSuccess("", "", "", "json error"); + } + Twitch.this.dialogCancelled = false; + dialog.dismiss(); + return true; + } + return false; + } + }); + dialog.setTitle("Twitch Sign In"); + dialog.setCancelable(true); + dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { // from class: com.tgc.sky.accounts.Twitch.5 + @Override // android.content.DialogInterface.OnDismissListener + public void onDismiss(DialogInterface dialogInterface) { + if (Twitch.this.dialogCancelled) { + Twitch.this.OnAccountSuccess("", "", "", "cancel"); + } + //Twitch.this.m_activity.setRequestedOrientation(Twitch.this.m_previousOrientation); + //Twitch.this.m_activity.portraitOnResume = false; + } + }); + this.dialogCancelled = true; + + dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); + dialog.show(); + } +} \ No newline at end of file