diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/annotations/AutoClaimChannelPointsCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/annotations/AutoClaimChannelPointsCompatibility.kt new file mode 100644 index 00000000..30473cf3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/annotations/AutoClaimChannelPointsCompatibility.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.twitch.chat.autoclaim.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility([Package("tv.twitch.android.app")]) +@Target(AnnotationTarget.CLASS) +internal annotation class AutoClaimChannelPointsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/fingerprints/CommunityPointsButtonViewDelegateFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/fingerprints/CommunityPointsButtonViewDelegateFingerprint.kt new file mode 100644 index 00000000..9d5ff736 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/fingerprints/CommunityPointsButtonViewDelegateFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.twitch.chat.autoclaim.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object CommunityPointsButtonViewDelegateFingerprint : MethodFingerprint( + customFingerprint = { methodDef -> + methodDef.definingClass.endsWith("CommunityPointsButtonViewDelegate;") + && methodDef.name == "showClaimAvailable" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/patch/AutoClaimChannelPointsPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/patch/AutoClaimChannelPointsPatch.kt new file mode 100644 index 00000000..1c9e9a45 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/patch/AutoClaimChannelPointsPatch.kt @@ -0,0 +1,70 @@ +package app.revanced.patches.twitch.chat.autoclaim.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.instruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.twitch.chat.autoclaim.annotations.AutoClaimChannelPointsCompatibility +import app.revanced.patches.twitch.chat.autoclaim.fingerprints.CommunityPointsButtonViewDelegateFingerprint +import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch + +@Patch +@DependsOn([SettingsPatch::class]) +@Name("auto-claim-channel-points") +@Description("Automatically claim channel points.") +@AutoClaimChannelPointsCompatibility +@Version("0.0.1") +class AutoClaimChannelPointPatch : BytecodePatch( + listOf(CommunityPointsButtonViewDelegateFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { + SettingsPatch.PreferenceScreen.CHAT.GENERAL.addPreferences( + SwitchPreference( + "revanced_auto_claim_channel_points", + StringResource( + "revanced_auto_claim_channel_points", + "Automatically claim channel points" + ), + true, + StringResource( + "revanced_auto_claim_channel_points_on", + "Channel points are claimed automatically" + ), + StringResource( + "revanced_auto_claim_channel_points_off", + "Channel points are not claimed automatically" + ), + ) + ) + + CommunityPointsButtonViewDelegateFingerprint.result?.mutableMethod?.apply { + val lastIndex = implementation!!.instructions.lastIndex + addInstructions( + lastIndex, // place in front of return-void + """ + invoke-static {}, Lapp/revanced/twitch/patches/AutoClaimChannelPointsPatch;->shouldAutoClaim()Z + move-result v0 + if-eqz v0, :auto_claim + + # Claim by calling the button's onClick method + + iget-object v0, p0, Ltv/twitch/android/shared/community/points/viewdelegate/CommunityPointsButtonViewDelegate;->buttonLayout:Landroid/view/ViewGroup; + invoke-virtual { v0 }, Landroid/view/View;->callOnClick()Z + """, + listOf(ExternalLabel("auto_claim", instruction(lastIndex))) + ) + } ?: return CommunityPointsButtonViewDelegateFingerprint.toErrorResult() + return PatchResultSuccess() + } +}