chore: remove obsolete code

This commit is contained in:
inotia00
2024-09-25 21:44:05 +09:00
parent 42d284654e
commit 0752ff0d72
31 changed files with 492 additions and 540 deletions

View File

@ -19,6 +19,7 @@ import app.revanced.patches.youtube.utils.pip.PiPStateHookPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.alsoResolve
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch
@ -87,23 +88,22 @@ object DownloadActionsPatch : BaseBytecodePatch(
?: throw PatchException("Could not find onClickListenerClass")
}
context.findClass(onClickListenerClass)
?.mutableClass
?.methods
?.first { method -> method.name == "onClick" }?.apply {
val insertIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_STATIC
&& getReference<MethodReference>()?.name == "isEmpty"
}
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
context.findMethodOrThrow(onClickListenerClass) {
name == "onClick"
}.apply {
val insertIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_STATIC
&& getReference<MethodReference>()?.name == "isEmpty"
}
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
addInstructions(
insertIndex, """
invoke-static {v$insertRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppPlaylistDownloadButtonOnClick(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$insertRegister
"""
)
} ?: throw PatchException("Could not find class $onClickListenerClass")
addInstructions(
insertIndex, """
invoke-static {v$insertRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppPlaylistDownloadButtonOnClick(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$insertRegister
"""
)
}
OfflinePlaylistEndpointFingerprint.resultOrThrow().mutableMethod.apply {
val playlistIdParameter = parameterTypes.indexOf("Ljava/lang/String;") + 1

View File

@ -11,6 +11,7 @@ import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_PATH
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addEntryValues
import app.revanced.patches.youtube.utils.settings.SettingsBytecodePatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch
@ -39,13 +40,15 @@ object YouTubeMusicActionsPatch : BaseBytecodePatch(
AppDeepLinkFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val packageNameIndex = it.scanResult.patternScanResult!!.startIndex
val packageNameField = getInstruction<ReferenceInstruction>(packageNameIndex).reference.toString()
val packageNameField =
getInstruction<ReferenceInstruction>(packageNameIndex).reference.toString()
implementation!!.instructions
.withIndex()
.filter { (_, instruction) ->
instruction.opcode == Opcode.IGET_OBJECT &&
instruction.getReference<FieldReference>()?.toString() == packageNameField
instruction.getReference<FieldReference>()
?.toString() == packageNameField
}
.map { (index, _) -> index }
.reversed()
@ -78,30 +81,28 @@ object YouTubeMusicActionsPatch : BaseBytecodePatch(
override fun close() {
if (SettingsPatch.containsPatch("GmsCore support")) {
val musicPackageName = PackageNameYouTubeMusic.valueOrThrow()
SettingsPatch.contexts.addEntryValues(
"revanced_third_party_youtube_music_label",
"RVX Music"
)
SettingsPatch.contexts.addEntryValues(
"revanced_third_party_youtube_music_package_name",
PackageNameYouTubeMusic.valueOrThrow()
musicPackageName
)
SettingsBytecodePatch.contexts
.findClass { classDef -> classDef.type == INTEGRATIONS_CLASS_DESCRIPTOR }
?.mutableClass
?.methods
?.first { method -> method.name == "getRVXMusicPackageName" }
?.apply {
val replaceIndex = indexOfFirstInstructionOrThrow(Opcode.CONST_STRING)
val replaceRegister =
getInstruction<OneRegisterInstruction>(replaceIndex).registerA
SettingsBytecodePatch.contexts.findMethodOrThrow(INTEGRATIONS_CLASS_DESCRIPTOR) {
name == "getRVXMusicPackageName"
}.apply {
val replaceIndex = indexOfFirstInstructionOrThrow(Opcode.CONST_STRING)
val replaceRegister =
getInstruction<OneRegisterInstruction>(replaceIndex).registerA
replaceInstruction(
replaceIndex,
"const-string v$replaceRegister, \"${PackageNameYouTubeMusic.valueOrThrow()}\""
)
}
replaceInstruction(
replaceIndex,
"const-string v$replaceRegister, \"$musicPackageName\""
)
}
}
}

View File

@ -89,12 +89,12 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
AutoMotiveFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = indexOfFirstStringInstructionOrThrow("Android Automotive") - 1
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex, """
invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->switchCreateWithNotificationButton(Z)Z
move-result v$register
invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->switchCreateWithNotificationButton(Z)Z
move-result v$insertRegister
"""
)
}

View File

@ -41,6 +41,7 @@ import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.util.alsoResolve
import app.revanced.util.doRecursively
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow
@ -114,8 +115,8 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
val attributeResolverMethodCall =
attributeResolverMethod.definingClass + "->" + attributeResolverMethod.name + "(Landroid/content/Context;I)Landroid/graphics/drawable/Drawable;"
context.findClass(GENERAL_CLASS_DESCRIPTOR)!!.mutableClass.methods.single { method ->
method.name == "getHeaderDrawable"
context.findMethodOrThrow(GENERAL_CLASS_DESCRIPTOR) {
name == "getHeaderDrawable"
}.addInstructions(
0, """
invoke-static {p0, p1}, $attributeResolverMethodCall
@ -381,15 +382,14 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
ToolBarHookPatch.hook("$GENERAL_CLASS_DESCRIPTOR->replaceCreateButton")
val settingsClass = context.findClass("Shell_SettingsActivity")
?: throw PatchException("Shell_SettingsActivity class not found.")
settingsClass.mutableClass.methods.find { it.name == "onCreate" }?.apply {
addInstruction(
0,
"invoke-static {p0}, $GENERAL_CLASS_DESCRIPTOR->setShellActivityTheme(Landroid/app/Activity;)V"
)
} ?: throw PatchException("onCreate method not found.")
context.findMethodOrThrow(
"Lcom/google/android/apps/youtube/app/application/Shell_SettingsActivity;"
) {
name == "onCreate"
}.addInstruction(
0,
"invoke-static {p0}, $GENERAL_CLASS_DESCRIPTOR->setShellActivityTheme(Landroid/app/Activity;)V"
)
// endregion

View File

@ -141,7 +141,10 @@ object ChangeHeaderPatch : BaseResourcePatch(
}
if (customBrandingIconType == "youtube_minimal_header") {
SettingsBytecodePatch.contexts.updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "MinimalHeader")
SettingsBytecodePatch.contexts.updatePatchStatus(
PATCH_STATUS_CLASS_DESCRIPTOR,
"MinimalHeader"
)
}
} else {
println(warnings)

View File

@ -3,13 +3,13 @@ package app.revanced.patches.youtube.player.ambientmode
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.PatchException
import app.revanced.patches.youtube.player.ambientmode.fingerprints.AmbientModeInFullscreenFingerprint
import app.revanced.patches.youtube.player.ambientmode.fingerprints.PowerSaveModeBroadcastReceiverFingerprint
import app.revanced.patches.youtube.player.ambientmode.fingerprints.PowerSaveModeSyntheticFingerprint
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.findMethodOrThrow
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.indexOfFirstStringInstructionOrThrow
@ -19,7 +19,6 @@ import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
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.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused")
@ -60,27 +59,30 @@ object AmbientModeSwitchPatch : BaseBytecodePatch(
}
syntheticClassList.distinct().forEach { className ->
context.findClass(className)?.mutableClass?.methods?.first { method ->
method.name == "accept"
}?.apply {
for (index in implementation!!.instructions.size - 1 downTo 0) {
val instruction = getInstruction(index)
if (instruction.opcode != Opcode.INVOKE_VIRTUAL)
continue
context.findMethodOrThrow(className) {
name == "accept"
}.apply {
implementation!!.instructions
.withIndex()
.filter { (_, instruction) ->
val reference = (instruction as? ReferenceInstruction)?.reference
instruction.opcode == Opcode.INVOKE_VIRTUAL &&
reference is MethodReference &&
reference.name == "isPowerSaveMode"
}
.map { (index, _) -> index }
.reversed()
.forEach { index ->
val register = getInstruction<OneRegisterInstruction>(index + 1).registerA
if (((instruction as Instruction35c).reference as MethodReference).name != "isPowerSaveMode")
continue
val register = getInstruction<OneRegisterInstruction>(index + 1).registerA
addInstructions(
index + 2, """
invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->bypassAmbientModeRestrictions(Z)Z
move-result v$register
"""
)
}
} ?: throw PatchException("Could not find $className")
addInstructions(
index + 2, """
invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->bypassAmbientModeRestrictions(Z)Z
move-result v$register
"""
)
}
}
}
// endregion

View File

@ -48,6 +48,7 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TapBl
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
@ -146,15 +147,13 @@ object PlayerComponentsPatch : BaseBytecodePatch(
hookInitVideoPanel(1)
} else {
val syntheticIndex =
indexOfFirstInstructionOrThrow(opcode = Opcode.NEW_INSTANCE)
indexOfFirstInstructionOrThrow(Opcode.NEW_INSTANCE)
val syntheticReference =
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
val syntheticClass =
context.findClass(syntheticReference)!!.mutableClass
syntheticClass.methods.find { method -> method.name == "onClick" }
?.hookInitVideoPanel(0)
?: throw PatchException("Could not find onClick method in $syntheticReference")
context.findMethodOrThrow(syntheticReference) {
name == "onClick"
}.hookInitVideoPanel(0)
}
}
}

View File

@ -29,6 +29,7 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AutoN
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullScreenEngagementPanel
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.QuickActionsElementContainer
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow
@ -253,18 +254,16 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
val invokeIndex =
indexOfFirstInstructionOrThrow(stringIndex, Opcode.INVOKE_INTERFACE)
val targetIndex = indexOfFirstInstructionOrThrow(invokeIndex, Opcode.CHECK_CAST)
val targetClass = context
.findClass(getInstruction<ReferenceInstruction>(targetIndex).reference.toString())!!
.mutableClass
val targetClass =
getInstruction<ReferenceInstruction>(targetIndex).reference.toString()
// add an instruction to check the vertical video
targetClass.methods.find { method -> method.parameters == listOf("I", "I", "Z") }
?.apply {
addInstruction(
1,
"invoke-static {p1, p2}, $PLAYER_CLASS_DESCRIPTOR->setVideoPortrait(II)V"
)
} ?: throw PatchException("Could not find targetMethod")
context.findMethodOrThrow(targetClass) {
parameters == listOf("I", "I", "Z")
}.addInstruction(
1,
"invoke-static {p1, p2}, $PLAYER_CLASS_DESCRIPTOR->setVideoPortrait(II)V"
)
}
}
@ -281,14 +280,11 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
}
val walkerMethod = getWalkerMethod(context, walkerIndex)
val targetClass =
context.findClass(walkerMethod.definingClass)!!.mutableClass
val constructorMethod = targetClass
.methods
.find { method ->
method.name == "<init>"
&& method.parameterTypes == listOf("Landroid/app/Activity;")
} ?: throw PatchException("Constructor method not found!")
val constructorMethod =
context.findMethodOrThrow(walkerMethod.definingClass) {
name == "<init>" &&
parameterTypes == listOf("Landroid/app/Activity;")
}
arrayOf(
walkerMethod,

View File

@ -30,6 +30,7 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelT
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.util.findMethodsOrThrow
import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow
@ -38,8 +39,6 @@ import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c
import com.android.tools.smali.dexlib2.dexbacked.reference.DexBackedMethodReference
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -84,14 +83,15 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
SeekbarTappingFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val tapSeekIndex = it.scanResult.patternScanResult!!.startIndex + 1
val tapSeekReference = getInstruction<BuilderInstruction35c>(tapSeekIndex).reference
val tapSeekClass =
context
.findClass((tapSeekReference as DexBackedMethodReference).definingClass)!!
.mutableClass
val tapSeekMethods = mutableMapOf<String, MutableMethod>()
val tapSeekClass = getInstruction(tapSeekIndex)
.getReference<MethodReference>()!!
.definingClass
for (method in tapSeekClass.methods) {
val tapSeekMethods = context.findMethodsOrThrow(tapSeekClass)
var pMethodCall = ""
var oMethodCall = ""
for (method in tapSeekMethods) {
if (method.implementation == null)
continue
@ -110,15 +110,17 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
// method founds
if (literal == 1)
tapSeekMethods["P"] = method
pMethodCall = "${method.definingClass}->${method.name}(I)V"
else if (literal == 2)
tapSeekMethods["O"] = method
oMethodCall = "${method.definingClass}->${method.name}(I)V"
}
val pMethod = tapSeekMethods["P"]
?: throw PatchException("pMethod not found")
val oMethod = tapSeekMethods["O"]
?: throw PatchException("oMethod not found")
if (pMethodCall.isEmpty()) {
throw PatchException("pMethod not found")
}
if (oMethodCall.isEmpty()) {
throw PatchException("oMethod not found")
}
val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2
@ -127,8 +129,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSeekbarTapping()Z
move-result v0
if-eqz v0, :disabled
invoke-virtual { p0, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V
invoke-virtual { p0, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V
invoke-virtual { p0, v2 }, $pMethodCall
invoke-virtual { p0, v2 }, $oMethodCall
""", ExternalLabel("disabled", getInstruction(insertIndex))
)
}

View File

@ -6,7 +6,6 @@ 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.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
@ -20,7 +19,9 @@ import app.revanced.patches.youtube.player.speedoverlay.fingerprints.SpeedOverla
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.alsoResolve
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.injectLiteralInstructionBooleanCall
@ -33,7 +34,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.util.MethodUtil
@Patch(dependencies = [SharedResourceIdPatch::class])
object SpeedOverlayPatch : BytecodePatch(
@ -135,16 +135,11 @@ object SpeedOverlayPatch : BytecodePatch(
hook(insertIndex, insertRegister, jumpIndex)
val slideToSeekBooleanMethod = context.toMethodWalker(it.mutableMethod)
.nextMethod(scanResult.startIndex + 1, true)
.getMethod() as MutableMethod
val slideToSeekBooleanMethod =
getWalkerMethod(context, scanResult.startIndex + 1)
val slideToSeekConstructorMethod =
context.findClass { classDef -> classDef.type == slideToSeekBooleanMethod.definingClass }
?.mutableClass
?.methods
?.find { method -> MethodUtil.isConstructor(method) }
?: throw PatchException("Could not find constructor method")
context.findMethodOrThrow(slideToSeekBooleanMethod.definingClass)
val slideToSeekSyntheticIndex = slideToSeekConstructorMethod
.indexOfFirstInstructionReversedOrThrow {
@ -157,11 +152,9 @@ object SpeedOverlayPatch : BytecodePatch(
.toString()
val slideToSeekSyntheticMethod =
context.findClass { classDef -> classDef.type == slideToSeekSyntheticClass }
?.mutableClass
?.methods
?.find { method -> method.name == "run" }
?: throw PatchException("Could not find synthetic method")
context.findMethodOrThrow(slideToSeekSyntheticClass) {
name == "run"
}
Pair(slideToSeekBooleanMethod, slideToSeekSyntheticMethod)
}

View File

@ -6,7 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
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.MutableMethod
import app.revanced.patches.youtube.utils.castbutton.fingerprints.MenuItemInitializeFingerprint
@ -18,6 +17,7 @@ import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DE
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.alsoResolve
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow
@ -50,17 +50,14 @@ object CastButtonPatch : BytecodePatch(
playerButtonMethod = PlayerButtonFingerprint.resultOrThrow().mutableMethod
val buttonClass = context.findClass("MediaRouteButton")
?: throw PatchException("MediaRouteButton class not found.")
buttonClass.mutableClass.methods.find { it.name == "setVisibility" }?.apply {
addInstructions(
0, """
invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideCastButton(I)I
move-result p1
"""
)
} ?: throw PatchException("setVisibility method not found.")
context.findMethodOrThrow("Landroidx/mediarouter/app/MediaRouteButton;") {
name == "setVisibility"
}.addInstructions(
0, """
invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideCastButton(I)I
move-result p1
"""
)
}

View File

@ -7,7 +7,7 @@ import app.revanced.patches.youtube.utils.fingerprints.PlaybackRateBottomSheetBu
import app.revanced.patches.youtube.utils.flyoutmenu.fingerprints.VideoQualityBottomSheetClassFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.addFieldAndInstructions
import app.revanced.util.addStaticFieldToIntegration
import app.revanced.util.resultOrThrow
@Patch(
@ -25,10 +25,6 @@ object FlyoutMenuHookPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
val videoUtilsMutableClass = context.findClass(
INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR
)!!.mutableClass
PlaybackRateBottomSheetBuilderFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val smaliInstructions =
@ -39,13 +35,12 @@ object FlyoutMenuHookPatch : BytecodePatch(
return-void
"""
videoUtilsMutableClass.addFieldAndInstructions(
context,
context.addStaticFieldToIntegration(
INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR,
"showPlaybackSpeedFlyoutMenu",
"playbackRateBottomSheetClass",
definingClass,
smaliInstructions,
true
smaliInstructions
)
}
}
@ -61,13 +56,12 @@ object FlyoutMenuHookPatch : BytecodePatch(
return-void
"""
videoUtilsMutableClass.addFieldAndInstructions(
context,
context.addStaticFieldToIntegration(
INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR,
"showVideoQualityFlyoutMenu",
"videoQualityBottomSheetClass",
definingClass,
smaliInstructions,
true
smaliInstructions
)
}
}

View File

@ -3,11 +3,11 @@ package app.revanced.patches.youtube.utils.lottie
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.lottie.fingerprints.SetAnimationFingerprint
import app.revanced.patches.youtube.utils.lottie.fingerprints.SetAnimationFingerprint.LOTTIE_ANIMATION_VIEW_CLASS_DESCRIPTOR
import app.revanced.util.findMethodOrThrow
import app.revanced.util.resultOrThrow
@Patch(
@ -20,21 +20,15 @@ object LottieAnimationViewHookPatch : BytecodePatch(
"$UTILS_PATH/LottieAnimationViewPatch;"
override fun execute(context: BytecodeContext) {
val setAnimationMethodName = SetAnimationFingerprint.resultOrThrow().mutableMethod.name
val setAnimationCall = "invoke-virtual {p0, p1}, " +
LOTTIE_ANIMATION_VIEW_CLASS_DESCRIPTOR +
"->" +
setAnimationMethodName +
"(I)V"
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)
?.mutableClass
?.methods
?.first { method -> method.name == "setAnimation" }
?.addInstruction(
0,
setAnimationCall
) ?: throw PatchException("Could not find setAnimation method")
context.findMethodOrThrow(INTEGRATIONS_CLASS_DESCRIPTOR) {
name == "setAnimation"
}.addInstruction(
0,
"invoke-virtual {p0, p1}, " +
LOTTIE_ANIMATION_VIEW_CLASS_DESCRIPTOR +
"->" +
SetAnimationFingerprint.resultOrThrow().mutableMethod.name +
"(I)V"
)
}
}

View File

@ -18,6 +18,7 @@ import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarButton
import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarConstructorFingerprint
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
@ -115,9 +116,9 @@ object NavigationBarHookPatch : BytecodePatch(
}
navigationTabCreatedCallback =
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
method.name == "navigationTabCreatedCallback"
} ?: throw PatchException("Could not find navigationTabCreatedCallback method")
context.findMethodOrThrow(INTEGRATIONS_CLASS_DESCRIPTOR) {
name == "navigationTabCreatedCallback"
}
MainActivityResolvePatch.injectOnBackPressedMethodCall(
INTEGRATIONS_CLASS_DESCRIPTOR,

View File

@ -17,6 +17,7 @@ import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerCont
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.alsoResolve
import app.revanced.util.findMethodOrThrow
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
@ -115,28 +116,25 @@ object PlayerControlsPatch : BytecodePatch(
// region set methods to inject into integration
val playerControlsMutableClass =
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
changeVisibilityMethod =
playerControlsMutableClass.methods.single { method ->
method.name == "changeVisibility"
&& method.parameters == listOf("Z", "Z")
context.findMethodOrThrow(INTEGRATIONS_CLASS_DESCRIPTOR) {
name == "changeVisibility"
&& parameters == listOf("Z", "Z")
}
changeVisibilityNegatedImmediatelyMethod =
playerControlsMutableClass.methods.single { method ->
method.name == "changeVisibilityNegatedImmediately"
context.findMethodOrThrow(INTEGRATIONS_CLASS_DESCRIPTOR) {
name == "changeVisibilityNegatedImmediately"
}
initializeBottomControlButtonMethod =
playerControlsMutableClass.methods.single { method ->
method.name == "initializeBottomControlButton"
context.findMethodOrThrow(INTEGRATIONS_CLASS_DESCRIPTOR) {
name == "initializeBottomControlButton"
}
initializeTopControlButtonMethod =
playerControlsMutableClass.methods.single { method ->
method.name == "initializeTopControlButton"
context.findMethodOrThrow(INTEGRATIONS_CLASS_DESCRIPTOR) {
name == "initializeTopControlButton"
}
// endregion

View File

@ -15,7 +15,10 @@ import app.revanced.patches.youtube.utils.playertype.fingerprint.BrowseIdClassFi
import app.revanced.patches.youtube.utils.playertype.fingerprint.PlayerTypeFingerprint
import app.revanced.patches.youtube.utils.playertype.fingerprint.VideoStateFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.addFieldAndInstructions
import app.revanced.util.addStaticFieldToIntegration
import app.revanced.util.alsoResolve
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.resultOrThrow
@ -57,22 +60,20 @@ object PlayerTypeHookPatch : BytecodePatch(
// region patch for set video state
YouTubeControlsOverlayFingerprint.resultOrThrow().let { parentResult ->
VideoStateFingerprint.also {
it.resolve(context, parentResult.classDef)
}.resultOrThrow().let {
it.mutableMethod.apply {
val endIndex = it.scanResult.patternScanResult!!.endIndex
val videoStateFieldName =
getInstruction<ReferenceInstruction>(endIndex).reference
VideoStateFingerprint.alsoResolve(
context, YouTubeControlsOverlayFingerprint
).let {
it.mutableMethod.apply {
val endIndex = it.scanResult.patternScanResult!!.endIndex
val videoStateFieldName =
getInstruction<ReferenceInstruction>(endIndex).reference
addInstructions(
0, """
iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field
invoke-static {v0}, $INTEGRATIONS_PLAYER_TYPE_HOOK_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V
"""
)
}
addInstructions(
0, """
iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field
invoke-static {v0}, $INTEGRATIONS_PLAYER_TYPE_HOOK_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V
"""
)
}
}
@ -83,39 +84,36 @@ object PlayerTypeHookPatch : BytecodePatch(
BrowseIdClassFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val targetIndex = indexOfFirstStringInstructionOrThrow("VL") - 1
val targetReference = getInstruction<ReferenceInstruction>(targetIndex).reference
val targetClass =
context.findClass((targetReference as FieldReference).definingClass)!!.mutableClass
val targetClass = getInstruction(targetIndex)
.getReference<FieldReference>()
?.definingClass
?: throw PatchException("Could not find browseId class")
targetClass.methods.find { method -> method.name == "<init>" }
?.apply {
val browseIdFieldIndex = indexOfFirstInstructionOrThrow(Opcode.IPUT_OBJECT)
val browseIdFieldName =
(getInstruction<ReferenceInstruction>(browseIdFieldIndex).reference as FieldReference).name
context.findMethodOrThrow(targetClass).apply {
val browseIdFieldReference = getInstruction<ReferenceInstruction>(
indexOfFirstInstructionOrThrow(Opcode.IPUT_OBJECT)
).reference
val browseIdFieldName = (browseIdFieldReference as FieldReference).name
val smaliInstructions =
val smaliInstructions =
"""
if-eqz v0, :ignore
iget-object v0, v0, $definingClass->$browseIdFieldName:Ljava/lang/String;
if-eqz v0, :ignore
return-object v0
:ignore
const-string v0, ""
return-object v0
"""
if-eqz v0, :ignore
iget-object v0, v0, $definingClass->$browseIdFieldName:Ljava/lang/String;
if-eqz v0, :ignore
return-object v0
:ignore
const-string v0, ""
return-object v0
"""
val rootViewMutableClass =
context.findClass(INTEGRATIONS_ROOT_VIEW_HOOK_CLASS_DESCRIPTOR)!!.mutableClass
rootViewMutableClass.addFieldAndInstructions(
context,
"getBrowseId",
"browseIdClass",
definingClass,
smaliInstructions,
true
)
} ?: throw PatchException("BrowseIdClass not found!")
context.addStaticFieldToIntegration(
INTEGRATIONS_ROOT_VIEW_HOOK_CLASS_DESCRIPTOR,
"getBrowseId",
"browseIdClass",
definingClass,
smaliInstructions
)
}
}
}

View File

@ -6,7 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.utils.fingerprints.RollingNumberTextViewAnimationUpdateFingerprint
@ -17,6 +16,8 @@ import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fin
import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberMeasureTextParentFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberSetterFingerprint
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.alsoResolve
import app.revanced.util.findMethodOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow
@ -26,7 +27,6 @@ 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.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.reference.Reference
@Patch(dependencies = [SettingsPatch::class])
object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
@ -47,130 +47,115 @@ object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
* In order to maintain compatibility with YouTube v18.48.39 or previous versions,
* This patch is applied only to the version after YouTube v18.49.37
*/
if (SettingsPatch.upward1849) {
if (!SettingsPatch.upward1849) {
return
}
RollingNumberSetterFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex
val rollingNumberClassReference =
getInstruction<ReferenceInstruction>(rollingNumberClassIndex).reference
val rollingNumberClass =
context.findClass(rollingNumberClassReference.toString())!!.mutableClass
RollingNumberSetterFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex
val rollingNumberClassReference =
getInstruction<ReferenceInstruction>(rollingNumberClassIndex).reference.toString()
val rollingNumberConstructorMethod =
context.findMethodOrThrow(rollingNumberClassReference)
val charSequenceFieldReference = with(rollingNumberConstructorMethod) {
getInstruction<ReferenceInstruction>(
indexOfFirstInstructionOrThrow(Opcode.IPUT_OBJECT)
).reference
}
lateinit var charSequenceFieldReference: Reference
val insertIndex = rollingNumberClassIndex + 1
val charSequenceInstanceRegister =
getInstruction<OneRegisterInstruction>(rollingNumberClassIndex).registerA
val registerCount = implementation!!.registerCount
rollingNumberClass.methods.find { method -> method.name == "<init>" }
?.apply {
val rollingNumberFieldIndex =
indexOfFirstInstructionOrThrow(opcode = Opcode.IPUT_OBJECT)
charSequenceFieldReference =
getInstruction<ReferenceInstruction>(rollingNumberFieldIndex).reference
} ?: throw PatchException("RollingNumberClass not found!")
// This register is being overwritten, so it is free to use.
val freeRegister = registerCount - 1
val conversionContextRegister = registerCount - parameters.size + 1
val insertIndex = rollingNumberClassIndex + 1
val charSequenceInstanceRegister =
getInstruction<OneRegisterInstruction>(rollingNumberClassIndex).registerA
val registerCount = implementation!!.registerCount
// This register is being overwritten, so it is free to use.
val freeRegister = registerCount - 1
val conversionContextRegister = registerCount - parameters.size + 1
addInstructions(
insertIndex, """
addInstructions(
insertIndex, """
iget-object v$freeRegister, v$charSequenceInstanceRegister, $charSequenceFieldReference
invoke-static {v$conversionContextRegister, v$freeRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberLoaded(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;
move-result-object v$freeRegister
iput-object v$freeRegister, v$charSequenceInstanceRegister, $charSequenceFieldReference
"""
)
}
)
}
}
// 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.resultOrThrow().let {
it.mutableMethod.apply {
val endIndex = it.scanResult.patternScanResult!!.endIndex
val measuredTextWidthIndex = endIndex - 2
val measuredTextWidthRegister =
getInstruction<TwoRegisterInstruction>(measuredTextWidthIndex).registerA
// 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.resultOrThrow().let {
it.mutableMethod.apply {
val endIndex = it.scanResult.patternScanResult!!.endIndex
val measuredTextWidthIndex = endIndex - 2
val measuredTextWidthRegister =
getInstruction<TwoRegisterInstruction>(measuredTextWidthIndex).registerA
addInstructions(
endIndex + 1, """
invoke-static {p1, v$measuredTextWidthRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
move-result v$measuredTextWidthRegister
"""
)
addInstructions(
endIndex + 1, """
invoke-static {p1, v$measuredTextWidthRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
move-result v$measuredTextWidthRegister
"""
)
val ifGeIndex = indexOfFirstInstructionOrThrow(opcode = Opcode.IF_GE)
val ifGeInstruction = getInstruction<TwoRegisterInstruction>(ifGeIndex)
val ifGeIndex = indexOfFirstInstructionOrThrow(opcode = Opcode.IF_GE)
val ifGeInstruction = getInstruction<TwoRegisterInstruction>(ifGeIndex)
removeInstruction(ifGeIndex)
addInstructionsWithLabels(
ifGeIndex, """
if-ge v${ifGeInstruction.registerA}, v${ifGeInstruction.registerB}, :jump
""", ExternalLabel("jump", getInstruction(endIndex))
)
}
removeInstruction(ifGeIndex)
addInstructionsWithLabels(
ifGeIndex, """
if-ge v${ifGeInstruction.registerA}, v${ifGeInstruction.registerB}, :jump
""", ExternalLabel("jump", getInstruction(endIndex))
)
}
}
RollingNumberMeasureTextParentFingerprint.resultOrThrow().classDef.let { parentClassDef ->
RollingNumberMeasureStaticLabelFingerprint.resolve(context, parentClassDef)
RollingNumberMeasureStaticLabelFingerprint.alsoResolve(
context,
RollingNumberMeasureTextParentFingerprint
).let {
it.mutableMethod.apply {
val measureTextIndex = it.scanResult.patternScanResult!!.startIndex + 1
val freeRegister = getInstruction<TwoRegisterInstruction>(0).registerA
// Additional text measurement method. Used if YouTube decides not to animate the likes count
// and sometimes used for initial video load.
RollingNumberMeasureStaticLabelFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val measureTextIndex = it.scanResult.patternScanResult!!.startIndex + 1
val freeRegister = getInstruction<TwoRegisterInstruction>(0).registerA
addInstructions(
measureTextIndex + 1, """
move-result v$freeRegister
invoke-static {p1, v$freeRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
"""
)
}
}
addInstructions(
measureTextIndex + 1, """
move-result v$freeRegister
invoke-static {p1, v$freeRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
"""
)
}
}
// 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.
RollingNumberTextViewFingerprint.resultOrThrow().let { parentResult ->
// Initial TextView is set in this method.
val initiallyCreatedTextViewMethod = parentResult.mutableMethod
// 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.
arrayOf(
// Initial TextView is set in this method.
RollingNumberTextViewFingerprint
.resultOrThrow(),
// Video 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.
val realTimeUpdateTextViewMethod =
RollingNumberTextViewAnimationUpdateFingerprint.also {
it.resolve(context, parentResult.classDef)
}.resultOrThrow().mutableMethod
arrayOf(
initiallyCreatedTextViewMethod,
realTimeUpdateTextViewMethod
).forEach { insertMethod ->
insertMethod.apply {
val setTextIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "setText"
}
val textViewRegister =
getInstruction<FiveRegisterInstruction>(setTextIndex).registerC
val textSpanRegister =
getInstruction<FiveRegisterInstruction>(setTextIndex).registerD
addInstructions(
setTextIndex, """
invoke-static {v$textViewRegister, v$textSpanRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$textSpanRegister
"""
)
}
// Video 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
.alsoResolve(context, RollingNumberTextViewFingerprint)
).forEach { fingerprintResult ->
fingerprintResult.mutableMethod.apply {
val setTextIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "setText"
}
val textViewRegister =
getInstruction<FiveRegisterInstruction>(setTextIndex).registerC
val textSpanRegister =
getInstruction<FiveRegisterInstruction>(setTextIndex).registerD
addInstructions(
setTextIndex, """
invoke-static {v$textViewRegister, v$textSpanRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$textSpanRegister
"""
)
}
}
}

View File

@ -71,28 +71,30 @@ object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
}
}
if (SettingsPatch.upward1834) {
TextComponentSpecFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.toString() == "Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;"
}
val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
val conversionContextRegister =
getInstruction<TwoRegisterInstruction>(0).registerA
val replaceReference =
getInstruction<ReferenceInstruction>(insertIndex).reference
if (!SettingsPatch.upward1834) {
return
}
addInstructions(
insertIndex + 1, """
invoke-static {v$conversionContextRegister, v$charSequenceRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onCharSequenceLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$charSequenceRegister
invoke-static {v$charSequenceRegister}, $replaceReference
"""
)
removeInstruction(insertIndex)
TextComponentSpecFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.toString() == "Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;"
}
val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
val conversionContextRegister =
getInstruction<TwoRegisterInstruction>(0).registerA
val replaceReference =
getInstruction<ReferenceInstruction>(insertIndex).reference
addInstructions(
insertIndex + 1, """
invoke-static {v$conversionContextRegister, v$charSequenceRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onCharSequenceLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$charSequenceRegister
invoke-static {v$charSequenceRegister}, $replaceReference
"""
)
removeInstruction(insertIndex)
}
}
}

View File

@ -10,11 +10,11 @@ import app.revanced.patcher.fingerprint.MethodFingerprintResult
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.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.shared.fingerprints.MdxPlayerDirectorSetVideoStageFingerprint
import app.revanced.patches.shared.fingerprints.VideoLengthFingerprint
import app.revanced.patches.youtube.utils.PlayerResponseModelUtils.PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.PlayerResponseModelUtils.indexOfPlayerResponseModelInstruction
import app.revanced.patches.youtube.utils.fingerprints.VideoEndFingerprint
@ -31,13 +31,12 @@ import app.revanced.patches.youtube.video.information.fingerprints.SeekRelativeF
import app.revanced.patches.youtube.video.information.fingerprints.VideoIdFingerprint
import app.revanced.patches.youtube.video.information.fingerprints.VideoIdFingerprintBackgroundPlay
import app.revanced.patches.youtube.video.information.fingerprints.VideoIdFingerprintShorts
import app.revanced.patches.shared.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.information.fingerprints.VideoTitleFingerprint
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.addFieldAndInstructions
import app.revanced.util.addStaticFieldToIntegration
import app.revanced.util.alsoResolve
import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod
@ -121,7 +120,6 @@ object VideoInformationPatch : BytecodePatch(
private var seekSourceMethodName = ""
private var seekRelativeSourceMethodName = ""
private lateinit var videoInformationMutableClass: MutableClass
private lateinit var context: BytecodeContext
private lateinit var playerConstructorMethod: MutableMethod
@ -179,21 +177,18 @@ object VideoInformationPatch : BytecodePatch(
return v0
"""
videoInformationMutableClass.addFieldAndInstructions(
context,
context.addStaticFieldToIntegration(
INTEGRATIONS_CLASS_DESCRIPTOR,
methodName,
fieldName,
definingClass,
smaliInstructions,
true
smaliInstructions
)
}
}
override fun execute(context: BytecodeContext) {
this.context = context
videoInformationMutableClass =
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
VideoEndFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
@ -449,8 +444,8 @@ object VideoInformationPatch : BytecodePatch(
return-void
"""
videoInformationMutableClass.addFieldAndInstructions(
context,
context.addStaticFieldToIntegration(
INTEGRATIONS_CLASS_DESCRIPTOR,
"overridePlaybackSpeed",
"playbackSpeedClass",
playbackSpeedClass,
@ -490,13 +485,12 @@ object VideoInformationPatch : BytecodePatch(
return-void
"""
videoInformationMutableClass.addFieldAndInstructions(
context,
context.addStaticFieldToIntegration(
INTEGRATIONS_CLASS_DESCRIPTOR,
"overrideVideoQuality",
"videoQualityClass",
videoQualityClass,
smaliInstructions,
true
smaliInstructions
)
}