fix(YouTube - Spoof app version): Remove broken spoof targets that YouTube no longer supports (#4610)

This commit is contained in:
LisoUseInAIKyrios
2025-03-19 18:08:51 +01:00
committed by GitHub
parent 2090f7ec8f
commit 883fbe7123
9 changed files with 43 additions and 298 deletions

View File

@ -98,20 +98,6 @@ internal val rollingNumberTextViewFingerprint = fingerprint {
}
}
internal val shortsTextViewFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters("L", "L")
opcodes(
Opcode.INVOKE_SUPER, // first instruction of method
Opcode.IF_NEZ,
null,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
)
}
internal val textComponentConstructorFingerprint = fingerprint {
accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PRIVATE)
strings("TextComponent")

View File

@ -1,9 +1,7 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike
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.extensions.InstructionExtensions.instructions
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
@ -169,51 +167,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
// endregion
// region Hook for non-litho Short videos.
shortsTextViewFingerprint.method.apply {
val insertIndex = shortsTextViewFingerprint.patternMatch!!.endIndex + 1
// If the field is true, the TextView is for a dislike button.
val isDisLikesBooleanInstruction = instructions.first { instruction ->
instruction.opcode == Opcode.IGET_BOOLEAN
} as ReferenceInstruction
val isDisLikesBooleanReference = isDisLikesBooleanInstruction.reference
// Like/Dislike button TextView field.
val textViewFieldInstruction = instructions.first { instruction ->
instruction.opcode == Opcode.IGET_OBJECT
} as ReferenceInstruction
val textViewFieldReference = textViewFieldInstruction.reference
// Check if the hooked TextView object is that of the dislike button.
// If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted.
// Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward.
addInstructionsWithLabels(
insertIndex,
"""
# Check, if the TextView is for a dislike button
iget-boolean v0, p0, $isDisLikesBooleanReference
if-eqz v0, :is_like
# Hook the TextView, if it is for the dislike button
iget-object v0, p0, $textViewFieldReference
invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setShortsDislikes(Landroid/view/View;)Z
move-result v0
if-eqz v0, :ryd_disabled
return-void
:is_like
:ryd_disabled
nop
""",
)
}
// endregion
// region Hook for litho Shorts
// region Hook Shorts
// Filter that parses the video id from the UI
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
@ -255,22 +209,25 @@ val returnYouTubeDislikePatch = bytecodePatch(
)
}
// 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.
val patternMatch = rollingNumberMeasureAnimatedTextFingerprint.patternMatch!!
// Additional check to verify the opcodes are at the start of the method
if (patternMatch.startIndex != 0) throw PatchException("Unexpected opcode location")
val endIndex = patternMatch.endIndex
rollingNumberMeasureAnimatedTextFingerprint.method.apply {
val measuredTextWidthRegister = getInstruction<OneRegisterInstruction>(endIndex).registerA
rollingNumberMeasureAnimatedTextFingerprint.let {
// 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.
val patternMatch = it.patternMatch!!
// Verify the opcodes are at the start of the method.
if (patternMatch.startIndex != 0) throw PatchException("Unexpected opcode location")
val endIndex = patternMatch.endIndex
addInstructions(
endIndex + 1,
"""
invoke-static {p1, v$measuredTextWidthRegister}, $EXTENSION_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
move-result v$measuredTextWidthRegister
""",
)
it.method.apply {
val measuredTextWidthRegister = getInstruction<OneRegisterInstruction>(endIndex).registerA
addInstructions(
endIndex + 1,
"""
invoke-static {p1, v$measuredTextWidthRegister}, $EXTENSION_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
move-result v$measuredTextWidthRegister
"""
)
}
}
// Additional text measurement method. Used if YouTube decides not to animate the likes count
@ -291,15 +248,14 @@ val returnYouTubeDislikePatch = bytecodePatch(
)
}
}
// 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.
// Initial TextView is set in this method.
val initiallyCreatedTextViewMethod = rollingNumberTextViewFingerprint.method
// 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.
arrayOf(
initiallyCreatedTextViewMethod,
// 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.
// Initial TextView is set in this method.
rollingNumberTextViewFingerprint.method,
// 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.
rollingNumberTextViewAnimationUpdateFingerprint.method,
).forEach { insertMethod ->
insertMethod.apply {
@ -315,9 +271,9 @@ val returnYouTubeDislikePatch = bytecodePatch(
addInstructions(
setTextIndex,
"""
invoke-static {v$textViewRegister, v$textSpanRegister}, $EXTENSION_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$textSpanRegister
""",
invoke-static {v$textViewRegister, v$textSpanRegister}, $EXTENSION_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$textSpanRegister
"""
)
}
}

View File

@ -16,7 +16,6 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@ -46,8 +45,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
val spoofAppVersionPatch = bytecodePatch(
name = "Spoof app version",
description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " +
"This can be used to restore old UI elements and features. " +
"Patching 19.16.39 includes additional older spoofing targets.",
"This can be used to restore old UI elements and features."
) {
dependsOn(
spoofAppVersionResourcePatch,
@ -59,7 +57,7 @@ val spoofAppVersionPatch = bytecodePatch(
compatibleWith(
"com.google.android.youtube"(
"19.16.39",
// "19.16.39", // Cannot be supported because the lowest spoof target is higher.
// "19.25.37", // Cannot be supported because the lowest spoof target is higher.
// "19.34.42", // Cannot be supported because the lowest spoof target is higher.
"19.43.41",
@ -81,19 +79,10 @@ val spoofAppVersionPatch = bytecodePatch(
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
preferences = setOf(
SwitchPreference("revanced_spoof_app_version"),
if (is_19_17_or_greater) {
ListPreference(
key = "revanced_spoof_app_version_target",
summaryKey = null,
)
} else {
ListPreference(
key = "revanced_spoof_app_version_target",
summaryKey = null,
entriesKey = "revanced_spoof_app_version_target_legacy_entries",
entryValuesKey = "revanced_spoof_app_version_target_legacy_entry_values"
)
}
ListPreference(
key = "revanced_spoof_app_version_target",
summaryKey = null,
)
)
)
)

View File

@ -143,24 +143,9 @@
<item>@string/revanced_spoof_app_version_target_entry_2</item>
</string-array>
<string-array name="revanced_spoof_app_version_target_entry_values">
<!-- Patching 19.23+ or later cannot spoof to 19.20 or lower
due to a missing library tab image resource. That can be fixed
by patching the code that loads the images and ignoring unknown images. -->
<item>19.35.36</item>
<item>19.26.42</item>
</string-array>
<string-array name="revanced_spoof_app_version_target_legacy_entries">
<item>@string/revanced_spoof_app_version_target_legacy_entry_1</item>
<item>@string/revanced_spoof_app_version_target_legacy_entry_2</item>
<item>@string/revanced_spoof_app_version_target_legacy_entry_3</item>
<item>@string/revanced_spoof_app_version_target_legacy_entry_4</item>
</string-array>
<string-array name="revanced_spoof_app_version_target_legacy_entry_values">
<item>18.33.40</item>
<item>18.20.39</item>
<item>18.09.39</item>
<item>17.33.42</item>
</string-array>
</patch>
<patch id="layout.formfactor.changeFormFactorPatch">
<string-array name="revanced_change_form_factor_entries">

View File

@ -868,7 +868,6 @@ Settings → Playback → Autoplay next video"</string>
<string name="revanced_ryd_enable_summary_on">Dislikes are shown</string>
<string name="revanced_ryd_enable_summary_off">Dislikes are not shown</string>
<string name="revanced_ryd_shorts_title">Show dislikes on Shorts</string>
<string name="revanced_ryd_shorts_summary_on">Dislikes on Shorts are shown</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Dislikes on Shorts are shown
Limitation: Dislikes may not appear in incognito mode"</string>
@ -1157,11 +1156,6 @@ If later turned off, it is recommended to clear the app data to prevent UI bugs.
<string name="revanced_spoof_app_version_target_title">Spoof app version target</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Restore old Shorts player icons</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - Restore old navigation icons</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Restore RYD on Shorts incognito mode</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Restore wide video speed &amp; quality menu</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Restore library tab</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Restore old playlist shelf</string>
</patch>
<patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">Set start page</string>