Skip to content

Commit

Permalink
feat(Discord): Add Plugin loader patch
Browse files Browse the repository at this point in the history
  • Loading branch information
oSumAtrIX committed Sep 11, 2024
1 parent 96e03ca commit f2f6d68
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app.revanced.patches.discord.misc.plugin

import app.revanced.patches.discord.misc.plugin.fingerprints.MainActivityOnCreateFingerprint
import app.revanced.patches.shared.misc.react.BaseReactPreloadScriptBootstrapperPatch

@Suppress("unused")
object PluginLoaderPatch : BaseReactPreloadScriptBootstrapperPatch(
name = "Plugin loader",
description = "Bootstraps a plugin loader.",
mainActivityOnCreateFingerprintInsertIndexPair = MainActivityOnCreateFingerprint to 2,
) {
override val integrationsClassDescriptor = "Lapp/revanced/integrations/discord/plugin/BunnyBootstrapperPatch;"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package app.revanced.patches.discord.misc.plugin.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint

internal object MainActivityOnCreateFingerprint : MethodFingerprint(
customFingerprint = { method, classDef -> method.name == "onCreate" && classDef.endsWith("ReactActivity;") },
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package app.revanced.patches.shared.misc.react

import app.revanced.patcher.PatchClass
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.shared.misc.react.fingerprints.LoadScriptFromAssetFingerprint
import app.revanced.patches.shared.misc.react.fingerprints.LoadScriptFromFileFingerprint
import app.revanced.util.resultOrThrow

abstract class BaseReactPreloadScriptBootstrapperPatch(
name: String? = null,
description: String? = null,
compatiblePackages: Set<CompatiblePackage>? = null,
dependencies: Set<PatchClass>? = null,
use: Boolean = true,
fingerprints: Set<MethodFingerprint> = emptySet(),
private val mainActivityOnCreateFingerprintInsertIndexPair: Pair<MethodFingerprint, Int>,
) : BytecodePatch(
name = name,
description = description,
compatiblePackages = compatiblePackages,
dependencies = dependencies,
use = use,
requiresIntegrations = true,
fingerprints = setOf(
LoadScriptFromAssetFingerprint,
LoadScriptFromFileFingerprint,
mainActivityOnCreateFingerprintInsertIndexPair.first,
) + fingerprints,
) {
abstract val integrationsClassDescriptor: String

override fun execute(context: BytecodeContext) {
val (mainActivityOnCreateFingerprint, insertIndex) = mainActivityOnCreateFingerprintInsertIndexPair
val loadScriptFromAssetMethod = LoadScriptFromAssetFingerprint.resultOrThrow().mutableMethod
val (catalystInstanceImplClassDef, loadScriptFromFileMethod) = LoadScriptFromFileFingerprint.resultOrThrow()
.let { it.mutableClass to it.mutableMethod }

// Create preload script on main activity creation.
mainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
insertIndex, // Skip super call.
"invoke-static { p0 }, " +
"$integrationsClassDescriptor->startWritePreloadScripts(Landroid/app/Activity;)V",
)

// Copy of loadScriptFromFile method acts as a preload script loader.
loadScriptFromFileMethod.toMutable().apply {
name = "loadPreloadScriptFromFile"
}.let(catalystInstanceImplClassDef.methods::add)

// Load preload script.
listOf(loadScriptFromFileMethod, loadScriptFromAssetMethod).forEach { loadScriptMethod ->
loadScriptMethod.addInstructions(
0,
"invoke-virtual { p0 }, $integrationsClassDescriptor->" +
"hookLoadScriptFromFile($catalystInstanceImplClassDef)V",
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package app.revanced.patches.shared.misc.react.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint

internal abstract class CatalystInstanceImplFingerprint(methodName: String) :
MethodFingerprint(
customFingerprint = { method, classDef ->
method.name == methodName && classDef.endsWith("CatalystInstanceImpl;")
},
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package app.revanced.patches.shared.misc.react.fingerprints

internal object LoadScriptFromAssetFingerprint : CatalystInstanceImplFingerprint("loadScriptFromAsset")
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package app.revanced.patches.shared.misc.react.fingerprints

internal object LoadScriptFromFileFingerprint : CatalystInstanceImplFingerprint("loadScriptFromFile")

0 comments on commit f2f6d68

Please sign in to comment.