refactor(YouTube/Video information): include video quality

This commit is contained in:
inotia00
2024-04-06 05:40:59 +09:00
parent 7ba43b6f4c
commit c17709319a
11 changed files with 123 additions and 195 deletions

View File

@ -10,7 +10,6 @@ import app.revanced.util.getTargetIndexReversed
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
object AlwaysRepeatPatch : BytecodePatch( object AlwaysRepeatPatch : BytecodePatch(

View File

@ -6,7 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patches.youtube.utils.fingerprints.TotalTimeFingerprint import app.revanced.patches.youtube.utils.fingerprints.TotalTimeFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.overridequality.OverrideQualityHookPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
@ -21,7 +20,6 @@ object AppendTimeStampInformationPatch : BaseBytecodePatch(
name = "Append time stamps information", name = "Append time stamps information",
description = "Adds an option to add the current video quality or playback speed in brackets next to the current time.", description = "Adds an option to add the current video quality or playback speed in brackets next to the current time.",
dependencies = setOf( dependencies = setOf(
OverrideQualityHookPatch::class,
SettingsPatch::class, SettingsPatch::class,
SharedResourceIdPatch::class, SharedResourceIdPatch::class,
VideoInformationPatch::class VideoInformationPatch::class

View File

@ -1,119 +0,0 @@
package app.revanced.patches.youtube.utils.overridequality
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH
import app.revanced.patches.youtube.utils.overridequality.fingerprints.VideoQualityListFingerprint
import app.revanced.patches.youtube.utils.overridequality.fingerprints.VideoQualityPatchFingerprint
import app.revanced.patches.youtube.utils.overridequality.fingerprints.VideoQualityTextFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.QualityAuto
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
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.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.immutable.ImmutableField
import com.android.tools.smali.dexlib2.util.MethodUtil
@Patch(dependencies = [SharedResourceIdPatch::class])
object OverrideQualityHookPatch : BytecodePatch(
setOf(
VideoQualityListFingerprint,
VideoQualityPatchFingerprint,
VideoQualityTextFingerprint
)
) {
private const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR =
"$VIDEO_PATH/VideoQualityPatch;"
private const val INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR =
"$INTEGRATIONS_PATH/utils/VideoUtils;"
private lateinit var objectClass: String
private lateinit var objectMethod: String
override fun execute(context: BytecodeContext) {
VideoQualityListFingerprint.resultOrThrow().let {
val constructorMethod =
it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) }
val overrideMethod =
it.mutableClass.methods.find { method -> method.parameterTypes.first() == "I" }
objectClass = it.method.definingClass
objectMethod = overrideMethod?.name
?: throw PatchException("Failed to find hook method")
constructorMethod.apply {
addInstruction(
2,
"sput-object p0, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->qualityClass:$objectClass"
)
}
it.mutableMethod.apply {
val listIndex = it.scanResult.patternScanResult!!.startIndex
val listRegister = getInstruction<FiveRegisterInstruction>(listIndex).registerD
val qualityAutoIndex = getWideLiteralInstructionIndex(QualityAuto) + 2
val qualityAutoRegister =
getInstruction<OneRegisterInstruction>(qualityAutoIndex).registerA
addInstruction(
listIndex,
"invoke-static {v$listRegister}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->setVideoQualityList([Ljava/lang/Object;)V"
)
addInstruction(
qualityAutoIndex + 1,
"sput-object v$qualityAutoRegister, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->qualityAutoString:Ljava/lang/String;"
)
}
}
VideoQualityPatchFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
it.mutableClass.staticFields.add(
ImmutableField(
definingClass,
"qualityClass",
objectClass,
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
annotations,
null
).toMutable()
)
addInstructions(
0, """
sget-object v0, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->qualityClass:$objectClass
invoke-virtual {v0, p0}, $objectClass->$objectMethod(I)V
"""
)
}
}
VideoQualityTextFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val textIndex = it.scanResult.patternScanResult!!.endIndex
val textRegister = getInstruction<TwoRegisterInstruction>(textIndex).registerA
addInstruction(
textIndex + 1,
"sput-object v$textRegister, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->currentQuality:Ljava/lang/String;"
)
}
}
}
}

View File

@ -1,16 +0,0 @@
package app.revanced.patches.youtube.utils.overridequality.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH
import com.android.tools.smali.dexlib2.AccessFlags
internal object VideoQualityPatchFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("I"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "$VIDEO_PATH/VideoQualityPatch;"
&& methodDef.name == "overrideQuality"
}
)

View File

@ -6,11 +6,11 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
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.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.utils.fingerprints.PlayerButtonsResourcesFingerprint
import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.BottomControlsInflateFingerprint import app.revanced.patches.youtube.utils.playercontrols.fingerprints.BottomControlsInflateFingerprint
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.ControlsLayoutInflateFingerprint import app.revanced.patches.youtube.utils.playercontrols.fingerprints.ControlsLayoutInflateFingerprint
import app.revanced.patches.youtube.utils.fingerprints.PlayerButtonsResourcesFingerprint
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerButtonsVisibilityFingerprint import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerButtonsVisibilityFingerprint
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsPatchFingerprint import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsPatchFingerprint
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint

View File

@ -2,12 +2,12 @@ package app.revanced.patches.youtube.video.information
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction 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.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction 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.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@ -18,11 +18,13 @@ import app.revanced.patches.youtube.utils.fingerprints.OrganicPlaybackContextMod
import app.revanced.patches.youtube.utils.fingerprints.VideoEndFingerprint import app.revanced.patches.youtube.utils.fingerprints.VideoEndFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.video.information.fingerprints.OnPlaybackSpeedItemClickFingerprint import app.revanced.patches.youtube.video.information.fingerprints.OnPlaybackSpeedItemClickFingerprint
import app.revanced.patches.youtube.video.information.fingerprints.PlaybackSpeedClassFingerprint import app.revanced.patches.youtube.video.information.fingerprints.PlaybackSpeedClassFingerprint
import app.revanced.patches.youtube.video.information.fingerprints.PlayerControllerSetTimeReferenceFingerprint import app.revanced.patches.youtube.video.information.fingerprints.PlayerControllerSetTimeReferenceFingerprint
import app.revanced.patches.youtube.video.information.fingerprints.VideoInformationPatchFingerprint
import app.revanced.patches.youtube.video.information.fingerprints.VideoLengthFingerprint import app.revanced.patches.youtube.video.information.fingerprints.VideoLengthFingerprint
import app.revanced.patches.youtube.video.information.fingerprints.VideoQualityListFingerprint
import app.revanced.patches.youtube.video.information.fingerprints.VideoQualityTextFingerprint
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.getTargetIndex import app.revanced.util.getTargetIndex
@ -31,8 +33,10 @@ import app.revanced.util.getWalkerMethod
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
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
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.immutable.ImmutableField import com.android.tools.smali.dexlib2.immutable.ImmutableField
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation
@ -44,6 +48,7 @@ import com.android.tools.smali.dexlib2.util.MethodUtil
dependencies = [ dependencies = [
PlayerResponseMethodHookPatch::class, PlayerResponseMethodHookPatch::class,
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
SharedResourceIdPatch::class,
VideoIdPatch::class VideoIdPatch::class
] ]
) )
@ -54,8 +59,9 @@ object VideoInformationPatch : BytecodePatch(
PlaybackSpeedClassFingerprint, PlaybackSpeedClassFingerprint,
PlayerControllerSetTimeReferenceFingerprint, PlayerControllerSetTimeReferenceFingerprint,
VideoEndFingerprint, VideoEndFingerprint,
VideoInformationPatchFingerprint, VideoLengthFingerprint,
VideoLengthFingerprint VideoQualityListFingerprint,
VideoQualityTextFingerprint
) )
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
@ -169,8 +175,10 @@ object VideoInformationPatch : BytecodePatch(
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameterBeforeVideoId( PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameterBeforeVideoId(
"$INTEGRATIONS_CLASS_DESCRIPTOR->newPlayerResponseParameter(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;") "$INTEGRATIONS_CLASS_DESCRIPTOR->newPlayerResponseParameter(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;")
val videoInformationMutableClass = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
/** /**
* Hook the user playback speed selection * Hook current playback speed
*/ */
OnPlaybackSpeedItemClickFingerprint.resultOrThrow().let { OnPlaybackSpeedItemClickFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
@ -186,6 +194,7 @@ object VideoInformationPatch : BytecodePatch(
val setPlaybackSpeedMethodReference = val setPlaybackSpeedMethodReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference.toString() getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference.toString()
// add override playback speed method
it.mutableClass.methods.add( it.mutableClass.methods.add(
ImmutableMethod( ImmutableMethod(
definingClass, definingClass,
@ -217,8 +226,8 @@ object VideoInformationPatch : BytecodePatch(
).toMutable() ).toMutable()
) )
// set current playback speed
val walkerMethod = getWalkerMethod(context, speedSelectionValueInstructionIndex + 2) val walkerMethod = getWalkerMethod(context, speedSelectionValueInstructionIndex + 2)
walkerMethod.apply { walkerMethod.apply {
addInstruction( addInstruction(
this.implementation!!.instructions.size - 1, this.implementation!!.instructions.size - 1,
@ -233,6 +242,8 @@ object VideoInformationPatch : BytecodePatch(
val index = result.scanResult.patternScanResult!!.endIndex val index = result.scanResult.patternScanResult!!.endIndex
val register = getInstruction<OneRegisterInstruction>(index).registerA val register = getInstruction<OneRegisterInstruction>(index).registerA
val playbackSpeedClass = this.returnType val playbackSpeedClass = this.returnType
// set playback speed class
replaceInstruction( replaceInstruction(
index, index,
"sput-object v$register, $INTEGRATIONS_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass" "sput-object v$register, $INTEGRATIONS_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass"
@ -242,31 +253,109 @@ object VideoInformationPatch : BytecodePatch(
"return-object v$register" "return-object v$register"
) )
VideoInformationPatchFingerprint.resultOrThrow().let { videoInformationMutableClass.methods.single { method ->
it.mutableMethod.apply { method.name == "overridePlaybackSpeed"
it.mutableClass.staticFields.add( }.apply {
ImmutableField( // add playback speed class
definingClass, videoInformationMutableClass.staticFields.add(
"playbackSpeedClass", ImmutableField(
playbackSpeedClass, definingClass,
AccessFlags.PUBLIC or AccessFlags.STATIC, "playbackSpeedClass",
null, playbackSpeedClass,
annotations, AccessFlags.PUBLIC or AccessFlags.STATIC,
null null,
).toMutable() annotations,
) null
).toMutable()
)
addInstructions( // call override playback speed method
0, """ addInstructionsWithLabels(
sget-object v0, $INTEGRATIONS_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass 0, """
invoke-virtual {v0, p0}, $playbackSpeedClass->overridePlaybackSpeed(F)V sget-object v0, $INTEGRATIONS_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass
return-void if-eqz v0, :ignore
""" invoke-virtual {v0, p0}, $playbackSpeedClass->overridePlaybackSpeed(F)V
) :ignore
} return-void
"""
)
} }
} }
} }
/**
* Hook current video quality
*/
VideoQualityListFingerprint.resultOrThrow().let {
val constructorMethod =
it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) }
val overrideMethod =
it.mutableClass.methods.find { method -> method.parameterTypes.first() == "I" }
val videoQualityClass = it.method.definingClass
val videoQualityMethodName = overrideMethod?.name
?: throw PatchException("Failed to find hook method")
// set video quality class
constructorMethod.apply {
addInstruction(
2,
"sput-object p0, $INTEGRATIONS_CLASS_DESCRIPTOR->videoQualityClass:$videoQualityClass"
)
}
// set video quality array
it.mutableMethod.apply {
val listIndex = it.scanResult.patternScanResult!!.startIndex
val listRegister = getInstruction<FiveRegisterInstruction>(listIndex).registerD
addInstruction(
listIndex,
"invoke-static {v$listRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setVideoQualityList([Ljava/lang/Object;)V"
)
}
videoInformationMutableClass.methods.single { method ->
method.name == "overrideVideoQuality"
}.apply {
// add video quality class
videoInformationMutableClass.staticFields.add(
ImmutableField(
definingClass,
"videoQualityClass",
videoQualityClass,
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
annotations,
null
).toMutable()
)
// call override video quality method
addInstructionsWithLabels(
0, """
sget-object v0, $INTEGRATIONS_CLASS_DESCRIPTOR->videoQualityClass:$videoQualityClass
if-eqz v0, :ignore
invoke-virtual {v0, p0}, $videoQualityClass->$videoQualityMethodName(I)V
:ignore
return-void
"""
)
}
}
// set current video quality
VideoQualityTextFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val textIndex = it.scanResult.patternScanResult!!.endIndex
val textRegister = getInstruction<TwoRegisterInstruction>(textIndex).registerA
addInstruction(
textIndex + 1,
"invoke-static {v$textRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setVideoQuality(Ljava/lang/String;)V"
)
}
}
} }
private fun MutableMethod.insert(insertIndex: Int, register: String, descriptor: String) = private fun MutableMethod.insert(insertIndex: Int, register: String, descriptor: String) =

View File

@ -1,16 +0,0 @@
package app.revanced.patches.youtube.video.information.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH
import com.android.tools.smali.dexlib2.AccessFlags
internal object VideoInformationPatchFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("F"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "$VIDEO_PATH/VideoInformation;"
&& methodDef.name == "overridePlaybackSpeed"
}
)

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.utils.overridequality.fingerprints package app.revanced.patches.youtube.video.information.fingerprints
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.QualityAuto import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.QualityAuto
import app.revanced.util.fingerprint.LiteralValueFingerprint import app.revanced.util.fingerprint.LiteralValueFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.utils.overridequality.fingerprints package app.revanced.patches.youtube.video.information.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

@ -2,14 +2,12 @@ package app.revanced.patches.youtube.video.quality
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.PatchException
import app.revanced.patches.youtube.utils.fingerprints.QualityChangedFromRecyclerViewFingerprint import app.revanced.patches.youtube.utils.fingerprints.QualityChangedFromRecyclerViewFingerprint
import app.revanced.patches.youtube.utils.fingerprints.QualitySetterFingerprint import app.revanced.patches.youtube.utils.fingerprints.QualitySetterFingerprint
import app.revanced.patches.youtube.utils.fix.shortsplayback.ShortsPlaybackPatch import app.revanced.patches.youtube.utils.fix.shortsplayback.ShortsPlaybackPatch
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH
import app.revanced.patches.youtube.utils.overridequality.OverrideQualityHookPatch
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
@ -18,14 +16,12 @@ import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.copyXmlNode import app.revanced.util.copyXmlNode
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@Suppress("unused") @Suppress("unused")
object VideoQualityPatch : BaseBytecodePatch( object VideoQualityPatch : BaseBytecodePatch(
name = "Default video quality", name = "Default video quality",
description = "Adds an option to set the default video quality.", description = "Adds an option to set the default video quality.",
dependencies = setOf( dependencies = setOf(
OverrideQualityHookPatch::class,
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
SettingsPatch::class, SettingsPatch::class,
ShortsPlaybackPatch::class, ShortsPlaybackPatch::class,
@ -49,11 +45,10 @@ object VideoQualityPatch : BaseBytecodePatch(
QualityChangedFromRecyclerViewFingerprint.resultOrThrow().let { QualityChangedFromRecyclerViewFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val index = it.scanResult.patternScanResult!!.startIndex val index = it.scanResult.patternScanResult!!.startIndex
val qualityRegister = getInstruction<TwoRegisterInstruction>(index).registerA
addInstruction( addInstruction(
index + 1, index + 1,
"invoke-static {v$qualityRegister}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userChangedQuality(I)V" "invoke-static {}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userSelectedVideoQuality()V"
) )
} }
@ -64,11 +59,9 @@ object VideoQualityPatch : BaseBytecodePatch(
it.mutableClass.methods.find { method -> method.name == "onItemClick" } it.mutableClass.methods.find { method -> method.name == "onItemClick" }
onItemClickMethod?.apply { onItemClickMethod?.apply {
val listItemIndexParameter = 3
addInstruction( addInstruction(
0, 0,
"invoke-static {p$listItemIndexParameter}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userChangedQualityIndex(I)V" "invoke-static {}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userSelectedVideoQuality()V"
) )
} ?: throw PatchException("Failed to find onItemClick method") } ?: throw PatchException("Failed to find onItemClick method")
} }

View File

@ -8,10 +8,10 @@ import app.revanced.patcher.patch.BytecodePatch
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.youtube.utils.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.video.videoid.fingerprints.VideoIdFingerprint
import app.revanced.patches.youtube.video.videoid.fingerprints.VideoIdParentFingerprint
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import app.revanced.patches.youtube.video.videoid.fingerprints.VideoIdFingerprint
import app.revanced.patches.youtube.video.videoid.fingerprints.VideoIdFingerprintBackgroundPlay import app.revanced.patches.youtube.video.videoid.fingerprints.VideoIdFingerprintBackgroundPlay
import app.revanced.patches.youtube.video.videoid.fingerprints.VideoIdParentFingerprint
import app.revanced.util.getTargetIndex import app.revanced.util.getTargetIndex
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode