feat: enable RN's LogBox and recovery options alert
This commit is contained in:
parent
2914d08cba
commit
d6435cc5aa
3 changed files with 121 additions and 2 deletions
|
|
@ -14,7 +14,6 @@ import de.robv.android.xposed.XC_MethodReplacement
|
||||||
import de.robv.android.xposed.XposedHelpers
|
import de.robv.android.xposed.XposedHelpers
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.decodeFromString
|
|
||||||
import kotlinx.serialization.json.*
|
import kotlinx.serialization.json.*
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
|
||||||
117
app/src/main/kotlin/io/github/pyoncord/xposed/LogBoxModule.kt
Normal file
117
app/src/main/kotlin/io/github/pyoncord/xposed/LogBoxModule.kt
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
package io.github.pyoncord.xposed
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
|
import android.app.AndroidAppHelper
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.util.Log
|
||||||
|
import de.robv.android.xposed.XC_MethodHook
|
||||||
|
import de.robv.android.xposed.XposedBridge
|
||||||
|
import de.robv.android.xposed.XposedHelpers
|
||||||
|
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class LogBoxModule: PyonModule() {
|
||||||
|
lateinit var packageParam: XC_LoadPackage.LoadPackageParam
|
||||||
|
|
||||||
|
override fun onInit(packageParam: XC_LoadPackage.LoadPackageParam) = with (packageParam) {
|
||||||
|
this@LogBoxModule.packageParam = packageParam
|
||||||
|
|
||||||
|
val dcdReactNativeHostClass = classLoader.loadClass("com.discord.bridge.DCDReactNativeHost")
|
||||||
|
val bridgeDevSupportManagerClass = classLoader.loadClass("com.facebook.react.devsupport.BridgeDevSupportManager")
|
||||||
|
|
||||||
|
val mReactInstanceDevHelperField = XposedHelpers.findField(bridgeDevSupportManagerClass, "mReactInstanceDevHelper")
|
||||||
|
|
||||||
|
val getUseDeveloperSupportMethod = dcdReactNativeHostClass.methods.first { it.name == "getUseDeveloperSupport" }
|
||||||
|
val handleReloadJSMethod = bridgeDevSupportManagerClass.methods.first { it.name == "handleReloadJS" }
|
||||||
|
val showDevOptionsDialogMethod = bridgeDevSupportManagerClass.methods.first { it.name == "showDevOptionsDialog" }
|
||||||
|
|
||||||
|
var alertDialog: AlertDialog? = null
|
||||||
|
|
||||||
|
// This enables the LogBox and opens dev option on shake
|
||||||
|
XposedBridge.hookMethod(
|
||||||
|
getUseDeveloperSupportMethod,
|
||||||
|
object : XC_MethodHook() {
|
||||||
|
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||||
|
param.result = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Triggered on shake
|
||||||
|
XposedBridge.hookMethod(
|
||||||
|
showDevOptionsDialogMethod,
|
||||||
|
object : XC_MethodHook() {
|
||||||
|
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||||
|
try {
|
||||||
|
if (alertDialog == null) {
|
||||||
|
val mReactInstanceDevHelper =
|
||||||
|
mReactInstanceDevHelperField.get(param.thisObject)
|
||||||
|
val getCurrentActivityMethod =
|
||||||
|
mReactInstanceDevHelper.javaClass.methods.first { it.name == "getCurrentActivity" }
|
||||||
|
|
||||||
|
val context =
|
||||||
|
getCurrentActivityMethod.invoke(mReactInstanceDevHelper) as Context
|
||||||
|
|
||||||
|
alertDialog = showRecoveryAlert(context) {
|
||||||
|
alertDialog = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
Log.e("Bunny", "Failed to show dev options dialog: $ex")
|
||||||
|
alertDialog = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the original dev menu
|
||||||
|
param.result = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Replace the method to direct relaunch the app instead of sending reload command to developer server
|
||||||
|
XposedBridge.hookMethod(
|
||||||
|
handleReloadJSMethod,
|
||||||
|
object : XC_MethodHook() {
|
||||||
|
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||||
|
reloadApp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return@with
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showRecoveryAlert(context: Context, onClose: () -> Unit): AlertDialog {
|
||||||
|
return AlertDialog.Builder(context)
|
||||||
|
.setTitle("Bunny Recovery Options")
|
||||||
|
.setItems(arrayOf("Reload", "Delete bundle.js")) { _, which ->
|
||||||
|
when (which) {
|
||||||
|
0 -> {
|
||||||
|
reloadApp()
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
val bundleFile = File(packageParam.appInfo.dataDir, "cache/pyoncord/bundle.js")
|
||||||
|
if (bundleFile.exists()) {
|
||||||
|
bundleFile.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadApp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
.setOnDismissListener {
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reloadApp() {
|
||||||
|
val application = AndroidAppHelper.currentApplication()
|
||||||
|
val intent = application.packageManager.getLaunchIntentForPackage(application.packageName)
|
||||||
|
application.startActivity(Intent.makeRestartActivityTask(intent!!.component))
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,7 @@ data class CustomLoadUrl(
|
||||||
val enabled: Boolean,
|
val enabled: Boolean,
|
||||||
val url: String
|
val url: String
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class LoaderConfig(
|
data class LoaderConfig(
|
||||||
val customLoadUrl: CustomLoadUrl
|
val customLoadUrl: CustomLoadUrl
|
||||||
|
|
@ -37,6 +38,7 @@ class Main : IXposedHookLoadPackage {
|
||||||
ThemeModule(),
|
ThemeModule(),
|
||||||
SysColorsModule(),
|
SysColorsModule(),
|
||||||
FontsModule(),
|
FontsModule(),
|
||||||
|
LogBoxModule()
|
||||||
)
|
)
|
||||||
|
|
||||||
fun buildLoaderJsonString(): String {
|
fun buildLoaderJsonString(): String {
|
||||||
|
|
@ -113,7 +115,8 @@ class Main : IXposedHookLoadPackage {
|
||||||
|
|
||||||
val config = try {
|
val config = try {
|
||||||
if (!configFile.exists()) throw Exception()
|
if (!configFile.exists()) throw Exception()
|
||||||
Json { ignoreUnknownKeys = true }.decodeFromString(configFile.readText())
|
val json = Json { ignoreUnknownKeys = true }
|
||||||
|
json.decodeFromString(configFile.readText())
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
LoaderConfig(
|
LoaderConfig(
|
||||||
customLoadUrl = CustomLoadUrl(
|
customLoadUrl = CustomLoadUrl(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue