diff --git a/patches/api/patches.api b/patches/api/patches.api index 20f74169a..1341b5ff8 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -184,6 +184,10 @@ public final class app/revanced/patches/duolingo/debug/EnableDebugMenuPatchKt { public static final fun getEnableDebugMenuPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatchKt { + public static final fun getSkipEnergyRechargeAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatchKt { public static final fun getHideSponsoredStoriesPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt new file mode 100644 index 000000000..73dbcf304 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.duolingo.energy + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +/** + * Matches the class found in [energyConfigToStringFingerprint]. + */ +internal val initializeEnergyConfigFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) + opcodes(Opcode.RETURN_VOID) +} + +// Class name currently is not obfuscated but it may be in the future. +internal val energyConfigToStringFingerprint = fingerprint { + parameters() + returns("Ljava/lang/String;") + strings("EnergyConfig(", "maxEnergy=") // Partial string matches. + custom { method, _ -> method.name == "toString" } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt new file mode 100644 index 000000000..bec800f50 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.duolingo.energy + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.util.findFieldFromToString + +@Suppress("unused") +val skipEnergyRechargeAdsPatch = bytecodePatch( + name = "Skip energy recharge ads", + description = "Skips watching ads to recharge energy." +) { + compatibleWith("com.duolingo") + + execute { + initializeEnergyConfigFingerprint + .match(energyConfigToStringFingerprint.classDef) + .method.apply { + val energyField = energyConfigToStringFingerprint.method + .findFieldFromToString("energy=") + val insertIndex = initializeEnergyConfigFingerprint.patternMatch!!.startIndex + + addInstructions( + insertIndex, + """ + const/16 v0, 99 + iput v0, p0, $energyField + """ + ) + } + } +}