mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 13:17:46 +02:00
chore: remove obsolete code
This commit is contained in:
@ -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
|
||||
|
@ -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\""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
"""
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
)
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user