feat(YouTube): Support versions 18.48.39, 18.49.37 and 19.01.34 (#2551)

Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
This commit is contained in:
oSumAtrIX 2024-01-16 19:54:06 +01:00 committed by GitHub
parent 57908dbeef
commit a938e736fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
71 changed files with 362 additions and 260 deletions

View file

@ -24,15 +24,16 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"com.google.android.youtube", [
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -25,8 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -29,8 +29,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -17,15 +17,10 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"com.google.android.youtube", [
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -17,15 +17,10 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"com.google.android.youtube", [
"18.48.39",
"18.49.37",
"19.01.34"
]
),
]

View file

@ -27,8 +27,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -29,8 +29,10 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
[
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -25,8 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
[
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
],

View file

@ -1,7 +1,5 @@
package app.revanced.patches.youtube.interaction.swipecontrols
import app.revanced.util.transformMethods
import app.revanced.util.traverseClassHierarchy
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
@ -10,7 +8,9 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.SwipeControlsHostActivityFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.shared.fingerprints.WatchWhileActivityFingerprint
import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint
import app.revanced.util.transformMethods
import app.revanced.util.traverseClassHierarchy
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
@ -31,8 +31,10 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]
@ -40,19 +42,19 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
@Suppress("unused")
object SwipeControlsBytecodePatch : BytecodePatch(
setOf(
WatchWhileActivityFingerprint,
MainActivityFingerprint,
SwipeControlsHostActivityFingerprint
)
) {
override fun execute(context: BytecodeContext) {
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
val targetClass = WatchWhileActivityFingerprint.result!!.mutableClass
val targetClass = MainActivityFingerprint.result!!.mutableClass
// inject the wrapper class from integrations into the class hierarchy of WatchWhileActivity
// Inject the wrapper class from integrations into the class hierarchy of MainActivity.
wrapperClass.setSuperClass(targetClass.superclass)
targetClass.setSuperClass(wrapperClass.type)
// ensure all classes and methods in the hierarchy are non-final, so we can override them in integrations
// Ensure all classes and methods in the hierarchy are non-final, so we can override them in integrations.
context.traverseClassHierarchy(targetClass) {
accessFlags = accessFlags and AccessFlags.FINAL.value.inv()
transformMethods {

View file

@ -29,8 +29,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
],

View file

@ -27,8 +27,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -37,8 +37,10 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -28,8 +28,10 @@ import com.android.tools.smali.dexlib2.Opcode
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -34,8 +34,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -32,8 +32,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -27,8 +27,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -27,8 +27,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -26,8 +26,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -27,8 +27,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -30,8 +30,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -27,8 +27,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -23,8 +23,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -23,8 +23,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -37,8 +37,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -34,8 +34,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -23,8 +23,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -23,8 +23,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -20,15 +20,20 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
SettingsPatch::class
],
compatiblePackages = [
CompatiblePackage("com.google.android.youtube", [
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
])
CompatiblePackage(
"com.google.android.youtube", [
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]
)
@Suppress("unused")

View file

@ -25,8 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"com.google.android.youtube", [
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -31,8 +31,10 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -35,8 +35,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -22,8 +22,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -19,13 +19,14 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -24,8 +24,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -18,8 +18,10 @@ import org.w3c.dom.Element
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
],

View file

@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
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.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
@ -18,7 +17,7 @@ import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.Lik
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RemoveLikeFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberMeasureAnimatedTextFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberMeasureStaticLabelFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberMeasureTextParentFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberMeasureStaticLabelParentFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberSetterFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberTextViewFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.ShortsTextViewFingerprint
@ -55,11 +54,8 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.49.37",
"19.01.34"
]
)
]
@ -76,7 +72,8 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
DislikeFingerprint,
RemoveLikeFingerprint,
RollingNumberSetterFingerprint,
RollingNumberMeasureTextParentFingerprint,
RollingNumberMeasureStaticLabelParentFingerprint,
RollingNumberMeasureAnimatedTextFingerprint,
RollingNumberTextViewFingerprint,
RollingNumberTextViewAnimationUpdateFingerprint
)
@ -276,37 +273,30 @@ object 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.
RollingNumberMeasureAnimatedTextFingerprint.also {
if (!it.resolve(context, RollingNumberMeasureTextParentFingerprint.result!!.classDef))
throw it.exception
}.result?.also {
RollingNumberMeasureAnimatedTextFingerprint.result?.also {
val scanResult = it.scanResult.patternScanResult!!
// Additional check to verify the opcodes are at the start of the method
if (scanResult.startIndex != 0) throw PatchException("Unexpected opcode location")
val endIndex = scanResult.endIndex
it.mutableMethod.apply {
val returnInstructionIndex = it.scanResult.patternScanResult!!.endIndex
val measuredTextWidthRegister =
getInstruction<OneRegisterInstruction>(returnInstructionIndex).registerA
val measuredTextWidthRegister = getInstruction<OneRegisterInstruction>(endIndex).registerA
replaceInstruction( // Replace instruction to preserve control flow label.
returnInstructionIndex,
"invoke-static {p1, v$measuredTextWidthRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F"
)
addInstructions(
returnInstructionIndex + 1,
"""
move-result v$measuredTextWidthRegister
return v$measuredTextWidthRegister
endIndex + 1,
"""
invoke-static {p1, v$measuredTextWidthRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
move-result v$measuredTextWidthRegister
"""
)
}
} ?: throw RollingNumberMeasureAnimatedTextFingerprint.exception
// Additional text measurement method. Used if YouTube decides not to animate the likes count
// and sometimes used for initial video load.
RollingNumberMeasureStaticLabelFingerprint.also {
if (!it.resolve(context, RollingNumberMeasureTextParentFingerprint.result!!.classDef))
throw it.exception
}.result?.also {
RollingNumberMeasureStaticLabelFingerprint.resolve(context, RollingNumberMeasureStaticLabelParentFingerprint.resultOrThrow().classDef)
RollingNumberMeasureStaticLabelFingerprint.result?.also {
val measureTextIndex = it.scanResult.patternScanResult!!.startIndex + 1
it.mutableMethod.apply {
val measureTextIndex = it.scanResult.patternScanResult!!.startIndex + 1
val freeRegister = getInstruction<TwoRegisterInstruction>(0).registerA
addInstructions(

View file

@ -5,19 +5,24 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
/**
* Resolves to class found in [RollingNumberMeasureTextParentFingerprint].
*/
internal object RollingNumberMeasureAnimatedTextFingerprint : MethodFingerprint(
returnType = "F",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Ljava/lang/String;"),
returnType = "Lj\$/util/Optional;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf(
"L",
"Ljava/lang/String;",
"L"
),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.IGET, // First instruction of method
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.CONST_HIGH16,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.ADD_FLOAT_2ADDR,
Opcode.ADD_INT_LIT8,
Opcode.GOTO,
Opcode.RETURN
Opcode.CONST_4,
Opcode.AGET,
Opcode.CONST_4,
Opcode.CONST_4, // Measured text width
)
)

View file

@ -6,7 +6,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
/**
* Resolves to class found in [RollingNumberMeasureTextParentFingerprint].
* Resolves to class found in [RollingNumberMeasureStaticLabelParentFingerprint].
*/
internal object RollingNumberMeasureStaticLabelFingerprint : MethodFingerprint(
returnType = "F",

View file

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object RollingNumberMeasureTextParentFingerprint : MethodFingerprint(
internal object RollingNumberMeasureStaticLabelParentFingerprint : MethodFingerprint(
returnType = "Ljava/lang/String;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),

View file

@ -26,8 +26,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.37.36",
"18.38.44",
"18.43.45",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -23,8 +23,10 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -38,13 +38,9 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.48.39",
"18.49.37",
"19.01.34"
]
)
],

View file

@ -28,8 +28,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -24,8 +24,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -32,8 +32,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
)
)
]

View file

@ -35,8 +35,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -40,8 +40,10 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -10,7 +10,7 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.WatchWhileActivityFingerprint
import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint
import com.android.tools.smali.dexlib2.Opcode
@Patch(
@ -21,15 +21,15 @@ import com.android.tools.smali.dexlib2.Opcode
)
@Suppress("unused")
object AnnouncementsPatch : BytecodePatch(
setOf(WatchWhileActivityFingerprint)
setOf(MainActivityFingerprint)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch;"
override fun execute(context: BytecodeContext) {
val onCreateMethod = WatchWhileActivityFingerprint.result?.let {
val onCreateMethod = MainActivityFingerprint.result?.let {
it.mutableClass.methods.find { method -> method.name == "onCreate" }
} ?: throw WatchWhileActivityFingerprint.exception
} ?: throw MainActivityFingerprint.exception
val superCallIndex = onCreateMethod.getInstructions().indexOfFirst { it.opcode == Opcode.INVOKE_SUPER_RANGE }

View file

@ -28,8 +28,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -23,12 +23,15 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]
)
@Suppress("unused")
object SpoofDeviceDimensionsPatch : BytecodePatch(
setOf(DeviceDimensionsModelToStringFingerprint)
) {

View file

@ -1,6 +1,5 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
@ -10,6 +9,7 @@ import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.OnBa
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.RecyclerViewScrollingFingerprint
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.RecyclerViewTopScrollingFingerprint
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.RecyclerViewTopScrollingParentFingerprint
import app.revanced.util.exception
@Patch(description = "Fixes the swipe back to exit gesture.")
@Suppress("unused")
@ -37,7 +37,7 @@ internal object FixBackToExitGesturePatch : BytecodePatch(
methodName = "onScrollingViews"
),
OnBackPressedFingerprint to IntegrationsMethod(
"p0", "onBackPressed", "Lcom/google/android/apps/youtube/app/watchwhile/WatchWhileActivity;"
"p0", "onBackPressed", "Landroid/app/Activity;"
)
).forEach { (fingerprint, target) -> fingerprint.injectCall(target) }
}

View file

@ -12,7 +12,9 @@ internal object OnBackPressedFingerprint : MethodFingerprint(
Opcode.RETURN_VOID
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("WatchWhileActivity;")
(methodDef.definingClass.endsWith("MainActivity;") ||
// Old versions of YouTube called this class "WatchWhileActivity" instead.
methodDef.definingClass.endsWith("WatchWhileActivity;"))
&& methodDef.name == "onBackPressed"
}
)

View file

@ -10,22 +10,16 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.UserAgentHeaderBuilderFingerprint
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch(
name = "Client spoof",
description = "Adds options to spoof the client to allow video playback.",
dependencies = [SpoofSignaturePatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"com.google.android.youtube", [
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -33,13 +33,9 @@ object GmsCoreSupportPatch : AbstractGmsCoreSupportPatch(
compatiblePackages = setOf(
CompatiblePackage(
"com.google.android.youtube", setOf(
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.48.39",
"18.49.37",
"19.01.34"
)
)
),

View file

@ -25,12 +25,15 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
[
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]
)
@Suppress("unused")
object BypassURLRedirectsPatch : BytecodePatch(
setOf(ABUriParserFingerprint, HTTPUriParserFingerprint)
) {

View file

@ -28,8 +28,10 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -34,13 +34,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
CompatiblePackage(
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -30,8 +30,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
[
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -4,10 +4,12 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object WatchWhileActivityFingerprint : MethodFingerprint(
internal object MainActivityFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf(),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("WatchWhileActivity;")
methodDef.definingClass.endsWith("MainActivity;")
// Old versions of YouTube called this class "WatchWhileActivity" instead.
|| methodDef.definingClass.endsWith("WatchWhileActivity;")
}
)

View file

@ -26,8 +26,10 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -1,6 +1,5 @@
package app.revanced.patches.youtube.video.information
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
@ -14,6 +13,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.video.information.fingerprints.*
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.BuilderInstruction

View file

@ -18,29 +18,44 @@ object PlayerResponseMethodHookPatch :
BytecodePatch(setOf(PlayerParameterBuilderFingerprint)),
Closeable,
MutableSet<PlayerResponseMethodHookPatch.Hook> by mutableSetOf() {
private const val VIDEO_ID_PARAMETER = 1
private const val IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER = 11
private const val PROTO_BUFFER_PARAMETER_PARAMETER = 3
// Parameter numbers of the patched method.
private const val PARAMETER_VIDEO_ID = 1
private const val PARAMETER_PROTO_BUFFER = 3
private const val PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING = 11
// Temporary 4-bit registers used to pass the parameters to integrations.
private const val REGISTER_VIDEO_ID = 0
private const val REGISTER_PROTO_BUFFER = 1
private const val REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING = 2
private lateinit var playerResponseMethod: MutableMethod
private var numberOfInstructionsAdded = 0
override fun execute(context: BytecodeContext) {
playerResponseMethod = PlayerParameterBuilderFingerprint.result?.mutableMethod
?: throw PlayerParameterBuilderFingerprint.exception
}
override fun close() {
fun hookVideoId(hook: Hook) = playerResponseMethod.addInstruction(
0, "invoke-static {p$VIDEO_ID_PARAMETER, p$IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER}, $hook"
)
fun hookVideoId(hook: Hook) {
playerResponseMethod.addInstruction(
0, "invoke-static {v$REGISTER_VIDEO_ID, v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING}, $hook"
)
numberOfInstructionsAdded++
}
fun hookProtoBufferParameter(hook: Hook) = playerResponseMethod.addInstructions(
0,
fun hookProtoBufferParameter(hook: Hook) {
playerResponseMethod.addInstructions(
0,
"""
invoke-static {v$REGISTER_PROTO_BUFFER, v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING}, $hook
move-result-object v$REGISTER_PROTO_BUFFER
"""
invoke-static {p$PROTO_BUFFER_PARAMETER_PARAMETER, p$IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER}, $hook
move-result-object p$PROTO_BUFFER_PARAMETER_PARAMETER
"""
)
)
numberOfInstructionsAdded += 2
}
// Reverse the order in order to preserve insertion order of the hooks.
val beforeVideoIdHooks = filterIsInstance<Hook.ProtoBufferParameterBeforeVideoId>().asReversed()
@ -51,6 +66,23 @@ object PlayerResponseMethodHookPatch :
afterVideoIdHooks.forEach(::hookProtoBufferParameter)
videoIdHooks.forEach(::hookVideoId)
beforeVideoIdHooks.forEach(::hookProtoBufferParameter)
// On some app targets the method has too many registers pushing the parameters past v15.
// Move the parameters to 4-bit registers so they can be passed to integrations.
playerResponseMethod.addInstructions(
0, """
move-object/from16 v$REGISTER_VIDEO_ID, p$PARAMETER_VIDEO_ID
move-object/from16 v$REGISTER_PROTO_BUFFER, p$PARAMETER_PROTO_BUFFER
move/from16 v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING, p$PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING
""",
)
numberOfInstructionsAdded += 3
// Move the modified register back.
playerResponseMethod.addInstruction(
numberOfInstructionsAdded,
"move-object/from16 p$PARAMETER_PROTO_BUFFER, v$REGISTER_PROTO_BUFFER"
)
}
internal abstract class Hook(private val methodDescriptor: String) {

View file

@ -31,13 +31,9 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -14,13 +14,9 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]

View file

@ -29,7 +29,13 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableField
@Patch(
description = "Adds custom playback speed options.",
dependencies = [IntegrationsPatch::class, LithoFilterPatch::class, SettingsPatch::class, RecyclerViewTreeHookPatch::class]
dependencies = [
IntegrationsPatch::class,
LithoFilterPatch::class,
SettingsPatch::class,
RecyclerViewTreeHookPatch::class,
CustomPlaybackSpeedResourcePatch::class
]
)
object CustomPlaybackSpeedPatch : BytecodePatch(
setOf(

View file

@ -0,0 +1,15 @@
package app.revanced.patches.youtube.video.speed.custom
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
internal object CustomPlaybackSpeedResourcePatch : ResourcePatch() {
var speedUnavailableId: Long = -1
override fun execute(context: ResourceContext) {
speedUnavailableId = ResourceMappingPatch.resourceMappings.single {
it.type == "string" && it.name == "varispeed_unavailable_message"
}.id
}
}

View file

@ -1,7 +1,10 @@
package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.video.speed.custom.CustomPlaybackSpeedResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
internal object ShowOldPlaybackSpeedMenuFingerprint : MethodFingerprint(
strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT")
internal object ShowOldPlaybackSpeedMenuFingerprint : LiteralValueFingerprint(
literalSupplier = {
CustomPlaybackSpeedResourcePatch.speedUnavailableId
}
)

View file

@ -1,6 +1,5 @@
package app.revanced.patches.youtube.video.videoid
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@ -13,6 +12,7 @@ import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import app.revanced.patches.youtube.video.videoid.fingerprint.VideoIdFingerprint
import app.revanced.patches.youtube.video.videoid.fingerprint.VideoIdFingerprintBackgroundPlay
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@ -49,7 +49,7 @@ object VideoIdPatch : BytecodePatch(
consumer(it, insertIndex, videoIdRegister)
}
} ?: throw VideoIdFingerprint.exception
} ?: throw exception
VideoIdFingerprint.setFields { method, index, register ->
videoIdMethod = method

View file

@ -10,19 +10,13 @@ internal object VideoIdFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"),
opcodes = listOf(
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT
Opcode.MOVE_RESULT_OBJECT,
)
)

View file

@ -10,18 +10,10 @@ internal object VideoIdFingerprintBackgroundPlay : MethodFingerprint(
accessFlags = AccessFlags.DECLARED_SYNCHRONIZED or AccessFlags.FINAL or AccessFlags.PUBLIC,
parameters = listOf("L"),
opcodes = listOf(
Opcode.MONITOR_EXIT,
Opcode.RETURN_VOID,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.NEW_ARRAY,
Opcode.SGET_OBJECT,
Opcode.APUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,

View file

@ -30,8 +30,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
"18.45.43"
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34"
]
)
]