Skip to content

Commit 806dd1f

Browse files
committed
feat(Discord): Add Plugin loader patch
1 parent 96e03ca commit 806dd1f

File tree

7 files changed

+112
-0
lines changed

7 files changed

+112
-0
lines changed

api/revanced-patches.api

+13
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,11 @@ public final class app/revanced/patches/cieid/restrictions/root/BypassRootChecks
251251
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
252252
}
253253

254+
public final class app/revanced/patches/discord/misc/plugin/PluginLoaderPatch : app/revanced/patches/shared/misc/react/BaseReactPreloadScriptBootstrapperPatch {
255+
public static final field INSTANCE Lapp/revanced/patches/discord/misc/plugin/PluginLoaderPatch;
256+
public fun getIntegrationsClassDescriptor ()Ljava/lang/String;
257+
}
258+
254259
public final class app/revanced/patches/duolingo/ad/DisableAdsPatch : app/revanced/patcher/patch/BytecodePatch {
255260
public static final field INSTANCE Lapp/revanced/patches/duolingo/ad/DisableAdsPatch;
256261
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
@@ -960,6 +965,14 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch
960965
public fun toString ()Ljava/lang/String;
961966
}
962967

968+
public abstract class app/revanced/patches/shared/misc/react/BaseReactPreloadScriptBootstrapperPatch : app/revanced/patcher/patch/BytecodePatch {
969+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZLjava/util/Set;Lkotlin/Pair;)V
970+
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZLjava/util/Set;Lkotlin/Pair;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
971+
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
972+
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
973+
public abstract fun getIntegrationsClassDescriptor ()Ljava/lang/String;
974+
}
975+
963976
public abstract class app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch : app/revanced/patcher/patch/ResourcePatch, java/io/Closeable, java/util/Set, kotlin/jvm/internal/markers/KMutableSet {
964977
public fun <init> ()V
965978
public fun <init> (Lkotlin/Pair;Ljava/util/Set;)V
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package app.revanced.patches.discord.misc.plugin
2+
3+
import app.revanced.patches.discord.misc.plugin.fingerprints.MainActivityOnCreateFingerprint
4+
import app.revanced.patches.shared.misc.react.BaseReactPreloadScriptBootstrapperPatch
5+
6+
@Suppress("unused")
7+
object PluginLoaderPatch : BaseReactPreloadScriptBootstrapperPatch(
8+
name = "Plugin loader",
9+
description = "Bootstraps a plugin loader.",
10+
mainActivityOnCreateFingerprintInsertIndexPair = MainActivityOnCreateFingerprint to 2,
11+
) {
12+
override val integrationsClassDescriptor = "Lapp/revanced/integrations/discord/plugin/BunnyBootstrapperPatch;"
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package app.revanced.patches.discord.misc.plugin.fingerprints
2+
3+
import app.revanced.patcher.fingerprint.MethodFingerprint
4+
5+
internal object MainActivityOnCreateFingerprint : MethodFingerprint(
6+
customFingerprint = { method, classDef -> method.name == "onCreate" && classDef.endsWith("ReactActivity;") },
7+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package app.revanced.patches.shared.misc.react
2+
3+
import app.revanced.patcher.PatchClass
4+
import app.revanced.patcher.data.BytecodeContext
5+
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
6+
import app.revanced.patcher.fingerprint.MethodFingerprint
7+
import app.revanced.patcher.patch.BytecodePatch
8+
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
9+
import app.revanced.patches.shared.misc.react.fingerprints.LoadScriptFromAssetsFingerprint
10+
import app.revanced.patches.shared.misc.react.fingerprints.LoadScriptFromFileFingerprint
11+
import app.revanced.util.resultOrThrow
12+
13+
abstract class BaseReactPreloadScriptBootstrapperPatch(
14+
name: String? = null,
15+
description: String? = null,
16+
compatiblePackages: Set<CompatiblePackage>? = null,
17+
dependencies: Set<PatchClass>? = null,
18+
use: Boolean = true,
19+
fingerprints: Set<MethodFingerprint> = emptySet(),
20+
private val mainActivityOnCreateFingerprintInsertIndexPair: Pair<MethodFingerprint, Int>,
21+
) : BytecodePatch(
22+
name = name,
23+
description = description,
24+
compatiblePackages = compatiblePackages,
25+
dependencies = dependencies,
26+
use = use,
27+
requiresIntegrations = true,
28+
fingerprints = setOf(
29+
LoadScriptFromAssetsFingerprint,
30+
LoadScriptFromFileFingerprint,
31+
mainActivityOnCreateFingerprintInsertIndexPair.first,
32+
) + fingerprints,
33+
) {
34+
abstract val integrationsClassDescriptor: String
35+
36+
override fun execute(context: BytecodeContext) {
37+
val (mainActivityOnCreateFingerprint, insertIndex) = mainActivityOnCreateFingerprintInsertIndexPair
38+
val loadScriptFromAssetMethod = LoadScriptFromAssetsFingerprint.resultOrThrow().mutableMethod
39+
val (catalystInstanceImplClassDef, loadScriptFromFileMethod) = LoadScriptFromFileFingerprint.resultOrThrow()
40+
.let { it.mutableClass to it.mutableMethod }
41+
42+
// Create preload script on main activity creation.
43+
mainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
44+
insertIndex, // Skip super call.
45+
"invoke-static { p0 }, " +
46+
"$integrationsClassDescriptor->hookOnCreate(Landroid/app/Activity;)V",
47+
)
48+
49+
// Copy of loadScriptFromFile method acts as a preload script loader.
50+
loadScriptFromFileMethod.toMutable().apply {
51+
name = "loadPreloadScriptFromFile"
52+
}.let(catalystInstanceImplClassDef.methods::add)
53+
54+
// Load preload script.
55+
listOf(loadScriptFromFileMethod, loadScriptFromAssetMethod).forEach { loadScriptMethod ->
56+
loadScriptMethod.addInstructions(
57+
0,
58+
"invoke-static { v0 }, $integrationsClassDescriptor->" +
59+
"hookLoadScriptFromFile($catalystInstanceImplClassDef)V",
60+
)
61+
}
62+
}
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package app.revanced.patches.shared.misc.react.fingerprints
2+
3+
import app.revanced.patcher.fingerprint.MethodFingerprint
4+
5+
internal abstract class CatalystInstanceImplFingerprint(methodName: String) :
6+
MethodFingerprint(
7+
customFingerprint = { method, classDef ->
8+
method.name == methodName && classDef.endsWith("CatalystInstanceImpl;")
9+
},
10+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package app.revanced.patches.shared.misc.react.fingerprints
2+
3+
internal object LoadScriptFromAssetsFingerprint : CatalystInstanceImplFingerprint("loadScriptFromAssets")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package app.revanced.patches.shared.misc.react.fingerprints
2+
3+
internal object LoadScriptFromFileFingerprint : CatalystInstanceImplFingerprint("loadScriptFromFile")

0 commit comments

Comments
 (0)