mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-22 00:42:38 +00:00
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.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 {
|
||||
|
||||
Reference in new issue
Block a user