mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-04 16:44:29 +02:00
fix(YouTube/Return YouTube Dislike): prevent the first Short opened from freezing the UI
This commit is contained in:
parent
f77c62cbad
commit
fa3acf8ffd
@ -18,8 +18,10 @@ import app.revanced.patches.youtube.utils.fix.parameter.fingerprints.StoryboardR
|
||||
import app.revanced.patches.youtube.utils.fix.parameter.fingerprints.StoryboardRendererSpecRecommendedLevelFingerprint
|
||||
import app.revanced.patches.youtube.utils.fix.parameter.fingerprints.StoryboardThumbnailFingerprint
|
||||
import app.revanced.patches.youtube.utils.fix.parameter.fingerprints.StoryboardThumbnailParentFingerprint
|
||||
import app.revanced.patches.youtube.utils.playerresponse.PlayerResponsePatch
|
||||
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.utils.videoid.general.VideoIdPatch
|
||||
import app.revanced.util.integrations.Constants.MISC_PATH
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@ -29,6 +31,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
description = "Spoofs player parameters to prevent playback issues.",
|
||||
dependencies = [
|
||||
PlayerTypeHookPatch::class,
|
||||
PlayerResponsePatch::class,
|
||||
VideoIdPatch::class,
|
||||
SettingsPatch::class
|
||||
],
|
||||
compatiblePackages = [
|
||||
@ -75,19 +79,9 @@ object SpoofPlayerParameterPatch : BytecodePatch(
|
||||
/**
|
||||
* Hook player parameter
|
||||
*/
|
||||
PlayerParameterBuilderFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val videoIdRegister = 1
|
||||
val playerParameterRegister = 3
|
||||
|
||||
addInstructions(
|
||||
0, """
|
||||
invoke-static {p$videoIdRegister, p$playerParameterRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object p$playerParameterRegister
|
||||
"""
|
||||
PlayerResponsePatch += PlayerResponsePatch.Hook.PlayerParameter(
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Z)Ljava/lang/String;"
|
||||
)
|
||||
}
|
||||
} ?: throw PlayerParameterBuilderFingerprint.exception
|
||||
|
||||
/**
|
||||
* Forces the SeekBar thumbnail preview container to be shown
|
||||
|
@ -2,39 +2,58 @@ package app.revanced.patches.youtube.utils.playerresponse
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.utils.fingerprints.PlayerParameterBuilderFingerprint
|
||||
import java.io.Closeable
|
||||
|
||||
object PlayerResponsePatch : BytecodePatch(
|
||||
setOf(PlayerParameterBuilderFingerprint)
|
||||
) {
|
||||
), Closeable,MutableSet<PlayerResponsePatch.Hook> by mutableSetOf() {
|
||||
private const val VIDEO_ID_PARAMETER = 1
|
||||
private const val VIDEO_IS_OPENING_OR_PLAYING_PARAMETER = 11
|
||||
private const val PLAYER_PARAMETER = 3
|
||||
private const val IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER = 11
|
||||
|
||||
private lateinit var insertMethod: MutableMethod
|
||||
|
||||
/**
|
||||
* Adds an invoke-static instruction, called with the new id when the video changes
|
||||
* @param methodDescriptor which method to call. Params have to be `Ljava/lang/String;`
|
||||
*/
|
||||
internal fun injectCall(
|
||||
methodDescriptor: String
|
||||
) {
|
||||
insertMethod.addInstructions(
|
||||
0, // move-result-object offset
|
||||
"invoke-static {p$VIDEO_ID_PARAMETER, p$VIDEO_IS_OPENING_OR_PLAYING_PARAMETER}, $methodDescriptor"
|
||||
)
|
||||
}
|
||||
private lateinit var playerResponseMethod: MutableMethod
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
PlayerParameterBuilderFingerprint.result?.let {
|
||||
insertMethod = it.mutableMethod
|
||||
} ?: throw PlayerParameterBuilderFingerprint.exception
|
||||
|
||||
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 hookPlayerParameter(hook: Hook) = playerResponseMethod.addInstructions(
|
||||
0, """
|
||||
invoke-static {p$PLAYER_PARAMETER, p$IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER}, $hook
|
||||
move-result-object p$PLAYER_PARAMETER
|
||||
"""
|
||||
)
|
||||
|
||||
// Reverse the order in order to preserve insertion order of the hooks.
|
||||
val beforeVideoIdHooks = filterIsInstance<Hook.PlayerBeforeVideoId>().asReversed()
|
||||
val videoIdHooks = filterIsInstance<Hook.VideoId>().asReversed()
|
||||
val afterVideoIdHooks = filterIsInstance<Hook.PlayerParameter>().asReversed()
|
||||
|
||||
// Add the hooks in this specific order as they insert instructions at the beginning of the method.
|
||||
afterVideoIdHooks.forEach(::hookPlayerParameter)
|
||||
videoIdHooks.forEach(::hookVideoId)
|
||||
beforeVideoIdHooks.forEach(::hookPlayerParameter)
|
||||
}
|
||||
|
||||
internal abstract class Hook(private val methodDescriptor: String) {
|
||||
internal class VideoId(methodDescriptor: String) : Hook(methodDescriptor)
|
||||
|
||||
internal class PlayerParameter(methodDescriptor: String) : Hook(methodDescriptor)
|
||||
internal class PlayerBeforeVideoId(methodDescriptor: String) : Hook(methodDescriptor)
|
||||
|
||||
override fun toString() = methodDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,13 +101,14 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
|
||||
|
||||
TextComponentConstructorFingerprint.result?.let { parentResult ->
|
||||
// Resolves fingerprints
|
||||
val parentClassDef = parentResult.classDef
|
||||
TextComponentContextFingerprint.resolve(context, parentClassDef)
|
||||
TextComponentTmpFingerprint.resolve(context, parentClassDef)
|
||||
TextComponentAtomicReferenceFingerprint.resolve(context, parentClassDef)
|
||||
TextComponentAtomicReferenceLegacyFingerprint.resolve(context, parentClassDef)
|
||||
|
||||
TextComponentContextFingerprint.also {
|
||||
it.resolve(
|
||||
context,
|
||||
parentResult.classDef
|
||||
)
|
||||
}.result?.let {
|
||||
TextComponentContextFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val booleanIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
|
||||
@ -127,12 +128,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
}
|
||||
} ?: throw TextComponentContextFingerprint.exception
|
||||
|
||||
TextComponentTmpFingerprint.also {
|
||||
it.resolve(
|
||||
context,
|
||||
parentResult.classDef
|
||||
)
|
||||
}.result?.let {
|
||||
TextComponentTmpFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
tmpRegister =
|
||||
@ -142,17 +138,11 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
|
||||
|
||||
val textComponentAtomicReferenceResult =
|
||||
TextComponentAtomicReferenceFingerprint.also {
|
||||
it.resolve(context, parentResult.classDef)
|
||||
}.result
|
||||
?: TextComponentAtomicReferenceLegacyFingerprint.also {
|
||||
it.resolve(context, parentResult.classDef)
|
||||
}.result
|
||||
TextComponentAtomicReferenceFingerprint.result
|
||||
?: TextComponentAtomicReferenceLegacyFingerprint.result
|
||||
?: throw TextComponentAtomicReferenceLegacyFingerprint.exception
|
||||
|
||||
TextComponentAtomicReferenceFingerprint.also {
|
||||
it.resolve(context, parentResult.classDef)
|
||||
}.result?.let {
|
||||
TextComponentAtomicReferenceFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
val originalRegisterA =
|
||||
@ -196,14 +186,14 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
}
|
||||
} ?: throw TextComponentConstructorFingerprint.exception
|
||||
|
||||
VideoIdPatch.injectCall("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V")
|
||||
VideoIdPatch.injectPlayerResponseVideoId("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->preloadVideoId(Ljava/lang/String;Z)V")
|
||||
|
||||
if (SettingsPatch.upward1834) {
|
||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
PlayerResponsePatch.injectCall("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V")
|
||||
VideoIdPatch.injectPlayerResponseVideoId("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V")
|
||||
}
|
||||
|
||||
PlayerResponsePatch.injectCall("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->preloadVideoId(Ljava/lang/String;Z)V")
|
||||
VideoIdPatch.injectCall("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V")
|
||||
|
||||
/**
|
||||
* Add ReVanced Extended Settings
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.utils.fingerprints.OrganicPlaybackContextModelFingerprint
|
||||
import app.revanced.patches.youtube.utils.playerresponse.PlayerResponsePatch
|
||||
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.utils.videoid.general.fingerprint.PlayerControllerSetTimeReferenceFingerprint
|
||||
import app.revanced.patches.youtube.utils.videoid.general.fingerprint.VideoEndFingerprint
|
||||
@ -27,7 +28,12 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
@Patch(dependencies = [PlayerTypeHookPatch::class])
|
||||
@Patch(
|
||||
dependencies = [
|
||||
PlayerTypeHookPatch::class,
|
||||
PlayerResponsePatch::class
|
||||
]
|
||||
)
|
||||
object VideoIdPatch : BytecodePatch(
|
||||
setOf(
|
||||
OrganicPlaybackContextModelFingerprint,
|
||||
@ -144,8 +150,12 @@ object VideoIdPatch : BytecodePatch(
|
||||
} ?: throw VideoIdFingerprint.exception
|
||||
} ?: throw VideoIdParentFingerprint.exception
|
||||
|
||||
injectCall("$VIDEO_PATH/VideoInformation;->setVideoId(Ljava/lang/String;)V")
|
||||
|
||||
injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V")
|
||||
injectPlayerResponseVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerResponseVideoId(Ljava/lang/String;Z)V")
|
||||
// Call before any other video id hooks,
|
||||
// so they can use VideoInformation and check if the video id is for a Short.
|
||||
PlayerResponsePatch += PlayerResponsePatch.Hook.PlayerBeforeVideoId(
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->newPlayerResponseSignature(Ljava/lang/String;Z)Ljava/lang/String;")
|
||||
}
|
||||
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR = "$VIDEO_PATH/VideoInformation;"
|
||||
@ -173,6 +183,34 @@ object VideoIdPatch : BytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks the video id of every video when loaded.
|
||||
* Supports all videos and functions in all situations.
|
||||
*
|
||||
* First parameter is the video id.
|
||||
* Second parameter is if the video is a Short AND it is being opened or is currently playing.
|
||||
*
|
||||
* Hook is always called off the main thread.
|
||||
*
|
||||
* This hook is called as soon as the player response is parsed,
|
||||
* and called before many other hooks are updated such as [PlayerTypeHookPatch].
|
||||
*
|
||||
* Note: The video id returned here may not be the current video that's being played.
|
||||
* It's common for multiple Shorts to load at once in preparation
|
||||
* for the user swiping to the next Short.
|
||||
*
|
||||
* Be aware, this can be called multiple times for the same video id.
|
||||
*
|
||||
* @param methodDescriptor which method to call. Params must be `Ljava/lang/String;Z`
|
||||
*/
|
||||
internal fun injectPlayerResponseVideoId(
|
||||
methodDescriptor: String
|
||||
) {
|
||||
PlayerResponsePatch += PlayerResponsePatch.Hook.VideoId(
|
||||
methodDescriptor
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableMethod.insert(insertIndex: Int, register: String, descriptor: String) =
|
||||
addInstruction(insertIndex, "invoke-static { $register }, $descriptor")
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user