mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 21:27:43 +02:00
cleanup
This commit is contained in:
@ -8,9 +8,9 @@ import org.jf.dexlib2.Opcode
|
||||
object QualityMenuViewInflateFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(Opcode.INVOKE_SUPER),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.videoqualityfragmentLabelId
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.videoqualityfragmentLabelId
|
||||
} == true
|
||||
}
|
||||
)
|
@ -3,12 +3,13 @@ package app.revanced.patches.youtube.layout.flyoutpanel.oldqualitylayout.bytecod
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patches.youtube.layout.flyoutpanel.oldqualitylayout.bytecode.fingerprints.QualityMenuViewInflateFingerprint
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.util.integrations.Constants.FLYOUTPANEL_LAYOUT
|
||||
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
|
||||
@ -19,21 +20,18 @@ class OldQualityLayoutBytecodePatch : BytecodePatch(
|
||||
listOf(QualityMenuViewInflateFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val inflateFingerprintResult = QualityMenuViewInflateFingerprint.result!!
|
||||
val method = inflateFingerprintResult.mutableMethod
|
||||
val instructions = method.implementation!!.instructions
|
||||
|
||||
// at this index the listener is added to the list view
|
||||
val listenerInvokeRegister = instructions.size - 1 - 1
|
||||
QualityMenuViewInflateFingerprint.result?.mutableMethod?.let {
|
||||
with (it.implementation!!.instructions) {
|
||||
val insertIndex = this.size - 1 - 1
|
||||
val register = (this[insertIndex] as FiveRegisterInstruction).registerC
|
||||
|
||||
// get the register which stores the quality menu list view
|
||||
val onItemClickViewRegister = (instructions[listenerInvokeRegister] as FiveRegisterInstruction).registerC
|
||||
|
||||
// insert the integrations method
|
||||
method.addInstruction(
|
||||
listenerInvokeRegister, // insert the integrations instructions right before the listener
|
||||
"invoke-static { v$onItemClickViewRegister }, $FLYOUTPANEL_LAYOUT->enableOldQualityMenu(Landroid/widget/ListView;)V"
|
||||
)
|
||||
it.addInstructions(
|
||||
insertIndex, // insert the integrations instructions right before the listener
|
||||
"invoke-static { v$register }, $FLYOUTPANEL_LAYOUT->enableOldQualityMenu(Landroid/widget/ListView;)V"
|
||||
)
|
||||
}
|
||||
} ?: return QualityMenuViewInflateFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ import org.jf.dexlib2.Opcode
|
||||
object ScrubbingLabelFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(Opcode.IPUT_BOOLEAN),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.scrubbingLabelId
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.scrubbingLabelId
|
||||
} == true
|
||||
}
|
||||
)
|
@ -7,14 +7,16 @@ import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.removeInstruction
|
||||
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.patches.youtube.layout.fullscreen.flimstripoverlay.bytecode.fingerprints.ScrubbingLabelFingerprint
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.util.integrations.Constants.FULLSCREEN_LAYOUT
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import org.jf.dexlib2.iface.reference.FieldReference
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("hide-filmstrip-overlay-bytecode-patch")
|
||||
@YouTubeCompatibility
|
||||
@ -25,32 +27,33 @@ class HideFilmstripOverlayBytecodePatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val scrubbingLabelResult = ScrubbingLabelFingerprint.result!!
|
||||
val scrubbingLabelMethod = scrubbingLabelResult.mutableMethod
|
||||
val scrubbingLabelMethodInstructions = scrubbingLabelMethod.implementation!!.instructions
|
||||
ScrubbingLabelFingerprint.result?.mutableMethod?.let {
|
||||
with (it.implementation!!.instructions) {
|
||||
for ((index, instruction) in this.withIndex()) {
|
||||
if (instruction.opcode != Opcode.IPUT_BOOLEAN) continue
|
||||
val primaryRegister = (instruction as TwoRegisterInstruction).registerA
|
||||
val secondaryRegister = (instruction as TwoRegisterInstruction).registerB
|
||||
val dummyRegister = primaryRegister + 2
|
||||
val fieldReference = (instruction as ReferenceInstruction).reference as FieldReference
|
||||
|
||||
for ((index, instruction) in scrubbingLabelMethodInstructions.withIndex()) {
|
||||
if (instruction.opcode != Opcode.IPUT_BOOLEAN) continue
|
||||
val scrubbingLabelRegisterA = (instruction as TwoRegisterInstruction).registerA
|
||||
val scrubbingLabelRegisterB = scrubbingLabelRegisterA + 2
|
||||
val scrubbingLabelRegisterC = (instruction as TwoRegisterInstruction).registerB
|
||||
val scrubbingLabelReference = (instruction as ReferenceInstruction).reference as FieldReference
|
||||
it.addInstructions(
|
||||
index + 1, """
|
||||
invoke-static {}, $FULLSCREEN_LAYOUT->hideFilmstripOverlay()Z
|
||||
move-result v$dummyRegister
|
||||
if-eqz v$dummyRegister, :show
|
||||
const/4 v$primaryRegister, 0x0
|
||||
:show
|
||||
iput-boolean v$primaryRegister, v$secondaryRegister, ${fieldReference.definingClass}->${fieldReference.name}:${fieldReference.type}
|
||||
"""
|
||||
)
|
||||
|
||||
scrubbingLabelMethod.addInstructions(
|
||||
index + 1, """
|
||||
invoke-static {}, $FULLSCREEN_LAYOUT->hideFilmstripOverlay()Z
|
||||
move-result v$scrubbingLabelRegisterB
|
||||
if-eqz v$scrubbingLabelRegisterB, :show
|
||||
const/4 v$scrubbingLabelRegisterA, 0x0
|
||||
:show
|
||||
iput-boolean v$scrubbingLabelRegisterA, v$scrubbingLabelRegisterC, ${scrubbingLabelReference.definingClass}->${scrubbingLabelReference.name}:${scrubbingLabelReference.type}
|
||||
"""
|
||||
)
|
||||
it.removeInstruction(index)
|
||||
|
||||
scrubbingLabelMethod.removeInstruction(index)
|
||||
break
|
||||
}
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
} ?: return ScrubbingLabelFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
return PatchResultError("Could not find the method to hook.")
|
||||
}
|
||||
}
|
||||
|
@ -6,13 +6,14 @@ import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.extensions.removeInstruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.layout.fullscreen.hapticfeedback.bytecode.fingerprints.*
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.util.integrations.Constants.FULLSCREEN_LAYOUT
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@ -29,27 +30,36 @@ class HapticFeedBackBytecodePatch : BytecodePatch(
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
|
||||
SeekHapticsFingerprint.disableHaptics("disableSeekVibrate")
|
||||
ScrubbingHapticsFingerprint.voidHaptics("disableScrubbingVibrate")
|
||||
MarkerHapticsFingerprint.voidHaptics("disableChapterVibrate")
|
||||
ZoomHapticsFingerprint.voidHaptics("disableZoomVibrate")
|
||||
arrayOf(
|
||||
SeekHapticsFingerprint to "disableSeekVibrate",
|
||||
ScrubbingHapticsFingerprint to "disableScrubbingVibrate",
|
||||
MarkerHapticsFingerprint to "disableChapterVibrate",
|
||||
ZoomHapticsFingerprint to "disableZoomVibrate"
|
||||
).map { (fingerprint, name) ->
|
||||
fingerprint.result?.let {
|
||||
if (fingerprint == SeekHapticsFingerprint)
|
||||
it.disableHaptics(name)
|
||||
else
|
||||
it.voidHaptics(name)
|
||||
} ?: return fingerprint.toErrorResult()
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
fun MethodFingerprint.disableHaptics(targetMethodName: String) {
|
||||
with(this.result!!) {
|
||||
val startIndex = scanResult.patternScanResult!!.startIndex
|
||||
val endIndex = scanResult.patternScanResult!!.endIndex
|
||||
val insertIndex = endIndex + 4
|
||||
val targetRegister = (method.implementation!!.instructions.elementAt(insertIndex) as OneRegisterInstruction).registerA
|
||||
val dummyRegister = targetRegister + 1
|
||||
fun MethodFingerprintResult.disableHaptics(targetMethodName: String) {
|
||||
val startIndex = scanResult.patternScanResult!!.startIndex
|
||||
val endIndex = scanResult.patternScanResult!!.endIndex
|
||||
val insertIndex = endIndex + 4
|
||||
val targetRegister = (method.implementation!!.instructions.elementAt(insertIndex) as OneRegisterInstruction).registerA
|
||||
val dummyRegister = targetRegister + 1
|
||||
|
||||
mutableMethod.removeInstruction(insertIndex)
|
||||
with (mutableMethod) {
|
||||
removeInstruction(insertIndex)
|
||||
|
||||
mutableMethod.addInstructions(
|
||||
insertIndex, """
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {}, $FULLSCREEN_LAYOUT->$targetMethodName()Z
|
||||
move-result v$dummyRegister
|
||||
if-eqz v$dummyRegister, :vibrate
|
||||
@ -57,31 +67,30 @@ class HapticFeedBackBytecodePatch : BytecodePatch(
|
||||
goto :exit
|
||||
:vibrate
|
||||
const-wide/16 v$targetRegister, 0x19
|
||||
""", listOf(ExternalLabel("exit", mutableMethod.instruction(insertIndex)))
|
||||
)
|
||||
""", listOf(ExternalLabel("exit", mutableMethod.instruction(insertIndex)))
|
||||
)
|
||||
|
||||
mutableMethod.addInstructions(
|
||||
startIndex, """
|
||||
addInstructions(
|
||||
startIndex, """
|
||||
invoke-static {}, $FULLSCREEN_LAYOUT->$targetMethodName()Z
|
||||
move-result v$dummyRegister
|
||||
if-eqz v$dummyRegister, :vibrate
|
||||
return-void
|
||||
""", listOf(ExternalLabel("vibrate", mutableMethod.instruction(startIndex)))
|
||||
)
|
||||
""", listOf(ExternalLabel("vibrate", mutableMethod.instruction(startIndex)))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun MethodFingerprint.voidHaptics(targetMethodName: String) {
|
||||
with(this.result!!) {
|
||||
mutableMethod.addInstructions(
|
||||
0, """
|
||||
fun MethodFingerprintResult.voidHaptics(targetMethodName: String) {
|
||||
mutableMethod.addInstructions(
|
||||
0, """
|
||||
invoke-static {}, $FULLSCREEN_LAYOUT->$targetMethodName()Z
|
||||
move-result v0
|
||||
if-eqz v0, :vibrate
|
||||
return-void
|
||||
""", listOf(ExternalLabel("vibrate", mutableMethod.instruction(0)))
|
||||
)
|
||||
}
|
||||
""", listOf(ExternalLabel("vibrate", mutableMethod.instruction(0)))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,18 +6,11 @@ import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object StartVideoInformerFingerprint : MethodFingerprint(
|
||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L", "L", "L"), listOf(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.CONST_STRING,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
)
|
||||
Opcode.RETURN_VOID,
|
||||
),
|
||||
strings = listOf("pc")
|
||||
)
|
@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object SubtitleTrackFingerprint : MethodFingerprint(
|
||||
"Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
|
||||
returnType = "Z",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf(),
|
||||
opcodes = listOf(
|
||||
Opcode.CONST_STRING,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
|
@ -7,13 +7,12 @@ import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.layout.general.autocaptions.bytecode.fingerprints.*
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.fingerprints.SubtitleButtonControllerFingerprint
|
||||
import app.revanced.shared.util.integrations.Constants.GENERAL_LAYOUT
|
||||
|
||||
@ -32,8 +31,8 @@ class AutoCaptionsBytecodePatch : BytecodePatch(
|
||||
StartVideoInformerFingerprint.toPatch(Status.DISABLED),
|
||||
SubtitleButtonControllerFingerprint.toPatch(Status.ENABLED)
|
||||
).forEach { (fingerprint, status) ->
|
||||
with(fingerprint.result ?: return PatchResultError("Failed to find ${fingerprint.name} method.")) {
|
||||
mutableMethod.addInstructions(
|
||||
with(fingerprint.result?.mutableMethod ?: return fingerprint.toErrorResult()) {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, ${status.value}
|
||||
@ -43,19 +42,19 @@ class AutoCaptionsBytecodePatch : BytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
val subtitleTrackMethod = SubtitleTrackFingerprint.result!!.mutableMethod
|
||||
|
||||
subtitleTrackMethod.addInstructions(
|
||||
0, """
|
||||
invoke-static {}, $GENERAL_LAYOUT->hideAutoCaptions()Z
|
||||
move-result v0
|
||||
if-eqz v0, :auto_captions_shown
|
||||
sget-boolean v0, $GENERAL_LAYOUT->captionsButtonStatus:Z
|
||||
if-nez v0, :auto_captions_shown
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
""", listOf(ExternalLabel("auto_captions_shown", subtitleTrackMethod.instruction(0)))
|
||||
)
|
||||
SubtitleTrackFingerprint.result?.mutableMethod?.let {
|
||||
it.addInstructions(
|
||||
0, """
|
||||
invoke-static {}, $GENERAL_LAYOUT->hideAutoCaptions()Z
|
||||
move-result v0
|
||||
if-eqz v0, :auto_captions_shown
|
||||
sget-boolean v0, $GENERAL_LAYOUT->captionsButtonStatus:Z
|
||||
if-nez v0, :auto_captions_shown
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
""", listOf(ExternalLabel("auto_captions_shown", it.instruction(0)))
|
||||
)
|
||||
} ?: return SubtitleTrackFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object EngagementPanelControllerFingerprint : MethodFingerprint(
|
||||
"L",
|
||||
AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
returnType = "L",
|
||||
access = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
strings = listOf(
|
||||
"EngagementPanelController: cannot show EngagementPanel before EngagementPanelController.init() has been called.",
|
||||
"[EngagementPanel] Cannot show EngagementPanel before EngagementPanelController.init() has been called."
|
||||
|
@ -11,6 +11,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.layout.general.autopopuppanels.bytecode.fingerprints.EngagementPanelControllerFingerprint
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.util.integrations.Constants.GENERAL_LAYOUT
|
||||
|
||||
@Name("hide-auto-player-popup-panels-bytecode-patch")
|
||||
@ -22,18 +23,19 @@ class PlayerPopupPanelsBytecodePatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val engagementPanelControllerMethod = EngagementPanelControllerFingerprint.result!!.mutableMethod
|
||||
|
||||
engagementPanelControllerMethod.addInstructions(
|
||||
0, """
|
||||
invoke-static { }, $GENERAL_LAYOUT->hideAutoPlayerPopupPanels()Z
|
||||
move-result v0
|
||||
if-eqz v0, :player_popup_panels_shown
|
||||
if-eqz p4, :player_popup_panels_shown
|
||||
const/4 v0, 0x0
|
||||
return-object v0
|
||||
""", listOf(ExternalLabel("player_popup_panels_shown", engagementPanelControllerMethod.instruction(0)))
|
||||
)
|
||||
EngagementPanelControllerFingerprint.result?.mutableMethod?.let {
|
||||
it.addInstructions(
|
||||
0, """
|
||||
invoke-static {}, $GENERAL_LAYOUT->hideAutoPlayerPopupPanels()Z
|
||||
move-result v0
|
||||
if-eqz v0, :player_popup_panels_shown
|
||||
if-eqz p4, :player_popup_panels_shown
|
||||
const/4 v0, 0x0
|
||||
return-object v0
|
||||
""", listOf(ExternalLabel("player_popup_panels_shown", it.instruction(0)))
|
||||
)
|
||||
} ?: return EngagementPanelControllerFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
@ -12,7 +12,10 @@ import org.jf.dexlib2.Opcode
|
||||
@YouTubeCompatibility
|
||||
@Version("0.0.1")
|
||||
object CreateMixPlaylistFingerprint : MethodFingerprint(
|
||||
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L", "L", "L", "L"), listOf(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
parameters = listOf("L", "L", "L", "L", "L", "L", "L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
|
@ -21,9 +21,9 @@ object FourthCreateMixPlaylistFingerprint : MethodFingerprint(
|
||||
Opcode.CHECK_CAST
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.abclistmenuitemLabelId
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.abclistmenuitemLabelId
|
||||
} == true
|
||||
}
|
||||
)
|
||||
|
@ -12,7 +12,10 @@ import org.jf.dexlib2.Opcode
|
||||
@YouTubeCompatibility
|
||||
@Version("0.0.1")
|
||||
object SecondCreateMixPlaylistFingerprint : MethodFingerprint(
|
||||
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L", "L", "L"), listOf(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
parameters = listOf("L", "L", "L", "L", "L", "L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
|
@ -21,9 +21,9 @@ object ThirdCreateMixPlaylistFingerprint : MethodFingerprint(
|
||||
Opcode.IPUT_OBJECT
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.bottompaneloverlaytextLabelId
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.bottompaneloverlaytextLabelId
|
||||
} == true
|
||||
}
|
||||
)
|
||||
|
@ -4,13 +4,14 @@ import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patches.youtube.layout.general.mixplaylists.bytecode.fingerprints.*
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.injectHideCall
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import org.jf.dexlib2.iface.instruction.Instruction
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
@ -29,34 +30,41 @@ class MixPlaylistsBytecodePatch : BytecodePatch(
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
|
||||
arrayOf(CreateMixPlaylistFingerprint, SecondCreateMixPlaylistFingerprint).forEach(::addHook)
|
||||
ThirdCreateMixPlaylistFingerprint.hookMixPlaylists(true)
|
||||
FourthCreateMixPlaylistFingerprint.hookMixPlaylists(false)
|
||||
arrayOf(
|
||||
CreateMixPlaylistFingerprint,
|
||||
SecondCreateMixPlaylistFingerprint
|
||||
).map {
|
||||
it.result ?: return it.toErrorResult()
|
||||
}.forEach {
|
||||
it.addHook()
|
||||
}
|
||||
|
||||
arrayOf(
|
||||
ThirdCreateMixPlaylistFingerprint to true,
|
||||
FourthCreateMixPlaylistFingerprint to false
|
||||
).map { (fingerprint, boolean) ->
|
||||
fingerprint.result?.hookMixPlaylists(boolean) ?: return fingerprint.toErrorResult()
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private fun addHook(fingerprint: MethodFingerprint) {
|
||||
with (fingerprint.result!!) {
|
||||
val insertIndex = scanResult.patternScanResult!!.endIndex - 3
|
||||
private fun MethodFingerprintResult.addHook() {
|
||||
val insertIndex = scanResult.patternScanResult!!.endIndex - 3
|
||||
val register = (mutableMethod.instruction(insertIndex - 2) as OneRegisterInstruction).registerA
|
||||
|
||||
val register = (mutableMethod.instruction(insertIndex - 2) as OneRegisterInstruction).registerA
|
||||
|
||||
mutableMethod.implementation!!.injectHideCall(insertIndex, register, "layout/GeneralLayoutPatch", "hideMixPlaylists")
|
||||
}
|
||||
mutableMethod.implementation!!.injectHideCall(insertIndex, register, "layout/GeneralLayoutPatch", "hideMixPlaylists")
|
||||
}
|
||||
|
||||
fun MethodFingerprint.hookMixPlaylists(isThirdFingerprint: Boolean) {
|
||||
private fun MethodFingerprintResult.hookMixPlaylists(isThirdFingerprint: Boolean) {
|
||||
fun getRegister(instruction: Instruction): Int {
|
||||
if (isThirdFingerprint) return (instruction as TwoRegisterInstruction).registerA
|
||||
return (instruction as Instruction21c).registerA
|
||||
if (isThirdFingerprint) return (instruction as TwoRegisterInstruction).registerA
|
||||
return (instruction as Instruction21c).registerA
|
||||
}
|
||||
with(this.result!!) {
|
||||
val endIndex = scanResult.patternScanResult!!.endIndex
|
||||
val instruction = method.implementation!!.instructions.elementAt(endIndex)
|
||||
val register = getRegister(instruction)
|
||||
val endIndex = scanResult.patternScanResult!!.endIndex
|
||||
val instruction = method.implementation!!.instructions.elementAt(endIndex)
|
||||
val register = getRegister(instruction)
|
||||
|
||||
mutableMethod.implementation!!.injectHideCall(endIndex, register, "layout/GeneralLayoutPatch", "hideMixPlaylists")
|
||||
}
|
||||
mutableMethod.implementation!!.injectHideCall(endIndex, register, "layout/GeneralLayoutPatch", "hideMixPlaylists")
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ object AccountSwitcherAccessibilityLabelFingerprint : MethodFingerprint(
|
||||
Opcode.NEW_ARRAY,
|
||||
Opcode.CONST_4,
|
||||
Opcode.APUT_OBJECT,
|
||||
Opcode.CONST,
|
||||
Opcode.CONST
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.accountSwitcherAccessibilityLabelId
|
||||
methodDef.implementation?.instructions?.any { it ->
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.accountSwitcherAccessibilityLabelId
|
||||
} == true
|
||||
}
|
||||
)
|
@ -10,6 +10,7 @@ import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patches.youtube.layout.general.personalinformation.bytecode.fingerprints.AccountSwitcherAccessibilityLabelFingerprint
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.util.integrations.Constants.GENERAL_LAYOUT
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@ -22,23 +23,20 @@ class HideEmailAddressBytecodePatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val accountSwitcherAccessibilityLabelResult = AccountSwitcherAccessibilityLabelFingerprint.result!!
|
||||
val accountSwitcherAccessibilityLabelMethod = accountSwitcherAccessibilityLabelResult.mutableMethod
|
||||
|
||||
val setVisibilityConstIndex =
|
||||
accountSwitcherAccessibilityLabelResult.scanResult.patternScanResult!!.endIndex
|
||||
AccountSwitcherAccessibilityLabelFingerprint.result?.let {
|
||||
with (it.mutableMethod) {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val register = (instruction(insertIndex - 2) as OneRegisterInstruction).registerA
|
||||
|
||||
val setVisibilityConstRegister = (
|
||||
accountSwitcherAccessibilityLabelMethod.instruction
|
||||
(setVisibilityConstIndex - 2) as OneRegisterInstruction
|
||||
).registerA
|
||||
|
||||
accountSwitcherAccessibilityLabelMethod.addInstructions(
|
||||
setVisibilityConstIndex, """
|
||||
invoke-static {v$setVisibilityConstRegister}, $GENERAL_LAYOUT->hideEmailAddress(I)I
|
||||
move-result v$setVisibilityConstRegister
|
||||
"""
|
||||
)
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {v$register}, $GENERAL_LAYOUT->hideEmailAddress(I)I
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: return AccountSwitcherAccessibilityLabelFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ object PivotBarCreateButtonViewFingerprint : MethodFingerprint(
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Z"),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.imageOnlyTabId
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.imageOnlyTabId
|
||||
} == true
|
||||
}
|
||||
)
|
@ -17,9 +17,9 @@ object PivotBarFingerprint : MethodFingerprint(
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass == "Lcom/google/android/apps/youtube/app/ui/pivotbar/PivotBar;" &&
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.imageWithTextTabId
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.imageWithTextTabId
|
||||
} == true
|
||||
}
|
||||
)
|
@ -65,14 +65,14 @@ class CreateButtonRemoverBytecodePatch : BytecodePatch(
|
||||
} ?: return PivotBarCreateButtonViewFingerprint.toErrorResult()
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
private companion object {
|
||||
const val hook =
|
||||
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $GENERAL_LAYOUT" +
|
||||
"->" +
|
||||
"hideCreateButton(Landroid/view/View;)V"
|
||||
|
||||
private lateinit var createRef: DexBackedMethodReference
|
||||
lateinit var createRef: DexBackedMethodReference
|
||||
|
||||
private var isSeondary: Boolean = false
|
||||
var isSeondary: Boolean = false
|
||||
}
|
||||
}
|
||||
|
@ -3,19 +3,18 @@ package app.revanced.patches.youtube.layout.general.pivotbar.shortsbutton.byteco
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
|
||||
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.patches.youtube.layout.general.pivotbar.shortsbutton.bytecode.fingerprints.PivotBarEnumFingerprint
|
||||
import app.revanced.patches.youtube.layout.general.pivotbar.shortsbutton.bytecode.fingerprints.PivotBarShortsButtonViewFingerprint
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.fingerprints.PivotBarFingerprint
|
||||
import app.revanced.shared.util.integrations.Constants.GENERAL_LAYOUT
|
||||
import app.revanced.shared.util.pivotbar.InjectionUtils.injectHook
|
||||
import app.revanced.shared.util.pivotbar.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
|
||||
import app.revanced.shared.util.pivotbar.InjectionUtils.injectHook
|
||||
|
||||
@Name("hide-shorts-button")
|
||||
@YouTubeCompatibility
|
||||
@ -29,42 +28,48 @@ class ShortsButtonRemoverBytecodePatch : BytecodePatch(
|
||||
* Resolve fingerprints
|
||||
*/
|
||||
|
||||
val pivotBarResult = PivotBarFingerprint.result ?: return PatchResultError("PivotBarFingerprint failed")
|
||||
val fingerprintResults = arrayOf(PivotBarEnumFingerprint, PivotBarShortsButtonViewFingerprint)
|
||||
.onEach {
|
||||
val resolutionSucceeded = it.resolve(
|
||||
context,
|
||||
pivotBarResult.mutableMethod,
|
||||
pivotBarResult.mutableClass
|
||||
)
|
||||
PivotBarFingerprint.result?.let { parentResult ->
|
||||
with (
|
||||
arrayOf(
|
||||
PivotBarEnumFingerprint,
|
||||
PivotBarShortsButtonViewFingerprint
|
||||
).onEach {
|
||||
it.resolve(
|
||||
context,
|
||||
parentResult.mutableMethod,
|
||||
parentResult.mutableClass
|
||||
)
|
||||
}.map {
|
||||
it.result?.scanResult?.patternScanResult ?: return it.toErrorResult()
|
||||
}
|
||||
) {
|
||||
val enumScanResult = this[0]
|
||||
val buttonViewResult = this[1]
|
||||
|
||||
if (!resolutionSucceeded) return PatchResultError("${it.name} failed")
|
||||
val enumHookInsertIndex = enumScanResult.startIndex + 2
|
||||
val buttonHookInsertIndex = buttonViewResult.endIndex
|
||||
|
||||
mapOf(
|
||||
buttonHook to buttonHookInsertIndex,
|
||||
enumHook to enumHookInsertIndex
|
||||
).forEach { (hook, insertIndex) ->
|
||||
parentResult.mutableMethod.injectHook(hook, insertIndex)
|
||||
}
|
||||
}
|
||||
.map { it.result!!.scanResult.patternScanResult!! }
|
||||
|
||||
val enumScanResult = fingerprintResults[0]
|
||||
val buttonViewResult = fingerprintResults[1]
|
||||
|
||||
val enumHookInsertIndex = enumScanResult.startIndex + 2
|
||||
val buttonHookInsertIndex = buttonViewResult.endIndex
|
||||
|
||||
/*
|
||||
* Inject hooks
|
||||
*/
|
||||
|
||||
val enumHook =
|
||||
"sput-object v$REGISTER_TEMPLATE_REPLACEMENT, $GENERAL_LAYOUT->lastPivotTab:Ljava/lang/Enum;"
|
||||
val buttonHook =
|
||||
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $GENERAL_LAYOUT->hideShortsButton(Landroid/view/View;)V"
|
||||
|
||||
// Inject bottom to top to not mess up the indices
|
||||
mapOf(
|
||||
buttonHook to buttonHookInsertIndex,
|
||||
enumHook to enumHookInsertIndex
|
||||
).forEach { (hook, insertIndex) ->
|
||||
pivotBarResult.mutableMethod.injectHook(hook, insertIndex)
|
||||
}
|
||||
} ?: return PivotBarFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
private companion object {
|
||||
const val enumHook =
|
||||
"sput-object v$REGISTER_TEMPLATE_REPLACEMENT, $GENERAL_LAYOUT" +
|
||||
"->" +
|
||||
"lastPivotTab:Ljava/lang/Enum;"
|
||||
|
||||
const val buttonHook =
|
||||
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $GENERAL_LAYOUT" +
|
||||
"->" +
|
||||
"hideShortsButton(Landroid/view/View;)V"
|
||||
}
|
||||
}
|
@ -30,12 +30,15 @@ class WideSearchbarBytecodePatch : BytecodePatch(
|
||||
WideSearchbarOneParentFingerprint to WideSearchbarOneFingerprint,
|
||||
WideSearchbarTwoParentFingerprint to WideSearchbarTwoFingerprint
|
||||
).map { (parentFingerprint, fingerprint) ->
|
||||
parentFingerprint.result?.let { parentResult ->
|
||||
fingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
|
||||
parentFingerprint.result?.classDef?.let { classDef ->
|
||||
fingerprint.also { it.resolve(context, classDef) }.result?.let {
|
||||
val index = if (fingerprint == WideSearchbarOneFingerprint) it.scanResult.patternScanResult!!.endIndex
|
||||
else it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
val targetMethod =
|
||||
context
|
||||
.toMethodWalker(it.method)
|
||||
.nextMethod(it.scanResult.patternScanResult!!.endIndex, true)
|
||||
.nextMethod(index, true)
|
||||
.getMethod() as MutableMethod
|
||||
|
||||
injectSearchBarHook(targetMethod)
|
||||
|
@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
object LayoutConstructorFingerprint : MethodFingerprint(
|
||||
strings = listOf("1.0x"),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
|
||||
customFingerprint = {
|
||||
it.definingClass.endsWith("YouTubeControlsOverlay;")
|
||||
}
|
||||
)
|
@ -11,6 +11,7 @@ import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.layout.player.autoplaybutton.bytecode.fingerprints.LayoutConstructorFingerprint
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.patches.mapping.ResourceMappingPatch
|
||||
import app.revanced.shared.util.integrations.Constants.PLAYER_LAYOUT
|
||||
import org.jf.dexlib2.iface.instruction.Instruction
|
||||
@ -28,31 +29,33 @@ class HideAutoplayButtonBytecodePatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val layoutGenMethodResult = LayoutConstructorFingerprint.result!!
|
||||
val layoutGenMethod = layoutGenMethodResult.mutableMethod
|
||||
val layoutGenMethodInstructions = layoutGenMethod.implementation!!.instructions
|
||||
|
||||
// resolve the offsets such as ...
|
||||
val autoNavPreviewStubId = ResourceMappingPatch.resourceMappings.single {
|
||||
it.name == "autonav_preview_stub"
|
||||
}.id
|
||||
// where to insert the branch instructions and ...
|
||||
val insertIndex = layoutGenMethodInstructions.indexOfFirst {
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == autoNavPreviewStubId
|
||||
}
|
||||
// where to branch away
|
||||
val branchIndex = layoutGenMethodInstructions.subList(insertIndex + 1, layoutGenMethodInstructions.size - 1).indexOfFirst {
|
||||
((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "addOnLayoutChangeListener"
|
||||
} + 2
|
||||
|
||||
val jumpInstruction = layoutGenMethodInstructions[insertIndex + branchIndex] as Instruction
|
||||
layoutGenMethod.addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {}, $PLAYER_LAYOUT->hideAutoPlayButton()Z
|
||||
move-result v15
|
||||
if-nez v15, :hidden
|
||||
""", listOf(ExternalLabel("hidden", jumpInstruction))
|
||||
)
|
||||
LayoutConstructorFingerprint.result?.mutableMethod?.let { method ->
|
||||
with (method.implementation!!.instructions) {
|
||||
// where to insert the branch instructions and ...
|
||||
val insertIndex = this.indexOfFirst {
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == autoNavPreviewStubId
|
||||
}
|
||||
// where to branch away
|
||||
val branchIndex = this.subList(insertIndex + 1, this.size - 1).indexOfFirst {
|
||||
((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "addOnLayoutChangeListener"
|
||||
} + 2
|
||||
|
||||
val jumpInstruction = this[insertIndex + branchIndex] as Instruction
|
||||
|
||||
method.addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {}, $PLAYER_LAYOUT->hideAutoPlayButton()Z
|
||||
move-result v15
|
||||
if-nez v15, :hidden
|
||||
""", listOf(ExternalLabel("hidden", jumpInstruction))
|
||||
)
|
||||
}
|
||||
} ?: return LayoutConstructorFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.fingerprints.SubtitleButtonControllerFingerprint
|
||||
import app.revanced.shared.util.integrations.Constants.PLAYER_LAYOUT
|
||||
import org.jf.dexlib2.Opcode
|
||||
@ -15,24 +16,27 @@ import org.jf.dexlib2.Opcode
|
||||
@Name("hide-captions-button-bytecode-patch")
|
||||
@YouTubeCompatibility
|
||||
@Version("0.0.1")
|
||||
class HideCaptionsButtonBytecodePatch : BytecodePatch(listOf(
|
||||
SubtitleButtonControllerFingerprint,
|
||||
)) {
|
||||
class HideCaptionsButtonBytecodePatch : BytecodePatch(
|
||||
listOf(
|
||||
SubtitleButtonControllerFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
|
||||
val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod
|
||||
val subtitleButtonControllerMethodInstructions = subtitleButtonControllerMethod.implementation!!.instructions
|
||||
SubtitleButtonControllerFingerprint.result?.mutableMethod?.let {
|
||||
with (it.implementation!!.instructions) {
|
||||
for ((index, instruction) in this.withIndex()) {
|
||||
if (instruction.opcode != Opcode.IGET_BOOLEAN) continue
|
||||
|
||||
for ((index, instruction) in subtitleButtonControllerMethodInstructions.withIndex()) {
|
||||
if (instruction.opcode != Opcode.IGET_BOOLEAN) continue
|
||||
it.addInstruction(
|
||||
index + 1,
|
||||
"invoke-static {v0}, $PLAYER_LAYOUT->hideCaptionsButton(Landroid/widget/ImageView;)V"
|
||||
)
|
||||
|
||||
subtitleButtonControllerMethod.addInstruction(
|
||||
index + 1,
|
||||
"invoke-static {v0}, $PLAYER_LAYOUT->hideCaptionsButton(Landroid/widget/ImageView;)V"
|
||||
)
|
||||
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} ?: return SubtitleButtonControllerFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import org.jf.dexlib2.AccessFlags
|
||||
@YouTubeCompatibility
|
||||
@Version("0.0.1")
|
||||
object InfocardsIncognitoFingerprint : MethodFingerprint(
|
||||
"Ljava/lang/Boolean;",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Ljava/lang/Boolean;",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
strings = listOf("vibrator")
|
||||
)
|
@ -11,7 +11,7 @@ import org.jf.dexlib2.AccessFlags
|
||||
@YouTubeCompatibility
|
||||
@Version("0.0.1")
|
||||
object InfocardsIncognitoParentFingerprint : MethodFingerprint(
|
||||
"Ljava/lang/String;",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Ljava/lang/String;",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
strings = listOf("player_overlay_info_card_teaser"),
|
||||
)
|
@ -11,6 +11,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patches.youtube.layout.player.infocards.bytecode.fingerprints.InfocardsIncognitoFingerprint
|
||||
import app.revanced.patches.youtube.layout.player.infocards.bytecode.fingerprints.InfocardsIncognitoParentFingerprint
|
||||
import app.revanced.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.shared.extensions.toErrorResult
|
||||
import app.revanced.shared.util.integrations.Constants.PLAYER_LAYOUT
|
||||
|
||||
@Name("hide-info-cards-bytecode-patch")
|
||||
@ -20,16 +21,17 @@ class HideInfoCardsBytecodePatch : BytecodePatch(
|
||||
listOf(InfocardsIncognitoParentFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
with(InfocardsIncognitoFingerprint.also {
|
||||
it.resolve(context, InfocardsIncognitoParentFingerprint.result!!.classDef)
|
||||
}.result!!.mutableMethod) {
|
||||
addInstructions(
|
||||
InfocardsIncognitoParentFingerprint.result?.classDef?.let { classDef ->
|
||||
InfocardsIncognitoFingerprint.also {
|
||||
it.resolve(context, classDef)
|
||||
}.result?.mutableMethod?.
|
||||
addInstructions(
|
||||
1, """
|
||||
invoke-static {v0}, $PLAYER_LAYOUT->hideInfoCard(Z)Z
|
||||
move-result v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
"""
|
||||
) ?: return InfocardsIncognitoFingerprint.toErrorResult()
|
||||
} ?: return InfocardsIncognitoParentFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
Reference in New Issue
Block a user