refactor(sponsorblock): sponsorblock button no longer overlaps after video ends

This commit is contained in:
inotia00 2023-03-04 02:33:37 +09:00
parent 50be52cfd8
commit c641d0f625
8 changed files with 66 additions and 79 deletions

View File

@ -8,14 +8,14 @@ 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.annotation.YouTubeCompatibility import app.revanced.patches.shared.annotation.YouTubeCompatibility
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch import app.revanced.patches.youtube.misc.playercontrols.patch.PlayerControlsPatch
import app.revanced.patches.youtube.misc.videoid.mainstream.patch.MainstreamVideoIdPatch import app.revanced.patches.youtube.misc.videoid.mainstream.patch.MainstreamVideoIdPatch
import app.revanced.util.integrations.Constants.BUTTON_PATH import app.revanced.util.integrations.Constants.BUTTON_PATH
@Name("overlay-buttons-bytecode-patch") @Name("overlay-buttons-bytecode-patch")
@DependsOn( @DependsOn(
dependencies = [ dependencies = [
PlayerControlsBytecodePatch::class, PlayerControlsPatch::class,
MainstreamVideoIdPatch::class MainstreamVideoIdPatch::class
] ]
) )
@ -32,8 +32,8 @@ class OverlayButtonsBytecodePatch : BytecodePatch() {
"$BUTTON_PATH/Whitelists;", "$BUTTON_PATH/Whitelists;",
"$BUTTON_PATH/Speed;" "$BUTTON_PATH/Speed;"
).forEach { descriptor -> ).forEach { descriptor ->
PlayerControlsBytecodePatch.initializeControl(descriptor) PlayerControlsPatch.initializeControl(descriptor)
PlayerControlsBytecodePatch.injectVisibility(descriptor) PlayerControlsPatch.injectVisibility(descriptor)
} }
return PatchResultSuccess() return PatchResultSuccess()

View File

@ -1,15 +0,0 @@
package app.revanced.patches.youtube.misc.playercontrols.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object VisibilityNegatedFingerprint : MethodFingerprint(
returnType = "V",
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Z"),
opcodes = listOf(
Opcode.IF_EQZ
)
)

View File

@ -1,19 +0,0 @@
package app.revanced.patches.youtube.misc.playercontrols.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object VisibilityNegatedParentFingerprint : MethodFingerprint(
returnType = "V",
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any {
it.opcode.ordinal == Opcode.CONST.ordinal &&
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.educationTextViewResourceId
} == true
}
)

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.misc.playercontrols.bytecode.patch package app.revanced.patches.youtube.misc.playercontrols.patch
import app.revanced.extensions.toErrorResult import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
@ -7,7 +7,6 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.instruction import app.revanced.patcher.extensions.instruction
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
@ -23,12 +22,11 @@ import org.jf.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.")
@YouTubeCompatibility @YouTubeCompatibility
@Version("0.0.1") @Version("0.0.1")
class PlayerControlsBytecodePatch : BytecodePatch( class PlayerControlsPatch : BytecodePatch(
listOf( listOf(
BottomControlsInflateFingerprint, BottomControlsInflateFingerprint,
ControlsLayoutInflateFingerprint, ControlsLayoutInflateFingerprint,
PlayerControlsVisibilityFingerprint, PlayerControlsVisibilityFingerprint
VisibilityNegatedParentFingerprint
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
@ -45,12 +43,6 @@ class PlayerControlsBytecodePatch : BytecodePatch(
inflateResult = it inflateResult = it
} ?: return BottomControlsInflateFingerprint.toErrorResult() } ?: return BottomControlsInflateFingerprint.toErrorResult()
VisibilityNegatedParentFingerprint.result?.let { parentResult ->
VisibilityNegatedFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
visibilityNegatedResult = it
} ?: return VisibilityNegatedFingerprint.toErrorResult()
} ?: return VisibilityNegatedParentFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }
@ -58,7 +50,6 @@ class PlayerControlsBytecodePatch : BytecodePatch(
lateinit var showPlayerControlsResult: MethodFingerprintResult lateinit var showPlayerControlsResult: MethodFingerprintResult
lateinit var controlsLayoutInflateResult: MethodFingerprintResult lateinit var controlsLayoutInflateResult: MethodFingerprintResult
lateinit var inflateResult: MethodFingerprintResult lateinit var inflateResult: MethodFingerprintResult
lateinit var visibilityNegatedResult: MethodFingerprintResult
fun MethodFingerprintResult.injectVisibilityCall( fun MethodFingerprintResult.injectVisibilityCall(
descriptor: String, descriptor: String,
@ -87,10 +78,6 @@ class PlayerControlsBytecodePatch : BytecodePatch(
showPlayerControlsResult.injectVisibilityCall(descriptor, "changeVisibility") showPlayerControlsResult.injectVisibilityCall(descriptor, "changeVisibility")
} }
fun injectVisibilityNegated(descriptor: String) {
visibilityNegatedResult.injectVisibilityCall(descriptor, "changeVisibilityNegatedImmediate")
}
fun initializeSB(descriptor: String) { fun initializeSB(descriptor: String) {
controlsLayoutInflateResult.injectCalls(descriptor) controlsLayoutInflateResult.injectCalls(descriptor)
} }

View File

@ -23,7 +23,6 @@ class SharedResourcdIdPatch : ResourcePatch {
var bottomUiContainerResourceId: Long = -1 var bottomUiContainerResourceId: Long = -1
var controlsLayoutStubResourceId: Long = -1 var controlsLayoutStubResourceId: Long = -1
var donationCompanionResourceId: Long = -1 var donationCompanionResourceId: Long = -1
var educationTextViewResourceId: Long = -1
var emptycolorLabelId: Long = -1 var emptycolorLabelId: Long = -1
var fabLabelId: Long = -1 var fabLabelId: Long = -1
var floatybarQueueLabelId: Long = -1 var floatybarQueueLabelId: Long = -1
@ -52,7 +51,6 @@ class SharedResourcdIdPatch : ResourcePatch {
bottomUiContainerResourceId = findSharedResourceId("id", "bottom_ui_container_stub") bottomUiContainerResourceId = findSharedResourceId("id", "bottom_ui_container_stub")
controlsLayoutStubResourceId = findSharedResourceId("id", "controls_layout_stub") controlsLayoutStubResourceId = findSharedResourceId("id", "controls_layout_stub")
donationCompanionResourceId = findSharedResourceId("layout", "donation_companion") donationCompanionResourceId = findSharedResourceId("layout", "donation_companion")
educationTextViewResourceId = findSharedResourceId("id", "user_education_text_view")
emptycolorLabelId = findSharedResourceId("color", "inline_time_bar_colorized_bar_empty_color_dark") emptycolorLabelId = findSharedResourceId("color", "inline_time_bar_colorized_bar_empty_color_dark")
fabLabelId = findSharedResourceId("id", "fab") fabLabelId = findSharedResourceId("id", "fab")
floatybarQueueLabelId = findSharedResourceId("string", "floaty_bar_queue_status") floatybarQueueLabelId = findSharedResourceId("string", "floaty_bar_queue_status")

View File

@ -0,0 +1,10 @@
package app.revanced.patches.youtube.misc.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object PlayerControllerFingerprint : MethodFingerprint(
customFingerprint = {
it.definingClass == "Lapp/revanced/integrations/sponsorblock/PlayerController;"
&& it.name == "setSponsorBarRect"
}
)

View File

@ -1,8 +0,0 @@
package app.revanced.patches.youtube.misc.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object PlayerOverlaysLayoutInitFingerprint : MethodFingerprint(
customFingerprint = { it.returnType.endsWith("YouTubePlayerOverlaysLayout;") }
)

View File

@ -5,13 +5,14 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.replaceInstruction
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.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.annotation.YouTubeCompatibility import app.revanced.patches.shared.annotation.YouTubeCompatibility
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch import app.revanced.patches.youtube.misc.playercontrols.patch.PlayerControlsPatch
import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch
import app.revanced.patches.youtube.misc.sponsorblock.bytecode.fingerprints.* import app.revanced.patches.youtube.misc.sponsorblock.bytecode.fingerprints.*
import app.revanced.patches.youtube.misc.timebar.patch.HookTimebarPatch import app.revanced.patches.youtube.misc.timebar.patch.HookTimebarPatch
@ -21,6 +22,7 @@ import app.revanced.util.bytecode.BytecodeHelper.updatePatchStatus
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.BuilderInstruction import org.jf.dexlib2.builder.BuilderInstruction
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction35c import org.jf.dexlib2.iface.instruction.formats.Instruction35c
import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.iface.reference.MethodReference
@ -29,7 +31,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
@DependsOn( @DependsOn(
[ [
MainstreamVideoIdPatch::class, MainstreamVideoIdPatch::class,
PlayerControlsBytecodePatch::class, PlayerControlsPatch::class,
SharedResourcdIdPatch::class SharedResourcdIdPatch::class
] ]
) )
@ -38,24 +40,40 @@ import org.jf.dexlib2.iface.reference.MethodReference
class SponsorBlockBytecodePatch : BytecodePatch( class SponsorBlockBytecodePatch : BytecodePatch(
listOf( listOf(
NextGenWatchLayoutFingerprint, NextGenWatchLayoutFingerprint,
PlayerOverlaysLayoutInitFingerprint PlayerControllerFingerprint
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
/* /*
inject MainstreamVideoIdPatch * Hook the video time methods
*/
with(MainstreamVideoIdPatch) {
videoTimeHook(
INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR,
"setVideoTime"
)
highPrecisionTimeHook(
INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR,
"setHighPrecisionVideoTime"
)
}
/*
* Inject MainstreamVideoIdPatch
*/ */
MainstreamVideoIdPatch.injectCall("$INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V") MainstreamVideoIdPatch.injectCall("$INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V")
/* /*
Seekbar drawing * Seekbar drawing
*/ */
insertMethod = HookTimebarPatch.setTimebarMethod insertMethod = HookTimebarPatch.setTimebarMethod
insertInstructions = insertMethod.implementation!!.instructions insertInstructions = insertMethod.implementation!!.instructions
/* /*
Get the instance of the seekbar rectangle * Get the instance of the seekbar rectangle
*/ */
for ((index, instruction) in insertInstructions.withIndex()) { for ((index, instruction) in insertInstructions.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_DIRECT_RANGE) continue if (instruction.opcode != Opcode.INVOKE_DIRECT_RANGE) continue
@ -74,7 +92,6 @@ class SponsorBlockBytecodePatch : BytecodePatch(
val insertIndex = index + 2 val insertIndex = index + 2
// set the thickness of the segment
insertMethod.addInstruction( insertMethod.addInstruction(
insertIndex, insertIndex,
"invoke-static {v${invokeInstruction.registerC}}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V" "invoke-static {v${invokeInstruction.registerC}}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V"
@ -83,8 +100,8 @@ class SponsorBlockBytecodePatch : BytecodePatch(
} }
/* /*
Set rectangle absolute left and right positions * Set rectangle absolute left and right positions
*/ */
val drawRectangleInstructions = insertInstructions.filter { val drawRectangleInstructions = insertInstructions.filter {
it is ReferenceInstruction && (it.reference as? MethodReference)?.name == "drawRect" && it is FiveRegisterInstruction it is ReferenceInstruction && (it.reference as? MethodReference)?.name == "drawRect" && it is FiveRegisterInstruction
}.map { // TODO: improve code }.map { // TODO: improve code
@ -100,8 +117,8 @@ class SponsorBlockBytecodePatch : BytecodePatch(
} }
/* /*
Draw segment * Draw segment
*/ */
val drawSegmentInstructionInsertIndex = (insertInstructions.size - 1 - 2) val drawSegmentInstructionInsertIndex = (insertInstructions.size - 1 - 2)
val (canvasInstance, centerY) = (insertInstructions[drawSegmentInstructionInsertIndex] as FiveRegisterInstruction).let { val (canvasInstance, centerY) = (insertInstructions[drawSegmentInstructionInsertIndex] as FiveRegisterInstruction).let {
it.registerC to it.registerE it.registerC to it.registerE
@ -112,13 +129,12 @@ class SponsorBlockBytecodePatch : BytecodePatch(
) )
/* /*
Voting & Shield button * Voting & Shield button
*/ */
arrayOf("ShieldButton", "VotingButton").forEach { arrayOf("ShieldButton", "VotingButton").forEach {
PlayerControlsBytecodePatch.initializeSB("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;") PlayerControlsPatch.initializeSB("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;")
PlayerControlsBytecodePatch.injectVisibility("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;") PlayerControlsPatch.injectVisibility("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;")
PlayerControlsBytecodePatch.injectVisibilityNegated("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;")
} }
// set SegmentHelperLayout.context to the player layout instance // set SegmentHelperLayout.context to the player layout instance
@ -128,6 +144,24 @@ class SponsorBlockBytecodePatch : BytecodePatch(
"invoke-static/range {p$instanceRegister}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->addSkipSponsorView15(Landroid/view/View;)V" "invoke-static/range {p$instanceRegister}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->addSkipSponsorView15(Landroid/view/View;)V"
) ?: return NextGenWatchLayoutFingerprint.toErrorResult() ) ?: return NextGenWatchLayoutFingerprint.toErrorResult()
/*
* Replace strings
*/
PlayerControllerFingerprint.result?.mutableMethod?.let {
val instructions = it.implementation!!.instructions
for ((index, instruction) in instructions.withIndex()) {
if (instruction.opcode != Opcode.CONST_STRING) continue
val register = (instruction as OneRegisterInstruction).registerA
it.replaceInstruction(
index,
"const-string v$register, \"${MainstreamVideoIdPatch.reactReference}\""
)
break
}
} ?: return PlayerControllerFingerprint.toErrorResult()
context.injectInit("FirstRun", "initializationSB") context.injectInit("FirstRun", "initializationSB")
context.updatePatchStatus("Sponsorblock") context.updatePatchStatus("Sponsorblock")