Update Main.kt

This commit is contained in:
OTKUSteyler 2026-09-10 12:09:38 +02:00 • committed by GitHub
parent ad10c8a2a1
commit ea21c20d18
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2,108 +2,92 @@ package GoonXposed.xposed
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.ContextWrapper import android.content.pm.ApplicationInfo
import android.os.Bundle
import de.robv.android.xposed.IXposedHookLoadPackage import de.robv.android.xposed.IXposedHookLoadPackage
import de.robv.android.xposed.IXposedHookZygoteInit import de.robv.android.xposed.IXposedHookZygoteInit
import de.robv.android.xposed.callbacks.XC_LoadPackage import de.robv.android.xposed.callbacks.XC_LoadPackage
import GoonXposed.xposed.Utils.Log import GoonXposed.bridge.GoonBridge
import GoonXposed.xposed.modules.* import GoonXposed.xposed.api.HostScope
import GoonXposed.xposed.modules.appearance.FontsModule import GoonXposed.xposed.tweaks.*
import GoonXposed.xposed.modules.appearance.SysColorsModule import GoonXposed.xposed.tweaks.base.lifecycleSupport
import GoonXposed.xposed.modules.appearance.ThemesModule import GoonXposed.xposed.tweaks.base.scriptLoader
import GoonXposed.xposed.modules.bridge.AdditionalBridgeMethodsModule import GoonXposed.xposed.tweaks.bridge.GoonBridgeRegistry
import GoonXposed.xposed.modules.bridge.BridgeModule import GoonXposed.xposed.tweaks.bridge.additionalBridgeMethods
import GoonXposed.xposed.modules.no_track.BlockCrashReportingModule import GoonXposed.xposed.tweaks.bridge.goonBridgeSupport
import GoonXposed.xposed.modules.no_track.BlockDeepLinksTrackingModule import GoonXposed.xposed.tweaks.legacy.appearance.fonts
import GoonXposed.xposed.modules.LogBox.* import GoonXposed.xposed.tweaks.legacy.appearance.sysColors
import kotlinx.coroutines.CompletableDeferred import GoonXposed.xposed.tweaks.legacy.appearance.themes
import GoonXposed.xposed.tweaks.legacy.goonPayloadGlobal
import GoonXposed.xposed.tweaks.discordVersionRetriever
import GoonXposed.xposed.tweaks.plugins.pluginLoader
import GoonXposed.xposed.tweaks.plugins.pluginStates
import GoonXposed.xposed.tweaks.plugins.repos.pluginRepos
object HookStateHolder { private lateinit var modulePath: String
/**
* Whether all hooks are completed, and we are ready to load the JS bundle.
*/
val readyDeferred = CompletableDeferred<Unit>()
/** @Suppress("UNUSED")
* Whether we have successfully received a [Context] yet. class Main : IXposedHookLoadPackage, IXposedHookZygoteInit {
* Sometimes the app process is recreated and Xposed hooks way too late for us to get [Context] from [ContextWrapper.attachBaseContext].
* But since Xposed hooks before [Activity.onCreate], we can still get it from there and still initialize properly.
*/
@Volatile @Volatile
var gotContext = false
}
class Main : Module(), IXposedHookLoadPackage, IXposedHookZygoteInit {
private var hooked = false private var hooked = false
private val modules = mutableListOf(
HookScriptLoaderModule, private val tweaks: List<TweakSpec> = listOf(
BridgeModule, // Framework
AdditionalBridgeMethodsModule, lifecycleSupport,
PluginsModule(), goonBridgeSupport,
UpdaterModule, scriptLoader,
FixResourcesModule, discordVersionRetriever,
BlockDeepLinksTrackingModule,
BlockCrashReportingModule, // Static patches
LogBoxModule, fixResources,
CacheModule,
PerfPatchesModule, // Persistence
FontsModule, caches,
ThemesModule, pluginStates,
SysColorsModule pluginRepos,
// Async updater
goonUpdater,
// Consumers
discordDevSupport,
additionalBridgeMethods,
fonts,
themes,
sysColors,
pluginLoader,
goonScriptLoader,
goonPayloadGlobal,
) )
init {
modules += PayloadGlobalModule(modules)
}
override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) { override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
for (module in modules) module.onInit(startupParam) modulePath = startupParam.modulePath
} }
override fun handleLoadPackage(param: XC_LoadPackage.LoadPackageParam) = with(param) { override fun handleLoadPackage(param: XC_LoadPackage.LoadPackageParam) {
// Only hook the main process.
// Discord uses ProcessPhoenix to spawn a ":phoenix" process to restart the app. It will cause concurrency issues.
if (param.processName != param.packageName) return
if (hooked) return if (hooked) return
val reactActivity = classLoader.loadClass(Constants.TARGET_ACTIVITY)
ContextWrapper::class.java.hookMethod("attachBaseContext", Context::class.java) {
after {
val ctx = args[0] as Context
HookStateHolder.gotContext = true
Log.i("Received Context")
this@Main.onContext(ctx)
}
}
reactActivity.hookMethod("onCreate", Bundle::class.java) {
after {
val act = thisObject as Activity
Log.i("Received Activity")
if (!HookStateHolder.gotContext) {
Log.w("Activity created before we got Context, process may have been recreated!")
this@Main.onContext(act.applicationContext)
}
this@Main.onActivity(act)
HookStateHolder.readyDeferred.complete(Unit)
}
}
this@Main.onLoad(param)
hooked = true hooked = true
}
override fun onLoad(packageParam: XC_LoadPackage.LoadPackageParam) { val ctx = HostScopeImpl(
for (module in modules) module.onLoad(packageParam) modulePath = modulePath,
} appInfo = param.appInfo,
classLoader = param.classLoader,
override fun onContext(context: Context) { )
for (module in modules) module.onContext(context) for (spec in tweaks) spec.applyTo(ctx)
}
override fun onActivity(activity: Activity) {
for (module in modules) module.onActivity(activity)
} }
} }
private class HostScopeImpl(
override val modulePath: String,
override val appInfo: ApplicationInfo,
override val classLoader: ClassLoader,
) : HostScope {
override val bridge: GoonBridge get() = GoonBridgeRegistry
override fun withAppContext(block: (Context) -> Unit) =
GoonXposed.xposed.tweaks.base.withAppContext(block)
override fun withAppActivity(block: (Activity) -> Unit) =
GoonXposed.xposed.tweaks.base.withAppActivity(block)
}