move gd functions to a separate file

This commit is contained in:
qimiko committed 2024-03-16 23:08:23 -07:00
1 parent d89e0f1134
commit a59cdd5d16
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.ConstrainedFrameLayout
import com.geode.launcher.utils.DownloadUtils
import com.geode.launcher.utils.GamePackageUtils
import com.geode.launcher.utils.GeodeUtils
import com.geode.launcher.utils.LaunchUtils
import com.geode.launcher.utils.PreferenceUtils
@@ -65,7 +66,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
super.onCreate(savedInstanceState)
// return back to main if Geometry Dash isn't found
if (!LaunchUtils.isGeometryDashInstalled(packageManager)) {
if (!GamePackageUtils.isGameInstalled(packageManager)) {
returnToMain()
return
}
@@ -77,7 +78,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
// generates helpful information for use in debugging library load failures
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 errorMessage = when {
@@ -163,7 +164,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
private fun setupRedirection(packageInfo: PackageInfo) {
try {
LaunchUtils.addAssetsFromPackage(assets, packageInfo)
GamePackageUtils.addAssetsFromPackage(assets, packageInfo)
} catch (e: NoSuchMethodException) {
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.PreferenceUtils
import com.geode.launcher.updater.ReleaseManager
import com.geode.launcher.utils.GamePackageUtils
import com.geode.launcher.utils.GeodeUtils
import com.geode.launcher.utils.useCountdownTimer
import kotlinx.coroutines.delay
@@ -78,7 +79,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
val gdInstalled = LaunchUtils.isGeometryDashInstalled(packageManager)
val gdInstalled = GamePackageUtils.isGameInstalled(packageManager)
val geodeInstalled = LaunchUtils.isGeodeInstalled(this)
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 packageManager = context.packageManager
val gdVersionCode = remember { LaunchUtils.getGeometryDashVersionCode(packageManager) }
val gdVersionString = remember { LaunchUtils.getGeometryDashVersionString(packageManager) }
val gdVersionCode = remember { GamePackageUtils.getGameVersionCode(packageManager) }
val gdVersionString = remember { GamePackageUtils.getGameVersionString(packageManager) }
var lastDismissedVersion by PreferenceUtils.useLongPreference(
preferenceKey = PreferenceUtils.Key.DISMISSED_GJ_UPDATE
@@ -562,8 +563,7 @@ fun ErrorInfoActions(extraDetails: String?, modifier: Modifier = Modifier) {
}
FilledTonalButton(onClick = {
val message = extraDetails
clipboardManager.setText(AnnotatedString(message))
clipboardManager.setText(AnnotatedString(extraDetails))
}) {
Icon(
painterResource(R.drawable.icon_content_copy),
@@ -864,7 +864,7 @@ fun MainScreen(
when {
gdInstalled && geodeInstalled -> {
val gdVersion = remember {
LaunchUtils.getGeometryDashVersionCode(context.packageManager)
GamePackageUtils.getGameVersionCode(context.packageManager)
}
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 {
// these versions should be aligned to windows releases, not what android says
activity.get()?.run {
val versionCode = LaunchUtils.getGeometryDashVersionCode(packageManager)
return gameVersionMap[versionCode] ?: LaunchUtils.getGeometryDashVersionString(packageManager)
val versionCode = GamePackageUtils.getGameVersionCode(packageManager)
return gameVersionMap[versionCode] ?: GamePackageUtils.getGameVersionString(packageManager)
}
return ""
@@ -1,89 +1,10 @@
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.pm.ApplicationInfo
import android.os.Build
import android.util.Log
import java.io.File
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
// despite being deprecated, this is also one of the few ways to get this information
@Suppress("DEPRECATION")
@@ -143,19 +64,6 @@ object LaunchUtils {
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 fun getCrashDirectory(context: Context): File {