mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2024-11-10 09:07:46 +01:00
feat(YouTube): Support version 18.29.38
This commit is contained in:
parent
134e66aa79
commit
c1b9eefa28
32 changed files with 214 additions and 334 deletions
|
@ -0,0 +1,12 @@
|
||||||
|
package app.revanced.patches.shared.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
object LayoutConstructorFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
parameters = emptyList(),
|
||||||
|
strings = listOf("1.0x")
|
||||||
|
)
|
|
@ -1,12 +0,0 @@
|
||||||
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patches.youtube.interaction.seekbar.patch.EnableSeekbarTappingResourcePatch
|
|
||||||
import app.revanced.util.patch.LiteralValueFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
|
|
||||||
object AccessibilityPlayerProgressTimeFingerprint : LiteralValueFingerprint(
|
|
||||||
returnType = "L",
|
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
|
||||||
literal = EnableSeekbarTappingResourcePatch.accessibilityPlayerProgressTime
|
|
||||||
)
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
@FuzzyPatternScanMethod(3)
|
||||||
|
object OnTouchEventHandlerFingerprint : MethodFingerprint(
|
||||||
|
returnType = "Z",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.PUBLIC,
|
||||||
|
parameters = listOf("L"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.INVOKE_VIRTUAL, // oMethodReference
|
||||||
|
Opcode.RETURN,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.IGET_BOOLEAN,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.RETURN,
|
||||||
|
Opcode.INT_TO_FLOAT,
|
||||||
|
Opcode.INT_TO_FLOAT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
Opcode.IF_NEZ,
|
||||||
|
Opcode.RETURN,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.INVOKE_VIRTUAL, // pMethodReference
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef, _ -> methodDef.name == "onTouchEvent" }
|
||||||
|
)
|
|
@ -13,13 +13,15 @@ import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility
|
import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility
|
||||||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.AccessibilityPlayerProgressTimeFingerprint
|
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.OnTouchEventHandlerFingerprint
|
||||||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingFingerprint
|
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.Method
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@DependsOn([IntegrationsPatch::class, EnableSeekbarTappingResourcePatch::class])
|
@DependsOn([IntegrationsPatch::class, EnableSeekbarTappingResourcePatch::class])
|
||||||
|
@ -27,37 +29,23 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
@Description("Enables tap-to-seek on the seekbar of the video player.")
|
@Description("Enables tap-to-seek on the seekbar of the video player.")
|
||||||
@SeekbarTappingCompatibility
|
@SeekbarTappingCompatibility
|
||||||
class EnableSeekbarTappingPatch : BytecodePatch(
|
class EnableSeekbarTappingPatch : BytecodePatch(
|
||||||
listOf(AccessibilityPlayerProgressTimeFingerprint, SeekbarTappingFingerprint)
|
listOf(OnTouchEventHandlerFingerprint, SeekbarTappingFingerprint)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
// Find the required methods to tap the seekbar.
|
// Find the required methods to tap the seekbar.
|
||||||
val seekbarTappingMethods =
|
val seekbarTappingMethods = OnTouchEventHandlerFingerprint.result?.let {
|
||||||
AccessibilityPlayerProgressTimeFingerprint.result?.classDef?.methods?.let { methods ->
|
val patternScanResult = it.scanResult.patternScanResult!!
|
||||||
buildMap {
|
|
||||||
// find the methods which tap the seekbar
|
|
||||||
methods.forEach { method ->
|
|
||||||
if (method.implementation == null) return@forEach
|
|
||||||
|
|
||||||
val instructions = method.implementation!!.instructions
|
fun getReference(index: Int) = it.mutableMethod.getInstruction<ReferenceInstruction>(index)
|
||||||
|
.reference as MethodReference
|
||||||
|
|
||||||
// The method has more than 7 instructions.
|
buildMap {
|
||||||
if (instructions.count() < 7) return@forEach
|
put("O", getReference(patternScanResult.endIndex))
|
||||||
|
put("N", getReference(patternScanResult.startIndex))
|
||||||
// The 7th instruction has the opcode CONST_4.
|
|
||||||
val instruction = instructions.elementAt(6)
|
|
||||||
if (instruction.opcode != Opcode.CONST_4) return@forEach
|
|
||||||
|
|
||||||
// the literal for this instruction has to be either 1 or 2.
|
|
||||||
val literal = (instruction as NarrowLiteralInstruction).narrowLiteral
|
|
||||||
|
|
||||||
// Based on the literal, determine which method is which.
|
|
||||||
if (literal == 1) this["P"] = method
|
|
||||||
if (literal == 2) this["O"] = method
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
seekbarTappingMethods ?: return AccessibilityPlayerProgressTimeFingerprint.toErrorResult()
|
seekbarTappingMethods ?: return OnTouchEventHandlerFingerprint.toErrorResult()
|
||||||
|
|
||||||
SeekbarTappingFingerprint.result?.let {
|
SeekbarTappingFingerprint.result?.let {
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex - 1
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex - 1
|
||||||
|
@ -68,11 +56,11 @@ class EnableSeekbarTappingPatch : BytecodePatch(
|
||||||
val freeRegister = 0
|
val freeRegister = 0
|
||||||
val xAxisRegister = 2
|
val xAxisRegister = 2
|
||||||
|
|
||||||
val pMethod = seekbarTappingMethods["P"]!!
|
|
||||||
val oMethod = seekbarTappingMethods["O"]!!
|
val oMethod = seekbarTappingMethods["O"]!!
|
||||||
|
val nMethod = seekbarTappingMethods["N"]!!
|
||||||
|
|
||||||
fun Method.toInvokeInstructionString() =
|
fun MethodReference.toInvokeInstructionString() =
|
||||||
"invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $definingClass->$name(I)V"
|
"invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $this"
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
|
@ -81,7 +69,7 @@ class EnableSeekbarTappingPatch : BytecodePatch(
|
||||||
move-result v$freeRegister
|
move-result v$freeRegister
|
||||||
if-eqz v$freeRegister, :disabled
|
if-eqz v$freeRegister, :disabled
|
||||||
${oMethod.toInvokeInstructionString()}
|
${oMethod.toInvokeInstructionString()}
|
||||||
${pMethod.toInvokeInstructionString()}
|
${nMethod.toInvokeInstructionString()}
|
||||||
""",
|
""",
|
||||||
ExternalLabel("disabled", getInstruction(insertIndex))
|
ExternalLabel("disabled", getInstruction(insertIndex))
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,16 +2,14 @@ package app.revanced.patches.youtube.interaction.seekbar.patch
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
|
||||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
|
||||||
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
|
@DependsOn([SettingsPatch::class])
|
||||||
class EnableSeekbarTappingResourcePatch : ResourcePatch {
|
class EnableSeekbarTappingResourcePatch : ResourcePatch {
|
||||||
override fun execute(context: ResourceContext): PatchResult {
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
|
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
|
||||||
|
@ -22,15 +20,6 @@ class EnableSeekbarTappingResourcePatch : ResourcePatch {
|
||||||
StringResource("revanced_seekbar_tapping_summary_off", "Seekbar tapping is disabled")
|
StringResource("revanced_seekbar_tapping_summary_off", "Seekbar tapping is disabled")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
accessibilityPlayerProgressTime = ResourceMappingPatch.resourceMappings.find {
|
|
||||||
it.name == "accessibility_player_progress_time"
|
|
||||||
}?.id ?: return PatchResultError("Failed to find required resource")
|
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal companion object {
|
|
||||||
var accessibilityPlayerProgressTime = -1L
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -19,8 +19,5 @@ object SubtitleButtonControllerFingerprint : MethodFingerprint(
|
||||||
Opcode.CONST,
|
Opcode.CONST,
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.IGET_OBJECT,
|
Opcode.IGET_OBJECT,
|
||||||
),
|
)
|
||||||
customFingerprint = { methodDef, _ ->
|
|
||||||
methodDef.definingClass.endsWith("SubtitleButtonController;")
|
|
||||||
}
|
|
||||||
)
|
)
|
|
@ -1,10 +0,0 @@
|
||||||
package app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
|
||||||
|
|
||||||
object LayoutConstructorFingerprint : MethodFingerprint(
|
|
||||||
strings = listOf("1.0x"),
|
|
||||||
customFingerprint = { methodDef, _ ->
|
|
||||||
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -17,7 +17,7 @@ import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
import app.revanced.patches.youtube.layout.buttons.autoplay.annotations.AutoplayButtonCompatibility
|
import app.revanced.patches.youtube.layout.buttons.autoplay.annotations.AutoplayButtonCompatibility
|
||||||
import app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints.LayoutConstructorFingerprint
|
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||||
|
|
|
@ -38,12 +38,12 @@ class HideCaptionsButtonPatch : BytecodePatch(listOf(
|
||||||
val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod
|
val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod
|
||||||
|
|
||||||
// Due to previously applied patches, scanResult index cannot be used in this context
|
// Due to previously applied patches, scanResult index cannot be used in this context
|
||||||
val igetBooleanIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst {
|
val insertIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst {
|
||||||
it.opcode == Opcode.IGET_BOOLEAN
|
it.opcode == Opcode.IGET_BOOLEAN
|
||||||
}
|
} + 1
|
||||||
|
|
||||||
subtitleButtonControllerMethod.addInstruction(
|
subtitleButtonControllerMethod.addInstruction(
|
||||||
igetBooleanIndex + 1,
|
insertIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static {v0}, Lapp/revanced/integrations/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V
|
invoke-static {v0}, Lapp/revanced/integrations/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints
|
package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.util.patch.LiteralValueFingerprint
|
|
||||||
import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch
|
import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
object HideLoadMoreButtonFingerprint : LiteralValueFingerprint(
|
object HideLoadMoreButtonFingerprint : LiteralValueFingerprint(
|
||||||
returnType = "V",
|
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
|
||||||
parameters = listOf("L", "L", "L", "L"),
|
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.CONST,
|
Opcode.CONST,
|
||||||
Opcode.CONST_4,
|
Opcode.CONST_4,
|
||||||
|
|
|
@ -17,7 +17,6 @@ object CreatePlayerOverviewFingerprint : MethodFingerprint(
|
||||||
Opcode.CHECK_CAST
|
Opcode.CHECK_CAST
|
||||||
),
|
),
|
||||||
customFingerprint = { methodDef, _ ->
|
customFingerprint = { methodDef, _ ->
|
||||||
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
|
methodDef.containsConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId)
|
||||||
&& methodDef.containsConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
|
@ -1,28 +1,24 @@
|
||||||
package app.revanced.patches.youtube.layout.hide.time.fingerprints
|
package app.revanced.patches.youtube.layout.hide.time.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
@FuzzyPatternScanMethod(1)
|
||||||
object TimeCounterFingerprint : MethodFingerprint(
|
object TimeCounterFingerprint : MethodFingerprint(
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
|
||||||
parameters = listOf(),
|
|
||||||
returnType = "V",
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.SUB_LONG_2ADDR,
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.IGET_OBJECT,
|
Opcode.IGET_OBJECT,
|
||||||
Opcode.IGET_WIDE,
|
Opcode.IGET_WIDE,
|
||||||
Opcode.INVOKE_STATIC,
|
Opcode.CONST_WIDE_16,
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.CMP_LONG,
|
||||||
Opcode.INVOKE_INTERFACE,
|
Opcode.IF_LEZ,
|
||||||
Opcode.RETURN_VOID,
|
Opcode.IGET_OBJECT,
|
||||||
),
|
Opcode.IF_EQZ,
|
||||||
customFingerprint = { _, classDef ->
|
Opcode.INVOKE_VIRTUAL,
|
||||||
// On older devices this fingerprint resolves very slowly.
|
Opcode.MOVE_RESULT,
|
||||||
// Speed this up by checking for the number of methods.
|
Opcode.IF_EQZ,
|
||||||
classDef.methods.count() == 14
|
Opcode.GOTO,
|
||||||
}
|
)
|
||||||
)
|
)
|
|
@ -1,8 +0,0 @@
|
||||||
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations
|
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Compatibility
|
|
||||||
import app.revanced.patcher.annotation.Package
|
|
||||||
|
|
||||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
|
||||||
internal annotation class FullscreenPanelsCompatibility
|
|
|
@ -1,11 +0,0 @@
|
||||||
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints
|
|
||||||
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
object FullscreenViewAdderFingerprint : MethodFingerprint(
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.IGET_BOOLEAN
|
|
||||||
)
|
|
||||||
)
|
|
|
@ -1,20 +0,0 @@
|
||||||
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
object FullscreenViewAdderParentFingerprint : MethodFingerprint(
|
|
||||||
returnType = "V",
|
|
||||||
parameters = listOf("Landroid/content/Context;", "Landroid/view/View;"),
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.GOTO,
|
|
||||||
Opcode.IGET_BOOLEAN,
|
|
||||||
Opcode.IF_EQ,
|
|
||||||
Opcode.GOTO,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
),
|
|
||||||
customFingerprint = { methodDef, _ ->
|
|
||||||
methodDef.definingClass.endsWith("FullscreenEngagementPanelOverlay;")
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -1,63 +0,0 @@
|
||||||
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.patch
|
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Description
|
|
||||||
import app.revanced.patcher.annotation.Name
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
|
||||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
|
||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
|
||||||
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations.FullscreenPanelsCompatibility
|
|
||||||
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints.FullscreenViewAdderFingerprint
|
|
||||||
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints.FullscreenViewAdderParentFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
|
||||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
|
||||||
|
|
||||||
@Patch
|
|
||||||
@Name("Disable fullscreen panels")
|
|
||||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
|
||||||
@Description("Disables video description and comments panel in fullscreen view.")
|
|
||||||
@FullscreenPanelsCompatibility
|
|
||||||
class FullscreenPanelsRemoverPatch : BytecodePatch(
|
|
||||||
listOf(
|
|
||||||
FullscreenViewAdderParentFingerprint
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
|
||||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
|
||||||
SwitchPreference(
|
|
||||||
"revanced_hide_fullscreen_panels",
|
|
||||||
StringResource("revanced_hide_fullscreen_panels_title", "Hide fullscreen panels"),
|
|
||||||
StringResource("revanced_hide_fullscreen_panels_summary_on", "Fullscreen panels are hidden"),
|
|
||||||
StringResource("revanced_hide_fullscreen_panels_summary_off", "Fullscreen panels are shown")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
val parentResult = FullscreenViewAdderParentFingerprint.result!!
|
|
||||||
FullscreenViewAdderFingerprint.resolve(context, parentResult.method, parentResult.classDef)
|
|
||||||
val result = FullscreenViewAdderParentFingerprint.result
|
|
||||||
?: return PatchResultError("Fingerprint not resolved!")
|
|
||||||
|
|
||||||
val method = result.mutableMethod
|
|
||||||
|
|
||||||
val ifIndex = result.scanResult.patternScanResult!!.startIndex + 2
|
|
||||||
|
|
||||||
method.removeInstruction(ifIndex)
|
|
||||||
method.addInstructions(
|
|
||||||
ifIndex,
|
|
||||||
"""
|
|
||||||
invoke-static {}, Lapp/revanced/integrations/patches/FullscreenPanelsRemoverPatch;->getFullscreenPanelsVisibility()I
|
|
||||||
move-result p1
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
return PatchResultSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,12 @@
|
||||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
object ShortsTextViewFingerprint : MethodFingerprint(
|
object ShortsTextViewFingerprint : MethodFingerprint(
|
||||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
// 18.29.38 method is public final visibility, but in 18.23.35 and older it's protected final.
|
||||||
|
// If 18.23.35 is dropped then accessFlags should be specified here.
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
parameters = listOf("L", "L"),
|
parameters = listOf("L", "L"),
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
|
|
|
@ -15,7 +15,7 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.MOVE_OBJECT_FROM16, // available unused register
|
Opcode.MOVE_OBJECT_FROM16, // available unused register
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
Opcode.MOVE_OBJECT_FROM16,
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
null, // move-object/from16 or move/from16
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
Opcode.MOVE_OBJECT_FROM16,
|
||||||
Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference
|
Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
|
|
@ -19,9 +19,6 @@ object ControlsOverlayFingerprint : MethodFingerprint(
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.CHECK_CAST,
|
Opcode.CHECK_CAST,
|
||||||
Opcode.NEW_INSTANCE,
|
Opcode.NEW_INSTANCE
|
||||||
),
|
)
|
||||||
customFingerprint = { methodDef, _ ->
|
|
||||||
methodDef.definingClass == "Lcom/google/android/apps/youtube/app/player/overlay/YouTubeControlsOverlay;"
|
|
||||||
}
|
|
||||||
)
|
)
|
|
@ -17,6 +17,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
|
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
|
||||||
import app.revanced.patches.shared.fingerprints.SeekbarFingerprint
|
import app.revanced.patches.shared.fingerprints.SeekbarFingerprint
|
||||||
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
|
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
|
||||||
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||||
|
@ -59,23 +60,16 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||||
listOf(
|
listOf(
|
||||||
SeekbarFingerprint,
|
SeekbarFingerprint,
|
||||||
AppendTimeFingerprint,
|
AppendTimeFingerprint,
|
||||||
ControlsOverlayFingerprint,
|
LayoutConstructorFingerprint,
|
||||||
AutoRepeatParentFingerprint,
|
AutoRepeatParentFingerprint,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private companion object {
|
|
||||||
const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
|
|
||||||
"Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;"
|
|
||||||
const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
|
|
||||||
"Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;"
|
|
||||||
const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
|
|
||||||
"Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;"
|
|
||||||
const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR =
|
|
||||||
"Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
LayoutConstructorFingerprint.result?.let {
|
||||||
|
if (!ControlsOverlayFingerprint.resolve(context, it.classDef))
|
||||||
|
throw ControlsOverlayFingerprint.toErrorResult()
|
||||||
|
} ?: return LayoutConstructorFingerprint.toErrorResult()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hook the video time methods
|
* Hook the video time methods
|
||||||
*/
|
*/
|
||||||
|
@ -279,4 +273,15 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;"
|
||||||
|
const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;"
|
||||||
|
const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;"
|
||||||
|
const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,10 @@ package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
object MiniPlayerOverrideFingerprint : MethodFingerprint(
|
object MiniPlayerOverrideFingerprint : MethodFingerprint(
|
||||||
"Z", AccessFlags.STATIC or AccessFlags.PUBLIC,
|
returnType = "L",
|
||||||
listOf("Landroid/content/Context;"),
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
opcodes = listOf(
|
parameters = listOf("L"),
|
||||||
Opcode.INVOKE_STATIC,
|
strings = listOf("appName")
|
||||||
Opcode.MOVE_RESULT,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.IF_EQ,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.IF_EQ,
|
|
||||||
Opcode.CONST_4, // override this value
|
|
||||||
Opcode.RETURN,
|
|
||||||
Opcode.CONST_4, // override this value
|
|
||||||
Opcode.RETURN
|
|
||||||
),
|
|
||||||
)
|
)
|
|
@ -1,7 +0,0 @@
|
||||||
package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
|
||||||
|
|
||||||
object MiniPlayerOverrideParentFingerprint : MethodFingerprint(
|
|
||||||
strings = listOf("Unset or unknown Input OneOf case for dynamic input")
|
|
||||||
)
|
|
|
@ -4,6 +4,7 @@ import app.revanced.extensions.toErrorResult
|
||||||
import app.revanced.patcher.annotation.Description
|
import app.revanced.patcher.annotation.Description
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.data.toMethodWalker
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||||
|
@ -17,7 +18,10 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
|
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
|
||||||
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.*
|
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorParentFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
@ -32,7 +36,7 @@ class TabletMiniPlayerPatch : BytecodePatch(
|
||||||
listOf(
|
listOf(
|
||||||
MiniPlayerDimensionsCalculatorParentFingerprint,
|
MiniPlayerDimensionsCalculatorParentFingerprint,
|
||||||
MiniPlayerResponseModelSizeCheckFingerprint,
|
MiniPlayerResponseModelSizeCheckFingerprint,
|
||||||
MiniPlayerOverrideParentFingerprint
|
MiniPlayerOverrideFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
@ -62,33 +66,33 @@ class TabletMiniPlayerPatch : BytecodePatch(
|
||||||
/** same register used to return **/
|
/** same register used to return **/
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
* Method with context parameter.
|
|
||||||
*/
|
|
||||||
MiniPlayerOverrideParentFingerprint.result?.let {
|
|
||||||
if (!MiniPlayerOverrideFingerprint.resolve(context, it.classDef))
|
|
||||||
throw MiniPlayerOverrideFingerprint.toErrorResult()
|
|
||||||
} ?: return MiniPlayerOverrideParentFingerprint.toErrorResult()
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Override every return instruction with the proxy call.
|
* Override every return instruction with the proxy call.
|
||||||
*/
|
*/
|
||||||
MiniPlayerOverrideFingerprint.result!!.mutableMethod.apply {
|
MiniPlayerOverrideFingerprint.result?.let { result ->
|
||||||
implementation!!.let { implementation ->
|
result.mutableMethod.let { method ->
|
||||||
val returnIndices = implementation.instructions
|
val appNameStringIndex = result.scanResult.stringsScanResult!!.matches.first().index + 2
|
||||||
.withIndex()
|
context.toMethodWalker(method).nextMethod(appNameStringIndex, true)
|
||||||
.filter { (_, instruction) -> instruction.opcode == Opcode.RETURN }
|
.getMethod() as MutableMethod
|
||||||
.map { (index, _) -> index }
|
}.apply {
|
||||||
|
implementation!!.let { implementation ->
|
||||||
|
val returnIndices = implementation.instructions
|
||||||
|
.withIndex()
|
||||||
|
.filter { (_, instruction) -> instruction.opcode == Opcode.RETURN }
|
||||||
|
.map { (index, _) -> index }
|
||||||
|
|
||||||
if (returnIndices.isEmpty()) throw PatchResultError("No return instructions found.")
|
if (returnIndices.isEmpty()) throw PatchResultError("No return instructions found.")
|
||||||
|
|
||||||
// This method clobbers register p0 to return the value, calculate to override.
|
// This method clobbers register p0 to return the value, calculate to override.
|
||||||
val returnedRegister = implementation.registerCount - parameters.size
|
val returnedRegister = implementation.registerCount - parameters.size
|
||||||
|
|
||||||
// Hook the returned register on every return instruction.
|
// Hook the returned register on every return instruction.
|
||||||
returnIndices.forEach { index -> insertOverride(index, returnedRegister) }
|
returnIndices.forEach { index -> insertOverride(index, returnedRegister) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return@let
|
||||||
|
} ?: return MiniPlayerOverrideFingerprint.toErrorResult()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Size check return value override.
|
* Size check return value override.
|
||||||
|
|
|
@ -4,22 +4,31 @@ import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||||
|
|
||||||
object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint(
|
object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf("I", "L", "L"),
|
parameters = listOf("I", "L", "L"),
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.IF_EQZ,
|
Opcode.CONST_4,
|
||||||
|
Opcode.IF_NE,
|
||||||
Opcode.SGET_OBJECT,
|
Opcode.SGET_OBJECT,
|
||||||
Opcode.IF_NE,
|
Opcode.IF_NE,
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.IPUT_BOOLEAN,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.IGET,
|
Opcode.IGET,
|
||||||
Opcode.INVOKE_STATIC
|
Opcode.CONST_4,
|
||||||
|
Opcode.IF_NE,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.SGET_OBJECT,
|
||||||
|
Opcode.IF_EQ,
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.RETURN_VOID
|
||||||
),
|
),
|
||||||
customFingerprint = { methodDef, _ ->
|
customFingerprint = { methodDef, _ ->
|
||||||
methodDef.definingClass.endsWith("MinimizedPlaybackPolicyController;")
|
methodDef.implementation!!.instructions.any {
|
||||||
|
((it as? NarrowLiteralInstruction)?.narrowLiteral == 5)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
package app.revanced.patches.youtube.misc.playercontrols.bytecode.patch
|
package app.revanced.patches.youtube.misc.playercontrols.bytecode.patch
|
||||||
|
|
||||||
|
import app.revanced.extensions.toErrorResult
|
||||||
import app.revanced.patcher.annotation.Description
|
import app.revanced.patcher.annotation.Description
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
|
||||||
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
|
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
|
||||||
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
|
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
|
||||||
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
|
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
|
||||||
|
@ -20,9 +23,17 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
@Description("Manages the code for the player controls of the YouTube player.")
|
@Description("Manages the code for the player controls of the YouTube player.")
|
||||||
@PlayerControlsCompatibility
|
@PlayerControlsCompatibility
|
||||||
class PlayerControlsBytecodePatch : BytecodePatch(
|
class PlayerControlsBytecodePatch : BytecodePatch(
|
||||||
listOf(PlayerControlsVisibilityFingerprint, BottomControlsInflateFingerprint)
|
listOf(
|
||||||
|
LayoutConstructorFingerprint,
|
||||||
|
BottomControlsInflateFingerprint
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
LayoutConstructorFingerprint.result?.let {
|
||||||
|
if (!PlayerControlsVisibilityFingerprint.resolve(context, it.classDef))
|
||||||
|
throw LayoutConstructorFingerprint.toErrorResult()
|
||||||
|
} ?: return LayoutConstructorFingerprint.toErrorResult()
|
||||||
|
|
||||||
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
|
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
|
||||||
inflateFingerprintResult = BottomControlsInflateFingerprint.result!!
|
inflateFingerprintResult = BottomControlsInflateFingerprint.result!!
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
object PlayerControlsVisibilityFingerprint : MethodFingerprint(
|
object PlayerControlsVisibilityFingerprint : MethodFingerprint(
|
||||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
parameters = listOf("Z", "Z"),
|
parameters = listOf("Z", "Z")
|
||||||
customFingerprint = { methodDef, _ ->
|
|
||||||
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
|
|
||||||
}
|
|
||||||
)
|
)
|
|
@ -10,26 +10,8 @@ object PlayerTypeFingerprint : MethodFingerprint(
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf("L"),
|
parameters = listOf("L"),
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.IF_NE,
|
Opcode.IF_NE,
|
||||||
Opcode.RETURN_VOID,
|
|
||||||
Opcode.IPUT_OBJECT,
|
|
||||||
Opcode.INVOKE_DIRECT,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.MOVE_RESULT,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.RETURN_VOID,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.RETURN_VOID
|
Opcode.RETURN_VOID
|
||||||
),
|
),
|
||||||
customFingerprint = { methodDef, _ ->
|
customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/YouTubePlayerOverlaysLayout;") }
|
||||||
methodDef.definingClass.endsWith("YouTubePlayerOverlaysLayout;")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,8 +17,5 @@ object VideoStateFingerprint : MethodFingerprint(
|
||||||
Opcode.IF_EQZ,
|
Opcode.IF_EQZ,
|
||||||
Opcode.IF_EQZ,
|
Opcode.IF_EQZ,
|
||||||
Opcode.IGET_OBJECT, // obfuscated parameter field name
|
Opcode.IGET_OBJECT, // obfuscated parameter field name
|
||||||
),
|
)
|
||||||
customFingerprint = { methodDef, _ ->
|
|
||||||
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
|
|
||||||
}
|
|
||||||
)
|
)
|
|
@ -12,33 +12,27 @@ import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.playertype.annotation.PlayerTypeHookCompatibility
|
|
||||||
import app.revanced.patches.youtube.misc.playertype.fingerprint.PlayerTypeFingerprint
|
import app.revanced.patches.youtube.misc.playertype.fingerprint.PlayerTypeFingerprint
|
||||||
import app.revanced.patches.youtube.misc.playertype.fingerprint.VideoStateFingerprint
|
import app.revanced.patches.youtube.misc.playertype.fingerprint.VideoStateFingerprint
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
|
||||||
@Name("Player type hook")
|
@Name("Player type hook")
|
||||||
@Description("Hook to get the current player type and video playback state.")
|
@Description("Hook to get the current player type and video playback state.")
|
||||||
@PlayerTypeHookCompatibility
|
|
||||||
@DependsOn([IntegrationsPatch::class])
|
@DependsOn([IntegrationsPatch::class])
|
||||||
class PlayerTypeHookPatch : BytecodePatch(
|
class PlayerTypeHookPatch : BytecodePatch(
|
||||||
listOf(PlayerTypeFingerprint, VideoStateFingerprint)
|
listOf(PlayerTypeFingerprint, VideoStateFingerprint)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
PlayerTypeFingerprint.result?.mutableMethod?.addInstruction(
|
||||||
PlayerTypeFingerprint.result?.let {
|
0,
|
||||||
it.mutableMethod.apply {
|
"invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V"
|
||||||
addInstruction(
|
) ?: return PlayerTypeFingerprint.toErrorResult()
|
||||||
0,
|
|
||||||
"invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} ?: return PlayerTypeFingerprint.toErrorResult()
|
|
||||||
|
|
||||||
VideoStateFingerprint.result?.let {
|
VideoStateFingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
0,
|
0,
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -10,6 +10,7 @@ object VideoIdFingerprint : MethodFingerprint(
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf("L"),
|
parameters = listOf("L"),
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.IF_EQZ,
|
Opcode.IF_EQZ,
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
@ -23,8 +24,5 @@ object VideoIdFingerprint : MethodFingerprint(
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.INVOKE_INTERFACE,
|
Opcode.INVOKE_INTERFACE,
|
||||||
Opcode.MOVE_RESULT_OBJECT
|
Opcode.MOVE_RESULT_OBJECT
|
||||||
),
|
)
|
||||||
customFingerprint = { methodDef, _ ->
|
|
||||||
methodDef.definingClass.endsWith("SubtitlesOverlayPresenter;")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,8 +9,21 @@ object VideoIdFingerprintBackgroundPlay : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.DECLARED_SYNCHRONIZED or AccessFlags.FINAL or AccessFlags.PUBLIC,
|
accessFlags = AccessFlags.DECLARED_SYNCHRONIZED or AccessFlags.FINAL or AccessFlags.PUBLIC,
|
||||||
parameters = listOf("L"),
|
parameters = listOf("L"),
|
||||||
opcodes = listOf(Opcode.INVOKE_INTERFACE),
|
opcodes = listOf(
|
||||||
customFingerprint = { methodDef, _ ->
|
Opcode.MONITOR_EXIT,
|
||||||
methodDef.definingClass.endsWith("PlaybackLifecycleMonitor;")
|
Opcode.RETURN_VOID,
|
||||||
}
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.NEW_ARRAY,
|
||||||
|
Opcode.SGET_OBJECT,
|
||||||
|
Opcode.APUT_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.INVOKE_INTERFACE,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
@ -25,27 +26,33 @@ class VideoIdPatch : BytecodePatch(
|
||||||
listOf(VideoIdFingerprint, VideoIdFingerprintBackgroundPlay)
|
listOf(VideoIdFingerprint, VideoIdFingerprintBackgroundPlay)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
VideoIdFingerprint.result?.let { result ->
|
/**
|
||||||
val videoIdRegisterInstructionIndex = result.scanResult.patternScanResult!!.endIndex
|
* Supplies the method and register index of the video id register.
|
||||||
|
*
|
||||||
|
* @param consumer Consumer that receives the method, insert index and video id register index.
|
||||||
|
*/
|
||||||
|
fun MethodFingerprint.setFields(consumer: (MutableMethod, Int, Int) -> Unit) = result?.let { result ->
|
||||||
|
val videoIdRegisterIndex = result.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
|
result.mutableMethod.let {
|
||||||
|
val videoIdRegister = it.getInstruction<OneRegisterInstruction>(videoIdRegisterIndex).registerA
|
||||||
|
val insertIndex = videoIdRegisterIndex + 1
|
||||||
|
consumer(it, insertIndex, videoIdRegister)
|
||||||
|
|
||||||
result.mutableMethod.also {
|
|
||||||
insertMethod = it
|
|
||||||
}.apply {
|
|
||||||
videoIdRegister = getInstruction<OneRegisterInstruction>(videoIdRegisterInstructionIndex).registerA
|
|
||||||
insertIndex = videoIdRegisterInstructionIndex + 1
|
|
||||||
}
|
}
|
||||||
} ?: return VideoIdFingerprint.toErrorResult()
|
} ?: throw VideoIdFingerprint.toErrorResult()
|
||||||
|
|
||||||
VideoIdFingerprintBackgroundPlay.result?.let { result ->
|
VideoIdFingerprint.setFields { method, insertIndex, videoIdRegister ->
|
||||||
val endIndex = result.scanResult.patternScanResult!!.endIndex
|
insertMethod = method
|
||||||
|
VideoIdPatch.insertIndex = insertIndex
|
||||||
|
VideoIdPatch.videoIdRegister = videoIdRegister
|
||||||
|
}
|
||||||
|
|
||||||
result.mutableMethod.also {
|
VideoIdFingerprintBackgroundPlay.setFields { method, insertIndex, videoIdRegister ->
|
||||||
backgroundPlaybackMethod = it
|
backgroundPlaybackMethod = method
|
||||||
}.apply {
|
backgroundPlaybackInsertIndex = insertIndex
|
||||||
backgroundPlaybackVideoIdRegister = getInstruction<OneRegisterInstruction>(endIndex + 1).registerA
|
backgroundPlaybackVideoIdRegister = videoIdRegister
|
||||||
backgroundPlaybackInsertIndex = endIndex + 2
|
}
|
||||||
}
|
|
||||||
} ?: return VideoIdFingerprintBackgroundPlay.toErrorResult()
|
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue