mirror of
https://github.com/revanced/revanced-patches
synced 2024-09-03 21:15:26 +02:00
feat(twitch): settings for patches (#1142)
This commit is contained in:
parent
a334562a27
commit
ed56f94f12
@ -4,15 +4,23 @@ import app.revanced.patcher.annotation.Description
|
|||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.addInstruction
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
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.ad.audio.annotations.AudioAdsCompatibility
|
import app.revanced.patches.twitch.ad.audio.annotations.AudioAdsCompatibility
|
||||||
import app.revanced.patches.twitch.ad.audio.fingerprints.AudioAdsPresenterPlayFingerprint
|
import app.revanced.patches.twitch.ad.audio.fingerprints.AudioAdsPresenterPlayFingerprint
|
||||||
|
import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||||
@Name("block-audio-ads")
|
@Name("block-audio-ads")
|
||||||
@Description("Blocks audio ads in streams and VODs.")
|
@Description("Blocks audio ads in streams and VODs.")
|
||||||
@AudioAdsCompatibility
|
@AudioAdsCompatibility
|
||||||
@ -23,9 +31,37 @@ class AudioAdsPatch : BytecodePatch(
|
|||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
// Block playAds call
|
// Block playAds call
|
||||||
with(AudioAdsPresenterPlayFingerprint.result!!) {
|
with(AudioAdsPresenterPlayFingerprint.result!!) {
|
||||||
mutableMethod.addInstruction(0, "return-void")
|
mutableMethod.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static { }, Lapp/revanced/twitch/patches/AudioAdsPatch;->shouldBlockAudioAds()Z
|
||||||
|
move-result v0
|
||||||
|
if-eqz v0, :show_audio_ads
|
||||||
|
return-void
|
||||||
|
""",
|
||||||
|
listOf(ExternalLabel("show_audio_ads", mutableMethod.instruction(0)))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_block_audio_ads",
|
||||||
|
StringResource(
|
||||||
|
"revanced_block_audio_ads",
|
||||||
|
"Block audio ads"
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
StringResource(
|
||||||
|
"revanced_block_audio_ads_on",
|
||||||
|
"Audio ads are blocked"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_block_audio_ads_off",
|
||||||
|
"Audio ads are unblocked"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,25 @@ import app.revanced.patcher.annotation.Description
|
|||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.addInstruction
|
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
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.ad.video.annotations.VideoAdsCompatibility
|
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||||
import app.revanced.patches.twitch.ad.video.fingerprints.AdsManagerFingerprint
|
import app.revanced.patches.twitch.ad.video.fingerprints.AdsManagerFingerprint
|
||||||
import app.revanced.patches.twitch.ad.video.fingerprints.CheckAdEligibilityLambdaFingerprint
|
import app.revanced.patches.twitch.ad.video.fingerprints.CheckAdEligibilityLambdaFingerprint
|
||||||
import app.revanced.patches.twitch.ad.video.fingerprints.ContentConfigShowAdsFingerprint
|
import app.revanced.patches.twitch.ad.video.fingerprints.ContentConfigShowAdsFingerprint
|
||||||
|
import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||||
@Name("block-video-ads")
|
@Name("block-video-ads")
|
||||||
@Description("Blocks video ads in streams and VODs.")
|
@Description("Blocks video ads in streams and VODs.")
|
||||||
@VideoAdsCompatibility
|
@VideoAdsCompatibility
|
||||||
@ -27,24 +34,34 @@ class VideoAdsPatch : BytecodePatch(
|
|||||||
CheckAdEligibilityLambdaFingerprint
|
CheckAdEligibilityLambdaFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
private fun createConditionInstructions(register: String = "v0") = """
|
||||||
|
invoke-static { }, Lapp/revanced/twitch/patches/VideoAdsPatch;->shouldBlockVideoAds()Z
|
||||||
|
move-result $register
|
||||||
|
if-eqz $register, :show_video_ads
|
||||||
|
"""
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
// Pretend our player is ineligible for all ads
|
// Pretend our player is ineligible for all ads
|
||||||
with(CheckAdEligibilityLambdaFingerprint.result!!) {
|
with(CheckAdEligibilityLambdaFingerprint.result!!) {
|
||||||
mutableMethod.addInstructions(
|
mutableMethod.addInstructions(
|
||||||
0,
|
0,
|
||||||
"""
|
"""
|
||||||
|
${createConditionInstructions()}
|
||||||
const/4 v0, 0
|
const/4 v0, 0
|
||||||
invoke-static {v0}, Lio/reactivex/Single;->just(Ljava/lang/Object;)Lio/reactivex/Single;
|
invoke-static {v0}, Lio/reactivex/Single;->just(Ljava/lang/Object;)Lio/reactivex/Single;
|
||||||
move-result-object p0
|
move-result-object p0
|
||||||
return-object p0
|
return-object p0
|
||||||
"""
|
""",
|
||||||
|
listOf(ExternalLabel("show_video_ads", mutableMethod.instruction(0)))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spoof showAds JSON field
|
// Spoof showAds JSON field
|
||||||
with(ContentConfigShowAdsFingerprint.result!!) {
|
with(ContentConfigShowAdsFingerprint.result!!) {
|
||||||
mutableMethod.addInstructions(0, """
|
mutableMethod.addInstructions(0, """
|
||||||
|
${createConditionInstructions()}
|
||||||
const/4 v0, 0
|
const/4 v0, 0
|
||||||
|
:show_video_ads
|
||||||
return v0
|
return v0
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@ -52,9 +69,35 @@ class VideoAdsPatch : BytecodePatch(
|
|||||||
|
|
||||||
// Block playAds call
|
// Block playAds call
|
||||||
with(AdsManagerFingerprint.result!!) {
|
with(AdsManagerFingerprint.result!!) {
|
||||||
mutableMethod.addInstruction(0, "return-void")
|
mutableMethod.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
${createConditionInstructions()}
|
||||||
|
return-void
|
||||||
|
""",
|
||||||
|
listOf(ExternalLabel("show_video_ads", mutableMethod.instruction(0)))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_block_video_ads",
|
||||||
|
StringResource(
|
||||||
|
"revanced_block_video_ads",
|
||||||
|
"Block video ads"
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
StringResource(
|
||||||
|
"revanced_block_video_ads_on",
|
||||||
|
"Video ads are blocked"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_block_video_ads_off",
|
||||||
|
"Video ads are unblocked"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package app.revanced.patches.twitch.chat.antidelete.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
|
||||||
|
object ChatUtilCreateDeletedSpanFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("/ChatUtil\$Companion;") && methodDef.name == "createDeletedSpanFromChatMessageSpan"
|
||||||
|
}
|
||||||
|
)
|
@ -6,13 +6,19 @@ import app.revanced.patcher.annotation.Version
|
|||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.*
|
import app.revanced.patcher.extensions.*
|
||||||
import app.revanced.patcher.patch.*
|
import app.revanced.patcher.patch.*
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.ArrayResource
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.ListPreference
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
|
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
|
||||||
import app.revanced.patches.twitch.chat.antidelete.fingerprints.*
|
import app.revanced.patches.twitch.chat.antidelete.fingerprints.*
|
||||||
import org.jf.dexlib2.Opcode
|
import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch
|
||||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction10x
|
import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||||
@Name("show-deleted-messages")
|
@Name("show-deleted-messages")
|
||||||
@Description("Shows deleted chat messages behind a clickable spoiler.")
|
@Description("Shows deleted chat messages behind a clickable spoiler.")
|
||||||
@ShowDeletedMessagesCompatibility
|
@ShowDeletedMessagesCompatibility
|
||||||
@ -21,25 +27,77 @@ class ShowDeletedMessagesPatch : BytecodePatch(
|
|||||||
listOf(
|
listOf(
|
||||||
SetHasModAccessFingerprint,
|
SetHasModAccessFingerprint,
|
||||||
DeletedMessageClickableSpanCtorFingerprint,
|
DeletedMessageClickableSpanCtorFingerprint,
|
||||||
|
ChatUtilCreateDeletedSpanFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
private fun createSpoilerConditionInstructions(register: String = "v0") = """
|
||||||
|
invoke-static {}, Lapp/revanced/twitch/patches/ShowDeletedMessagesPatch;->shouldUseSpoiler()Z
|
||||||
|
move-result $register
|
||||||
|
if-eqz $register, :no_spoiler
|
||||||
|
"""
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
// Force set hasModAccess member to true in constructor
|
// Spoiler mode: Force set hasModAccess member to true in constructor
|
||||||
with(DeletedMessageClickableSpanCtorFingerprint.result!!.mutableMethod) {
|
with(DeletedMessageClickableSpanCtorFingerprint.result!!.mutableMethod) {
|
||||||
addInstructions(
|
addInstructions(
|
||||||
implementation!!.instructions.lastIndex, /* place in front of return-void */
|
implementation!!.instructions.lastIndex, /* place in front of return-void */
|
||||||
"""
|
"""
|
||||||
|
${createSpoilerConditionInstructions()}
|
||||||
const/4 v0, 1
|
const/4 v0, 1
|
||||||
iput-boolean v0, p0, $definingClass->hasModAccess:Z
|
iput-boolean v0, p0, $definingClass->hasModAccess:Z
|
||||||
"""
|
""",
|
||||||
|
listOf(ExternalLabel("no_spoiler", instruction(implementation!!.instructions.lastIndex)))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable setHasModAccess setter
|
// Spoiler mode: Disable setHasModAccess setter
|
||||||
with(SetHasModAccessFingerprint.result!!.mutableMethod.implementation!!) {
|
with(SetHasModAccessFingerprint.result!!) {
|
||||||
addInstruction(0, BuilderInstruction10x(Opcode.RETURN_VOID))
|
mutableMethod.addInstruction(0, "return-void")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cross-out mode: Reformat span of deleted message
|
||||||
|
with(ChatUtilCreateDeletedSpanFingerprint.result!!) {
|
||||||
|
mutableMethod.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static {p2}, Lapp/revanced/twitch/patches/ShowDeletedMessagesPatch;->reformatDeletedMessage(Landroid/text/Spanned;)Landroid/text/Spanned;
|
||||||
|
move-result-object v0
|
||||||
|
if-eqz v0, :no_reformat
|
||||||
|
return-object v0
|
||||||
|
""",
|
||||||
|
listOf(ExternalLabel("no_reformat", mutableMethod.instruction(0)))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.PreferenceScreen.CHAT.GENERAL.addPreferences(
|
||||||
|
ListPreference(
|
||||||
|
"revanced_show_deleted_messages",
|
||||||
|
StringResource(
|
||||||
|
"revanced_show_deleted_messages_title",
|
||||||
|
"Show deleted messages"
|
||||||
|
),
|
||||||
|
ArrayResource(
|
||||||
|
"revanced_deleted_messages",
|
||||||
|
listOf(
|
||||||
|
StringResource("revanced_deleted_messages_hide", "Do not show deleted messages"),
|
||||||
|
StringResource("revanced_deleted_messages_spoiler", "Hide deleted messages behind a spoiler"),
|
||||||
|
StringResource("revanced_deleted_messages_cross_out", "Show deleted messages as crossed-out text")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
ArrayResource(
|
||||||
|
"revanced_deleted_messages_values",
|
||||||
|
listOf(
|
||||||
|
StringResource("key_revanced_deleted_messages_hide", "hide"),
|
||||||
|
StringResource("key_revanced_deleted_messages_spoiler", "spoiler"),
|
||||||
|
StringResource("key_revanced_deleted_messages_cross_out", "cross-out")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"cross-out"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
SettingsPatch.addString("revanced_deleted_msg", "message deleted")
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,19 @@ import app.revanced.patcher.extensions.addInstructions
|
|||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||||
import app.revanced.patches.twitch.debug.fingerprints.IsDebugConfigEnabledFingerprint
|
import app.revanced.patches.twitch.debug.fingerprints.IsDebugConfigEnabledFingerprint
|
||||||
import app.revanced.patches.twitch.debug.fingerprints.IsOmVerificationEnabledFingerprint
|
import app.revanced.patches.twitch.debug.fingerprints.IsOmVerificationEnabledFingerprint
|
||||||
import app.revanced.patches.twitch.debug.fingerprints.ShouldShowDebugOptionsFingerprint
|
import app.revanced.patches.twitch.debug.fingerprints.ShouldShowDebugOptionsFingerprint
|
||||||
|
import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
|
||||||
@Patch(false)
|
@Patch(false)
|
||||||
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||||
@Name("debug-mode")
|
@Name("debug-mode")
|
||||||
@Description("Enables Twitch's internal debugging mode.")
|
@Description("Enables Twitch's internal debugging mode.")
|
||||||
@DebugModeCompatibility
|
@DebugModeCompatibility
|
||||||
@ -37,13 +43,34 @@ class DebugModePatch : BytecodePatch(
|
|||||||
addInstructions(
|
addInstructions(
|
||||||
0,
|
0,
|
||||||
"""
|
"""
|
||||||
const/4 v0, 0x1
|
invoke-static {}, Lapp/revanced/twitch/patches/DebugModePatch;->isDebugModeEnabled()Z
|
||||||
|
move-result v0
|
||||||
return v0
|
return v0
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsPatch.PreferenceScreen.MISC.OTHER.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_debug_mode",
|
||||||
|
StringResource(
|
||||||
|
"revanced_debug_mode_enable",
|
||||||
|
"Enable debug mode"
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
StringResource(
|
||||||
|
"revanced_debug_mode_on",
|
||||||
|
"Debug mode is enabled (not recommended)"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_debug_mode_off",
|
||||||
|
"Debug mode is disabled"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user