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.annotations.DependsOn
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.util.integrations.Constants.BUTTON_PATH
@Name("overlay-buttons-bytecode-patch")
@DependsOn(
dependencies = [
PlayerControlsBytecodePatch::class,
PlayerControlsPatch::class,
MainstreamVideoIdPatch::class
]
)
@ -32,8 +32,8 @@ class OverlayButtonsBytecodePatch : BytecodePatch() {
"$BUTTON_PATH/Whitelists;",
"$BUTTON_PATH/Speed;"
).forEach { descriptor ->
PlayerControlsBytecodePatch.initializeControl(descriptor)
PlayerControlsBytecodePatch.injectVisibility(descriptor)
PlayerControlsPatch.initializeControl(descriptor)
PlayerControlsPatch.injectVisibility(descriptor)
}
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.patcher.annotation.Description
@ -7,7 +7,6 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
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.patch.BytecodePatch
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.")
@YouTubeCompatibility
@Version("0.0.1")
class PlayerControlsBytecodePatch : BytecodePatch(
class PlayerControlsPatch : BytecodePatch(
listOf(
BottomControlsInflateFingerprint,
ControlsLayoutInflateFingerprint,
PlayerControlsVisibilityFingerprint,
VisibilityNegatedParentFingerprint
PlayerControlsVisibilityFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
@ -45,12 +43,6 @@ class PlayerControlsBytecodePatch : BytecodePatch(
inflateResult = it
} ?: 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()
}
@ -58,7 +50,6 @@ class PlayerControlsBytecodePatch : BytecodePatch(
lateinit var showPlayerControlsResult: MethodFingerprintResult
lateinit var controlsLayoutInflateResult: MethodFingerprintResult
lateinit var inflateResult: MethodFingerprintResult
lateinit var visibilityNegatedResult: MethodFingerprintResult
fun MethodFingerprintResult.injectVisibilityCall(
descriptor: String,
@ -87,10 +78,6 @@ class PlayerControlsBytecodePatch : BytecodePatch(
showPlayerControlsResult.injectVisibilityCall(descriptor, "changeVisibility")
}
fun injectVisibilityNegated(descriptor: String) {
visibilityNegatedResult.injectVisibilityCall(descriptor, "changeVisibilityNegatedImmediate")
}
fun initializeSB(descriptor: String) {
controlsLayoutInflateResult.injectCalls(descriptor)
}

View File

@ -23,7 +23,6 @@ class SharedResourcdIdPatch : ResourcePatch {
var bottomUiContainerResourceId: Long = -1
var controlsLayoutStubResourceId: Long = -1
var donationCompanionResourceId: Long = -1
var educationTextViewResourceId: Long = -1
var emptycolorLabelId: Long = -1
var fabLabelId: Long = -1
var floatybarQueueLabelId: Long = -1
@ -52,7 +51,6 @@ class SharedResourcdIdPatch : ResourcePatch {
bottomUiContainerResourceId = findSharedResourceId("id", "bottom_ui_container_stub")
controlsLayoutStubResourceId = findSharedResourceId("id", "controls_layout_stub")
donationCompanionResourceId = findSharedResourceId("layout", "donation_companion")
educationTextViewResourceId = findSharedResourceId("id", "user_education_text_view")
emptycolorLabelId = findSharedResourceId("color", "inline_time_bar_colorized_bar_empty_color_dark")
fabLabelId = findSharedResourceId("id", "fab")
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.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
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.sponsorblock.bytecode.fingerprints.*
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.builder.BuilderInstruction
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.formats.Instruction35c
import org.jf.dexlib2.iface.reference.MethodReference
@ -29,7 +31,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
@DependsOn(
[
MainstreamVideoIdPatch::class,
PlayerControlsBytecodePatch::class,
PlayerControlsPatch::class,
SharedResourcdIdPatch::class
]
)
@ -38,24 +40,40 @@ import org.jf.dexlib2.iface.reference.MethodReference
class SponsorBlockBytecodePatch : BytecodePatch(
listOf(
NextGenWatchLayoutFingerprint,
PlayerOverlaysLayoutInitFingerprint
PlayerControllerFingerprint
)
) {
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")
/*
Seekbar drawing
* Seekbar drawing
*/
insertMethod = HookTimebarPatch.setTimebarMethod
insertInstructions = insertMethod.implementation!!.instructions
/*
Get the instance of the seekbar rectangle
* Get the instance of the seekbar rectangle
*/
for ((index, instruction) in insertInstructions.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_DIRECT_RANGE) continue
@ -74,7 +92,6 @@ class SponsorBlockBytecodePatch : BytecodePatch(
val insertIndex = index + 2
// set the thickness of the segment
insertMethod.addInstruction(
insertIndex,
"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 {
it is ReferenceInstruction && (it.reference as? MethodReference)?.name == "drawRect" && it is FiveRegisterInstruction
}.map { // TODO: improve code
@ -100,8 +117,8 @@ class SponsorBlockBytecodePatch : BytecodePatch(
}
/*
Draw segment
*/
* Draw segment
*/
val drawSegmentInstructionInsertIndex = (insertInstructions.size - 1 - 2)
val (canvasInstance, centerY) = (insertInstructions[drawSegmentInstructionInsertIndex] as FiveRegisterInstruction).let {
it.registerC to it.registerE
@ -112,13 +129,12 @@ class SponsorBlockBytecodePatch : BytecodePatch(
)
/*
Voting & Shield button
* Voting & Shield button
*/
arrayOf("ShieldButton", "VotingButton").forEach {
PlayerControlsBytecodePatch.initializeSB("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;")
PlayerControlsBytecodePatch.injectVisibility("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;")
PlayerControlsBytecodePatch.injectVisibilityNegated("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;")
PlayerControlsPatch.initializeSB("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;")
PlayerControlsPatch.injectVisibility("$INTEGRATIONS_BUTTON_CLASS_DESCRIPTOR/$it;")
}
// 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"
) ?: 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.updatePatchStatus("Sponsorblock")