forked from geode-sdk/android-launcher
move gd functions to a separate file
This commit is contained in:
5 files changed
+110
-103
No files matched your search
@@ -24,6 +24,7 @@ import com.customRobTop.JniToCpp
|
|||||||
import com.geode.launcher.utils.Constants
|
import com.geode.launcher.utils.Constants
|
||||||
import com.geode.launcher.utils.ConstrainedFrameLayout
|
import com.geode.launcher.utils.ConstrainedFrameLayout
|
||||||
import com.geode.launcher.utils.DownloadUtils
|
import com.geode.launcher.utils.DownloadUtils
|
||||||
|
import com.geode.launcher.utils.GamePackageUtils
|
||||||
import com.geode.launcher.utils.GeodeUtils
|
import com.geode.launcher.utils.GeodeUtils
|
||||||
import com.geode.launcher.utils.LaunchUtils
|
import com.geode.launcher.utils.LaunchUtils
|
||||||
import com.geode.launcher.utils.PreferenceUtils
|
import com.geode.launcher.utils.PreferenceUtils
|
||||||
@@ -65,7 +66,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
// return back to main if Geometry Dash isn't found
|
// return back to main if Geometry Dash isn't found
|
||||||
if (!LaunchUtils.isGeometryDashInstalled(packageManager)) {
|
if (!GamePackageUtils.isGameInstalled(packageManager)) {
|
||||||
returnToMain()
|
returnToMain()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -77,7 +78,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
|
|
||||||
// generates helpful information for use in debugging library load failures
|
// generates helpful information for use in debugging library load failures
|
||||||
val gdPackageInfo = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
val gdPackageInfo = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
||||||
val abiMismatch = LaunchUtils.detectAbiMismatch(this, gdPackageInfo, e)
|
val abiMismatch = GamePackageUtils.detectAbiMismatch(this, gdPackageInfo, e)
|
||||||
|
|
||||||
val is64bit = LaunchUtils.is64bit
|
val is64bit = LaunchUtils.is64bit
|
||||||
val errorMessage = when {
|
val errorMessage = when {
|
||||||
@@ -163,7 +164,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
|
|
||||||
private fun setupRedirection(packageInfo: PackageInfo) {
|
private fun setupRedirection(packageInfo: PackageInfo) {
|
||||||
try {
|
try {
|
||||||
LaunchUtils.addAssetsFromPackage(assets, packageInfo)
|
GamePackageUtils.addAssetsFromPackage(assets, packageInfo)
|
||||||
} catch (e: NoSuchMethodException) {
|
} catch (e: NoSuchMethodException) {
|
||||||
Log.e("GeodeLauncher", "Failed to add asset redirection", e)
|
Log.e("GeodeLauncher", "Failed to add asset redirection", e)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import com.geode.launcher.utils.Constants
|
|||||||
import com.geode.launcher.utils.LaunchUtils
|
import com.geode.launcher.utils.LaunchUtils
|
||||||
import com.geode.launcher.utils.PreferenceUtils
|
import com.geode.launcher.utils.PreferenceUtils
|
||||||
import com.geode.launcher.updater.ReleaseManager
|
import com.geode.launcher.updater.ReleaseManager
|
||||||
|
import com.geode.launcher.utils.GamePackageUtils
|
||||||
import com.geode.launcher.utils.GeodeUtils
|
import com.geode.launcher.utils.GeodeUtils
|
||||||
import com.geode.launcher.utils.useCountdownTimer
|
import com.geode.launcher.utils.useCountdownTimer
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -78,7 +79,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
val gdInstalled = LaunchUtils.isGeometryDashInstalled(packageManager)
|
val gdInstalled = GamePackageUtils.isGameInstalled(packageManager)
|
||||||
val geodeInstalled = LaunchUtils.isGeodeInstalled(this)
|
val geodeInstalled = LaunchUtils.isGeodeInstalled(this)
|
||||||
|
|
||||||
val returnMessage = intent.extras?.getString(LaunchUtils.LAUNCHER_KEY_RETURN_MESSAGE)
|
val returnMessage = intent.extras?.getString(LaunchUtils.LAUNCHER_KEY_RETURN_MESSAGE)
|
||||||
@@ -232,8 +233,8 @@ fun UpdateWarning(inSafeMode: Boolean = false, onDismiss: () -> Unit) {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val packageManager = context.packageManager
|
val packageManager = context.packageManager
|
||||||
|
|
||||||
val gdVersionCode = remember { LaunchUtils.getGeometryDashVersionCode(packageManager) }
|
val gdVersionCode = remember { GamePackageUtils.getGameVersionCode(packageManager) }
|
||||||
val gdVersionString = remember { LaunchUtils.getGeometryDashVersionString(packageManager) }
|
val gdVersionString = remember { GamePackageUtils.getGameVersionString(packageManager) }
|
||||||
|
|
||||||
var lastDismissedVersion by PreferenceUtils.useLongPreference(
|
var lastDismissedVersion by PreferenceUtils.useLongPreference(
|
||||||
preferenceKey = PreferenceUtils.Key.DISMISSED_GJ_UPDATE
|
preferenceKey = PreferenceUtils.Key.DISMISSED_GJ_UPDATE
|
||||||
@@ -562,8 +563,7 @@ fun ErrorInfoActions(extraDetails: String?, modifier: Modifier = Modifier) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FilledTonalButton(onClick = {
|
FilledTonalButton(onClick = {
|
||||||
val message = extraDetails
|
clipboardManager.setText(AnnotatedString(extraDetails))
|
||||||
clipboardManager.setText(AnnotatedString(message))
|
|
||||||
}) {
|
}) {
|
||||||
Icon(
|
Icon(
|
||||||
painterResource(R.drawable.icon_content_copy),
|
painterResource(R.drawable.icon_content_copy),
|
||||||
@@ -864,7 +864,7 @@ fun MainScreen(
|
|||||||
when {
|
when {
|
||||||
gdInstalled && geodeInstalled -> {
|
gdInstalled && geodeInstalled -> {
|
||||||
val gdVersion = remember {
|
val gdVersion = remember {
|
||||||
LaunchUtils.getGeometryDashVersionCode(context.packageManager)
|
GamePackageUtils.getGameVersionCode(context.packageManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gdVersion < Constants.SUPPORTED_VERSION_CODE) {
|
if (gdVersion < Constants.SUPPORTED_VERSION_CODE) {
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package com.geode.launcher.utils
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
|
import android.content.pm.PackageInfo
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.res.AssetManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
object GamePackageUtils {
|
||||||
|
fun isGameInstalled(packageManager: PackageManager): Boolean {
|
||||||
|
return try {
|
||||||
|
packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
||||||
|
true
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getGameVersionCode(packageManager: PackageManager): Long {
|
||||||
|
val game = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
||||||
|
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
game.longVersionCode
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
game.versionCode.toLong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getGameVersionString(packageManager: PackageManager): String {
|
||||||
|
val game = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
||||||
|
return game.versionName
|
||||||
|
}
|
||||||
|
|
||||||
|
fun detectAbiMismatch(context: Context, packageInfo: PackageInfo, loadException: Error): Boolean {
|
||||||
|
val abi = LaunchUtils.applicationArchitecture
|
||||||
|
val isExtracted =
|
||||||
|
packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS == ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS
|
||||||
|
val isSplit = (packageInfo.applicationInfo.splitSourceDirs?.size ?: 0) > 1
|
||||||
|
|
||||||
|
val metadata =
|
||||||
|
"Geometry Dash metadata:\nSplit sources: $isSplit\nExtracted libraries: $isExtracted\nLauncher architecture: $abi"
|
||||||
|
Log.i("GeodeLauncher", metadata)
|
||||||
|
|
||||||
|
// easiest check! these messages are hardcoded in bionic/linker/linker_phdr.cpp
|
||||||
|
if (loadException.message?.contains("32-bit instead of 64-bit") == true) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadException.message?.contains("64-bit instead of 32-bit") == true) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine if it can find gd libraries for the opposite architecture
|
||||||
|
val gdBinaryName = "lib${Constants.COCOS_LIB_NAME}.so"
|
||||||
|
val oppositeArchitecture = if (abi == "arm64-v8a") "armeabi-v7a" else "arm64-v8a"
|
||||||
|
|
||||||
|
// detect issues using native library directory (only works on extracted libraries)
|
||||||
|
val nativeLibraryDir = packageInfo.applicationInfo.nativeLibraryDir
|
||||||
|
|
||||||
|
if (nativeLibraryDir.contains(oppositeArchitecture)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// android has some odd behavior where 32bit libraries get installed to the arm directory instead of armeabi-v7a
|
||||||
|
// detect it, ig
|
||||||
|
if (oppositeArchitecture == "armeabi-v7a" && nativeLibraryDir.contains("/lib/arm/")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isExtracted) {
|
||||||
|
try {
|
||||||
|
context.assets.openNonAssetFd("lib/$oppositeArchitecture/$gdBinaryName")
|
||||||
|
return true
|
||||||
|
} catch (_: Exception) {
|
||||||
|
// this is good, actually!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("DiscouragedPrivateApi")
|
||||||
|
fun addAssetsFromPackage(assetManager: AssetManager, packageInfo: PackageInfo) {
|
||||||
|
// this method is officially marked as deprecated but it is the only method we are allowed to reflect
|
||||||
|
// (the source recommends replacing with AssetManager.setApkAssets(ApkAssets[], boolean) lol)
|
||||||
|
val clazz = assetManager.javaClass
|
||||||
|
val aspMethod = clazz.getDeclaredMethod("addAssetPath", String::class.java)
|
||||||
|
|
||||||
|
aspMethod.invoke(assetManager, packageInfo.applicationInfo.sourceDir)
|
||||||
|
packageInfo.applicationInfo.splitSourceDirs?.forEach {
|
||||||
|
aspMethod.invoke(assetManager, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -359,8 +359,8 @@ object GeodeUtils {
|
|||||||
fun getGameVersion(): String {
|
fun getGameVersion(): String {
|
||||||
// these versions should be aligned to windows releases, not what android says
|
// these versions should be aligned to windows releases, not what android says
|
||||||
activity.get()?.run {
|
activity.get()?.run {
|
||||||
val versionCode = LaunchUtils.getGeometryDashVersionCode(packageManager)
|
val versionCode = GamePackageUtils.getGameVersionCode(packageManager)
|
||||||
return gameVersionMap[versionCode] ?: LaunchUtils.getGeometryDashVersionString(packageManager)
|
return gameVersionMap[versionCode] ?: GamePackageUtils.getGameVersionString(packageManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -1,89 +1,10 @@
|
|||||||
package com.geode.launcher.utils
|
package com.geode.launcher.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.pm.PackageInfo
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.content.res.AssetManager
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ApplicationInfo
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object LaunchUtils {
|
object LaunchUtils {
|
||||||
fun isGeometryDashInstalled(packageManager: PackageManager): Boolean {
|
|
||||||
return try {
|
|
||||||
packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
|
||||||
true
|
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGeometryDashVersionCode(packageManager: PackageManager): Long {
|
|
||||||
val game = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
|
||||||
|
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
||||||
game.longVersionCode
|
|
||||||
} else {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
game.versionCode.toLong()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGeometryDashVersionString(packageManager: PackageManager): String {
|
|
||||||
val game = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
|
||||||
return game.versionName
|
|
||||||
}
|
|
||||||
|
|
||||||
fun detectAbiMismatch(context: Context, packageInfo: PackageInfo, loadException: Error): Boolean {
|
|
||||||
val abi = applicationArchitecture
|
|
||||||
val isExtracted =
|
|
||||||
packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS == ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS
|
|
||||||
val isSplit = (packageInfo.applicationInfo.splitSourceDirs?.size ?: 0) > 1
|
|
||||||
|
|
||||||
val metadata =
|
|
||||||
"Geometry Dash metadata:\nSplit sources: $isSplit\nExtracted libraries: $isExtracted\nLauncher architecture: $abi"
|
|
||||||
Log.i("GeodeLauncher", metadata)
|
|
||||||
|
|
||||||
// easiest check! these messages are hardcoded in bionic/linker/linker_phdr.cpp
|
|
||||||
if (loadException.message?.contains("32-bit instead of 64-bit") == true) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loadException.message?.contains("64-bit instead of 32-bit") == true) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine if it can find gd libraries for the opposite architecture
|
|
||||||
val gdBinaryName = "lib${Constants.COCOS_LIB_NAME}.so"
|
|
||||||
val oppositeArchitecture = if (abi == "arm64-v8a") "armeabi-v7a" else "arm64-v8a"
|
|
||||||
|
|
||||||
// detect issues using native library directory (only works on extracted libraries)
|
|
||||||
val nativeLibraryDir = packageInfo.applicationInfo.nativeLibraryDir
|
|
||||||
|
|
||||||
if (nativeLibraryDir.contains(oppositeArchitecture)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// android has some odd behavior where 32bit libraries get installed to the arm directory instead of armeabi-v7a
|
|
||||||
// detect it, ig
|
|
||||||
if (oppositeArchitecture == "armeabi-v7a" && nativeLibraryDir.contains("/lib/arm/")) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isExtracted) {
|
|
||||||
try {
|
|
||||||
context.assets.openNonAssetFd("lib/$oppositeArchitecture/$gdBinaryName")
|
|
||||||
return true
|
|
||||||
} catch (_: Exception) {
|
|
||||||
// this is good, actually!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// supposedly CPU_ABI returns the current arch for the running application
|
// supposedly CPU_ABI returns the current arch for the running application
|
||||||
// despite being deprecated, this is also one of the few ways to get this information
|
// despite being deprecated, this is also one of the few ways to get this information
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
@@ -143,19 +64,6 @@ object LaunchUtils {
|
|||||||
return File(getBaseDirectory(context), "save")
|
return File(getBaseDirectory(context), "save")
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DiscouragedPrivateApi")
|
|
||||||
fun addAssetsFromPackage(assetManager: AssetManager, packageInfo: PackageInfo) {
|
|
||||||
// this method is officially marked as deprecated but it is the only method we are allowed to reflect
|
|
||||||
// (the source recommends replacing with AssetManager.setApkAssets(ApkAssets[], boolean) lol)
|
|
||||||
val clazz = assetManager.javaClass
|
|
||||||
val aspMethod = clazz.getDeclaredMethod("addAssetPath", String::class.java)
|
|
||||||
|
|
||||||
aspMethod.invoke(assetManager, packageInfo.applicationInfo.sourceDir)
|
|
||||||
packageInfo.applicationInfo.splitSourceDirs?.forEach {
|
|
||||||
aspMethod.invoke(assetManager, it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private const val CRASH_INDICATOR_NAME = "lastSessionDidCrash"
|
private const val CRASH_INDICATOR_NAME = "lastSessionDidCrash"
|
||||||
|
|
||||||
private fun getCrashDirectory(context: Context): File {
|
private fun getCrashDirectory(context: Context): File {
|
||||||
|
|||||||
Reference in new issue
Block a user