mirror of
https://github.com/revanced/revanced-patches
synced 2024-12-29 08:55:50 +01:00
feat(Duolingo): Add Disable ads
and Enable debug menu
patch (#3422)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de> Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
This commit is contained in:
parent
eb740abd39
commit
d0a8599f76
@ -243,6 +243,18 @@ public final class app/revanced/patches/cieid/restrictions/root/BypassRootChecks
|
|||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/duolingo/ad/DisableAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/duolingo/ad/DisableAdsPatch;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/duolingo/debug/EnableDebugMenuPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/duolingo/debug/EnableDebugMenuPatch;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/facebook/ads/story/HideStoryAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/facebook/ads/story/HideStoryAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/facebook/ads/story/HideStoryAdsPatch;
|
public static final field INSTANCE Lapp/revanced/patches/facebook/ads/story/HideStoryAdsPatch;
|
||||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package app.revanced.patches.duolingo.ad
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.duolingo.ad.fingerprints.InitializeMonetizationDebugSettingsFingerprint
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Disable ads",
|
||||||
|
compatiblePackages = [CompatiblePackage("com.duolingo")]
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object DisableAdsPatch : BytecodePatch(
|
||||||
|
setOf(InitializeMonetizationDebugSettingsFingerprint)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
// Couple approaches to remove ads exist:
|
||||||
|
//
|
||||||
|
// MonetizationDebugSettings has a boolean value for "disableAds".
|
||||||
|
// OnboardingState has a getter to check if the user has any "adFreeSessions".
|
||||||
|
// SharedPreferences has a debug boolean value with key "disable_ads", which maps to "DebugCategory.DISABLE_ADS".
|
||||||
|
//
|
||||||
|
// MonetizationDebugSettings seems to be the most general setting to work fine.
|
||||||
|
InitializeMonetizationDebugSettingsFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex,
|
||||||
|
"const/4 v$register, 0x1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package app.revanced.patches.duolingo.ad.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
internal object InitializeMonetizationDebugSettingsFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
|
parameters = listOf(
|
||||||
|
"Z", // disableAds
|
||||||
|
"Z", // useDebugBilling
|
||||||
|
"Z", // showManageSubscriptions
|
||||||
|
"Z", // alwaysShowSuperAds
|
||||||
|
"Lcom/duolingo/debug/FamilyQuestOverride;",
|
||||||
|
),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.IPUT_BOOLEAN
|
||||||
|
)
|
||||||
|
)
|
@ -0,0 +1,35 @@
|
|||||||
|
package app.revanced.patches.duolingo.debug
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.duolingo.debug.fingerprints.InitializeBuildConfigProviderFingerprint
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Enable debug menu",
|
||||||
|
compatiblePackages = [CompatiblePackage("com.duolingo", ["5.158.4"])],
|
||||||
|
use = false
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object EnableDebugMenuPatch : BytecodePatch(
|
||||||
|
setOf(InitializeBuildConfigProviderFingerprint)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
InitializeBuildConfigProviderFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex,
|
||||||
|
"const/4 v$register, 0x1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package app.revanced.patches.duolingo.debug.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `BuildConfigProvider` class has two booleans:
|
||||||
|
*
|
||||||
|
* - `isChina`: (usually) compares "play" with "china"...except for builds in China
|
||||||
|
* - `isDebug`: compares "release" with "debug" <-- we want to force this to `true`
|
||||||
|
*/
|
||||||
|
internal object InitializeBuildConfigProviderFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
|
strings = listOf(
|
||||||
|
"debug",
|
||||||
|
"release",
|
||||||
|
"china",
|
||||||
|
),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.IPUT_BOOLEAN
|
||||||
|
)
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user