feat(YouTube): Add Disable rolling number animations patch (#3298)

This commit is contained in:
LisoUseInAIKyrios 2023-11-19 17:03:35 +02:00 committed by oSumAtrIX
parent acf26ea821
commit a0121ae7b6
No known key found for this signature in database
GPG key ID: A9B3094ACDB604B4
16 changed files with 133 additions and 25 deletions

View file

@ -7,10 +7,10 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.shared.fingerprints.WatchWhileActivityFingerprint
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.SwipeControlsHostActivityFingerprint import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.SwipeControlsHostActivityFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.shared.fingerprints.WatchWhileActivityFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethod

View file

@ -9,12 +9,12 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction

View file

@ -0,0 +1,78 @@
package app.revanced.patches.youtube.layout.hide.rollingnumber
import app.revanced.extensions.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
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.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.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.RollingNumberTextViewAnimationUpdateFingerprint
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Disable rolling number animations",
description = "Disables rolling number animations of video view count, upload time, and user likes",
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]
)
@Suppress("unused")
object DisableRollingNumberAnimationPatch : BytecodePatch(
setOf(
RollingNumberTextViewAnimationUpdateFingerprint
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/DisableRollingNumberAnimationsPatch;"
override fun execute(context: BytecodeContext) {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_disable_rolling_number_animations",
StringResource("revanced_disable_rolling_number_animations_title", "Disable rolling number animations"),
StringResource("revanced_disable_rolling_number_animations_summary_on", "Rolling numbers are not animated"),
StringResource("revanced_disable_rolling_number_animations_summary_off", "Rolling numbers are animated")
)
)
// Animations are disabled by preventing an Image from being applied to the text span,
// which prevents the animations from appearing.
RollingNumberTextViewAnimationUpdateFingerprint.result?.apply {
val patternScanResult = scanResult.patternScanResult!!
val blockStartIndex = patternScanResult.startIndex
val blockEndIndex = patternScanResult.endIndex + 1
mutableMethod.apply {
val freeRegister = getInstruction<OneRegisterInstruction>(blockStartIndex).registerA
// ReturnYouTubeDislike also makes changes to this same method,
// and must add control flow label to a noop instruction to
// ensure RYD patch adds it's changes after the control flow label.
addInstructions(blockEndIndex, "nop")
addInstructionsWithLabels(
blockStartIndex,
"""
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->disableRollingNumberAnimations()Z
move-result v$freeRegister
if-nez v$freeRegister, :disable_animations
""",
ExternalLabel("disable_animations", getInstruction(blockEndIndex))
)
}
} ?: throw RollingNumberTextViewAnimationUpdateFingerprint.exception
}
}

View file

@ -5,14 +5,14 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch
import app.revanced.patches.youtube.layout.seekbar.SeekbarPreferencesPatch import app.revanced.patches.youtube.layout.seekbar.SeekbarPreferencesPatch
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
@Patch( @Patch(
name = "Hide seekbar", name = "Hide seekbar",

View file

@ -11,13 +11,13 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.* import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.shared.fingerprints.RollingNumberTextViewAnimationUpdateFingerprint
import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -55,8 +55,9 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
DislikeFingerprint, DislikeFingerprint,
RemoveLikeFingerprint, RemoveLikeFingerprint,
RollingNumberSetterFingerprint, RollingNumberSetterFingerprint,
RollingNumberMeasureTextParentFingerprint,
RollingNumberTextViewFingerprint, RollingNumberTextViewFingerprint,
RollingNumberMeasureTextParentFingerprint RollingNumberTextViewAnimationUpdateFingerprint
) )
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
@ -184,7 +185,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
// Rolling Number text views use the measured width of the raw string for layout. // Rolling Number text views use the measured width of the raw string for layout.
// Modify the measure text calculation to include the left drawable separator if needed. // Modify the measure text calculation to include the left drawable separator if needed.
RollingNumberMeasureTextFingerprint.also { RollingNumberMeasureAnimatedTextFingerprint.also {
if (!it.resolve(context, RollingNumberMeasureTextParentFingerprint.result!!.classDef)) if (!it.resolve(context, RollingNumberMeasureTextParentFingerprint.result!!.classDef))
throw it.exception throw it.exception
}.result?.also { }.result?.also {
@ -205,11 +206,11 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
""" """
) )
} }
} ?: throw RollingNumberMeasureTextFingerprint.exception } ?: throw RollingNumberMeasureAnimatedTextFingerprint.exception
// Additional text measurement method. Used if YouTube decides not to animate the likes count // Additional text measurement method. Used if YouTube decides not to animate the likes count
// and sometimes used for initial video load. // and sometimes used for initial video load.
RollingNumberStaticLabelMeasureTextFingerprint.also { RollingNumberMeasureStaticLabelFingerprint.also {
if (!it.resolve(context, RollingNumberMeasureTextParentFingerprint.result!!.classDef)) if (!it.resolve(context, RollingNumberMeasureTextParentFingerprint.result!!.classDef))
throw it.exception throw it.exception
}.result?.also { }.result?.also {
@ -225,7 +226,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
""" """
) )
} }
} ?: throw RollingNumberStaticLabelMeasureTextFingerprint.exception } ?: throw RollingNumberMeasureStaticLabelFingerprint.exception
// The rolling number Span is missing styling since it's initially set as a String. // The rolling number Span is missing styling since it's initially set as a String.
// Modify the UI text view and use the styled like/dislike Span. // Modify the UI text view and use the styled like/dislike Span.
@ -235,9 +236,9 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
// Videos less than 24 hours after uploaded, like counts will be updated in real time. // Videos less than 24 hours after uploaded, like counts will be updated in real time.
// Whenever like counts are updated, TextView is set in this method. // Whenever like counts are updated, TextView is set in this method.
val realTimeUpdateTextViewMethod = it.mutableClass.methods.find { method -> val realTimeUpdateTextViewMethod =
method.parameterTypes.first() == "Landroid/graphics/Bitmap;" RollingNumberTextViewAnimationUpdateFingerprint.result?.mutableMethod
} ?: throw PatchException("Failed to find realTimeUpdateTextViewMethod") ?: throw RollingNumberTextViewAnimationUpdateFingerprint.exception
arrayOf( arrayOf(
initiallyCreatedTextViewMethod, initiallyCreatedTextViewMethod,

View file

@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.Opcode
/** /**
* Resolves to class found in [RollingNumberMeasureTextParentFingerprint]. * Resolves to class found in [RollingNumberMeasureTextParentFingerprint].
*/ */
object RollingNumberMeasureTextFingerprint : MethodFingerprint( object RollingNumberMeasureAnimatedTextFingerprint : MethodFingerprint(
returnType = "F", returnType = "F",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Ljava/lang/String;"), parameters = listOf("Ljava/lang/String;"),

View file

@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.Opcode
/** /**
* Resolves to class found in [RollingNumberMeasureTextParentFingerprint]. * Resolves to class found in [RollingNumberMeasureTextParentFingerprint].
*/ */
object RollingNumberStaticLabelMeasureTextFingerprint : MethodFingerprint( object RollingNumberMeasureStaticLabelFingerprint : MethodFingerprint(
returnType = "F", returnType = "F",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Ljava/lang/String;"), parameters = listOf("Ljava/lang/String;"),

View file

@ -17,7 +17,7 @@ object RollingNumberTextViewFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID Opcode.RETURN_VOID
), ),
customFingerprint = custom@{ _, classDef -> customFingerprint = { _, classDef ->
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;" classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;"
} }
) )

View file

@ -11,8 +11,6 @@ import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
import app.revanced.patches.youtube.layout.sponsorblock.fingerprints.AppendTimeFingerprint import app.revanced.patches.youtube.layout.sponsorblock.fingerprints.AppendTimeFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.fingerprints.ControlsOverlayFingerprint import app.revanced.patches.youtube.layout.sponsorblock.fingerprints.ControlsOverlayFingerprint
@ -22,7 +20,9 @@ import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParen
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode

View file

@ -7,10 +7,10 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.fingerprints.WatchWhileActivityFingerprint
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.WatchWhileActivityFingerprint
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@Patch( @Patch(

View file

@ -5,7 +5,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.packagename.ChangePackageNamePatch import app.revanced.patches.all.misc.packagename.ChangePackageNamePatch
import app.revanced.patches.shared.fingerprints.WatchWhileActivityFingerprint import app.revanced.patches.youtube.shared.fingerprints.WatchWhileActivityFingerprint
import app.revanced.patches.youtube.layout.buttons.cast.HideCastButtonPatch import app.revanced.patches.youtube.layout.buttons.cast.HideCastButtonPatch
import app.revanced.patches.youtube.misc.fix.playback.ClientSpoofPatch import app.revanced.patches.youtube.misc.fix.playback.ClientSpoofPatch
import app.revanced.patches.youtube.misc.microg.fingerprints.* import app.revanced.patches.youtube.misc.microg.fingerprints.*

View file

@ -6,7 +6,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint.MethodFingerprintResult import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction

View file

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints package app.revanced.patches.youtube.shared.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View file

@ -0,0 +1,30 @@
package app.revanced.patches.youtube.shared.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
object RollingNumberTextViewAnimationUpdateFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/graphics/Bitmap;"),
opcodes = listOf(
Opcode.NEW_INSTANCE, // bitmap ImageSpan
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.CONST_16,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INT_TO_FLOAT,
Opcode.INVOKE_VIRTUAL, // set textview padding using bitmap width
),
customFingerprint = { _, classDef ->
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;"
}
)

View file

@ -1,5 +1,4 @@
package app.revanced.patches.shared.fingerprints package app.revanced.patches.youtube.shared.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View file

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints package app.revanced.patches.youtube.shared.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint