revanced-patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt

83 lines
3.6 KiB
Kotlin

package app.revanced.patches.youtube.misc.playercontrols.bytecode.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
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.PlayerControlsVisibilityFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Name("player-controls-bytecode-patch")
@DependsOn([ResourceMappingResourcePatch::class])
@Description("Manages the code for the player controls of the YouTube player.")
@PlayerControlsCompatibility
@Version("0.0.1")
class PlayerControlsBytecodePatch : BytecodePatch(
listOf(PlayerControlsVisibilityFingerprint)
) {
override fun execute(data: BytecodeData): PatchResult {
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
bottomUiContainerResourceId = ResourceMappingResourcePatch
.resourceMappings
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
// TODO: another solution is required, this is hacky
listOf(BottomControlsInflateFingerprint).resolve(data, data.classes)
inflateFingerprintResult = BottomControlsInflateFingerprint.result!!
return PatchResultSuccess()
}
internal companion object {
var bottomUiContainerResourceId: Long = 0
lateinit var showPlayerControlsFingerprintResult: MethodFingerprintResult
private var inflateFingerprintResult: MethodFingerprintResult? = null
set(fingerprint) {
field = fingerprint!!.also {
moveToRegisterInstructionIndex = it.scanResult.patternScanResult!!.endIndex
viewRegister =
(it.mutableMethod.implementation!!.instructions[moveToRegisterInstructionIndex] as OneRegisterInstruction).registerA
}
}
private var moveToRegisterInstructionIndex: Int = 0
private var viewRegister: Int = 0
/**
* Injects the code to change the visibility of controls.
* @param descriptor The descriptor of the method which should be called.
*/
fun injectVisibilityCheckCall(descriptor: String) {
showPlayerControlsFingerprintResult.mutableMethod.addInstruction(
0,
"""
invoke-static {p1}, $descriptor
"""
)
}
/**
* Injects the code to initialize the controls.
* @param descriptor The descriptor of the method which should be calleed.
*/
fun initializeControl(descriptor: String) {
inflateFingerprintResult!!.mutableMethod.addInstruction(
moveToRegisterInstructionIndex + 1,
"invoke-static {v$viewRegister}, $descriptor"
)
}
}
}