cleanup YouTube Music patches

This commit is contained in:
inotia00 2023-02-13 17:11:22 +09:00
parent 0bfc5a2fd9
commit e3b11f2680
24 changed files with 348 additions and 345 deletions

View File

@ -9,27 +9,24 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.patches.videoads.GeneralVideoAdsPatch
import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
@Patch
@Name("hide-music-ads")
@Description("Removes ads in the music player.")
@DependsOn(
[
GeneralVideoAdsPatch::class,
MusicIntegrationsPatch::class,
MusicSettingsPatch::class
]
)
@Name("hide-music-ads")
@Description("Removes ads in the music player.")
@YouTubeMusicCompatibility
@Version("0.0.1")
class MusicVideoAdsPatch : BytecodePatch() {
override fun execute(context: BytecodeContext): PatchResult {
val INTEGRATIONS_CLASS_DESCRIPTOR = "$MUSIC_SETTINGS_PATH->hideMusicAds()Z"
GeneralVideoAdsPatch.injectLegacyAds(INTEGRATIONS_CLASS_DESCRIPTOR)
@ -37,4 +34,7 @@ class MusicVideoAdsPatch : BytecodePatch() {
return PatchResultSuccess()
}
private companion object {
const val INTEGRATIONS_CLASS_DESCRIPTOR = "$MUSIC_SETTINGS_PATH->hideMusicAds()Z"
}
}

View File

@ -15,7 +15,6 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.audio.codecs.fingerprints.*
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
@ -24,9 +23,9 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.Method
@Patch
@DependsOn([MusicIntegrationsPatch::class, MusicSettingsPatch::class])
@Name("enable-opus-codec")
@Description("Enable opus codec when playing audio.")
@DependsOn([MusicSettingsPatch::class])
@YouTubeMusicCompatibility
@Version("0.0.1")
class CodecsUnlockPatch : BytecodePatch(

View File

@ -12,6 +12,7 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AudioOnlyEnablerFingerprint
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
@Patch
@Name("exclusive-audio-playback")
@ -24,9 +25,11 @@ class ExclusiveAudioPatch : BytecodePatch(
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val method = AudioOnlyEnablerFingerprint.result!!.mutableMethod
method.replaceInstruction(method.implementation!!.instructions.count() - 1, "const/4 v0, 0x1")
method.addInstruction("return v0")
AudioOnlyEnablerFingerprint.result?.mutableMethod?.let {
it.replaceInstruction(it.implementation!!.instructions.count() - 1, "const/4 v0, 0x1")
it.addInstruction("return v0")
} ?: return AudioOnlyEnablerFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -17,9 +17,9 @@ object TabLayoutFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.colorGreyLabelId
methodDef.implementation?.instructions?.any {
it.opcode.ordinal == Opcode.CONST.ordinal &&
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.colorGreyLabelId
} == true
}
)

View File

@ -13,7 +13,6 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.layout.blacknavbar.fingerprints.TabLayoutFingerprint
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.resourceid.patch.SharedResourcdIdPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
@ -26,7 +25,6 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction31i
@Description("Sets the navigation bar color to black.")
@DependsOn(
[
MusicIntegrationsPatch::class,
MusicSettingsPatch::class,
SharedResourcdIdPatch::class
]

View File

@ -6,23 +6,22 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
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.music.layout.castbutton.fingerprints.HideCastButtonFingerprint
import app.revanced.patches.music.layout.castbutton.fingerprints.HideCastButtonParentFingerprint
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
@Patch
@DependsOn([MusicIntegrationsPatch::class, MusicSettingsPatch::class])
@Name("hide-music-cast-button")
@Description("Hides the cast button in the video player and header")
@DependsOn([MusicSettingsPatch::class])
@YouTubeMusicCompatibility
@Version("0.0.1")
class HideWatermarkPatch : BytecodePatch(
@ -31,16 +30,15 @@ class HideWatermarkPatch : BytecodePatch(
)
) {
override fun execute(context: BytecodeContext): PatchResult {
HideCastButtonFingerprint.resolve(context, HideCastButtonParentFingerprint.result!!.classDef)
val result = HideCastButtonFingerprint.result
?: return PatchResultError("Required parent method could not be found.")
result.mutableMethod.addInstructions(
0, """
invoke-static {p1}, $MUSIC_SETTINGS_PATH->hideCastButton(I)I
move-result p1
"""
)
HideCastButtonParentFingerprint.result?.let { parentResult ->
HideCastButtonFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.addInstructions(
0, """
invoke-static {p1}, $MUSIC_SETTINGS_PATH->hideCastButton(I)I
move-result p1
"""
) ?: return HideCastButtonFingerprint.toErrorResult()
} ?: return HideCastButtonParentFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -1,26 +0,0 @@
package app.revanced.patches.music.layout.compactheader.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 CompactHeaderConstructorFingerprint : MethodFingerprint(
returnType = "V",
access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L", "L", "L", "L", "L"),
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST
)
)

View File

@ -4,44 +4,76 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.music.layout.compactheader.fingerprints.CompactHeaderConstructorFingerprint
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.findMutableMethodOf
import app.revanced.shared.extensions.toResult
import app.revanced.shared.patches.mapping.ResourceMappingPatch
import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
import org.jf.dexlib2.builder.instruction.BuilderInstruction11x
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
@Patch
@DependsOn([MusicIntegrationsPatch::class, MusicSettingsPatch::class])
@Name("hide-compact-header")
@Description("Hides the music category bar at the top of the homepage.")
@DependsOn(
[
ResourceMappingPatch::class,
MusicSettingsPatch::class
]
)
@YouTubeMusicCompatibility
@Version("0.0.1")
class CompactHeaderPatch : BytecodePatch(
listOf(
CompactHeaderConstructorFingerprint
)
) {
class CompactHeaderPatch : BytecodePatch() {
// list of resource names to get the id of
private val resourceIds = arrayOf(
"layout" to "chip_cloud"
).map { (type, name) ->
ResourceMappingPatch
.resourceMappings
.single { it.type == type && it.name == name }.id
}
private var patchSuccessArray = Array(resourceIds.size) {false}
override fun execute(context: BytecodeContext): PatchResult {
val result = CompactHeaderConstructorFingerprint.result!!
val method = result.mutableMethod
context.classes.forEach { classDef ->
classDef.methods.forEach { method ->
with(method.implementation) {
this?.instructions?.forEachIndexed { index, instruction ->
when (instruction.opcode) {
Opcode.CONST -> {
when ((instruction as Instruction31i).wideLiteral) {
resourceIds[0] -> { // compact header
val insertIndex = index + 4
val invokeInstruction = instructions.elementAt(insertIndex)
if (invokeInstruction.opcode != Opcode.CHECK_CAST) return@forEachIndexed
val insertIndex = result.scanResult.patternScanResult!!.endIndex
val register = (method.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA
method.addInstructions(
insertIndex, """
invoke-static {}, $MUSIC_SETTINGS_PATH->hideCompactHeader()I
move-result v2
invoke-virtual {v${register}, v2}, Landroid/view/View;->setVisibility(I)V
"""
)
val mutableMethod = context.proxy(classDef).mutableClass.findMutableMethodOf(method)
return PatchResultSuccess()
val register = (invokeInstruction as Instruction21c).registerA
mutableMethod.addInstruction(
insertIndex,
"invoke-static { v$register }, $MUSIC_SETTINGS_PATH->hideCompactHeader(Landroid/view/View;)V"
)
patchSuccessArray[0] = true;
}
}
}
else -> return@forEachIndexed
}
}
}
}
}
return toResult(patchSuccessArray.indexOf(false))
}
}

View File

@ -11,6 +11,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
@Patch
@Name("minimized-playback-music")
@ -23,9 +24,10 @@ class MinimizedPlaybackPatch : BytecodePatch(
)
) {
override fun execute(context: BytecodeContext): PatchResult {
MinimizedPlaybackManagerFingerprint.result!!.mutableMethod.addInstruction(
MinimizedPlaybackManagerFingerprint.result?.mutableMethod?.addInstruction(
0, "return-void"
)
) ?: return MinimizedPlaybackManagerFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -12,17 +12,17 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.layout.minimizedplayer.fingerprints.MinimizedPlayerFingerprint
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@DependsOn([MusicIntegrationsPatch::class, MusicSettingsPatch::class])
@Name("enable-force-minimized-player")
@Description("Permanently keep player minimized even if another track is played.")
@DependsOn([MusicSettingsPatch::class])
@YouTubeMusicCompatibility
@Version("0.0.1")
class MinimizedPlayerPatch : BytecodePatch(
@ -32,19 +32,21 @@ class MinimizedPlayerPatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext): PatchResult {
val result = MinimizedPlayerFingerprint.result!!
val method = result.mutableMethod
val index = result.scanResult.patternScanResult!!.endIndex
val register = (method.implementation!!.instructions[index - 1] as OneRegisterInstruction).registerA - 1
val jumpInstruction = method.implementation!!.instructions[index + 1] as Instruction
MinimizedPlayerFingerprint.result?.let {
with (it.mutableMethod) {
val index = it.scanResult.patternScanResult!!.endIndex
val register = (implementation!!.instructions[index - 1] as OneRegisterInstruction).registerA - 1
val jumpInstruction = implementation!!.instructions[index + 1] as Instruction
method.addInstructions(
index, """
invoke-static {}, $MUSIC_SETTINGS_PATH->enableForceMinimizedPlayer()Z
move-result v$register
if-nez v$register, :enforce
""", listOf(ExternalLabel("enforce", jumpInstruction))
)
addInstructions(
index, """
invoke-static {}, $MUSIC_SETTINGS_PATH->enableForceMinimizedPlayer()Z
move-result v$register
if-nez v$register, :enforce
""", listOf(ExternalLabel("enforce", jumpInstruction))
)
}
} ?: return MinimizedPlayerFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -7,16 +7,16 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
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.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.layout.miniplayercolor.fingerprints.MiniplayerColorFingerprint
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import app.revanced.shared.fingerprints.MiniplayerColorParentFingerprint
import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
import org.jf.dexlib2.iface.instruction.Instruction
@ -25,9 +25,9 @@ import org.jf.dexlib2.iface.reference.FieldReference
import org.jf.dexlib2.iface.reference.MethodReference
@Patch
@DependsOn([MusicIntegrationsPatch::class, MusicSettingsPatch::class])
@Name("enable-color-match-player")
@Description("Matches the fullscreen player color with the minimized one.")
@DependsOn([MusicSettingsPatch::class])
@YouTubeMusicCompatibility
@Version("0.0.1")
class MiniplayerColorPatch : BytecodePatch(
@ -37,64 +37,70 @@ class MiniplayerColorPatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext): PatchResult {
val miniplayerColorParentResult = MiniplayerColorParentFingerprint.result!!
val miniplayerColorParentMethod = miniplayerColorParentResult.mutableMethod
MiniplayerColorParentFingerprint.result?.let { parentResult ->
MiniplayerColorFingerprint.resolve(context, miniplayerColorParentResult.classDef)
val miniplayerColorResult = MiniplayerColorFingerprint.result!!
val miniplayerColorMethod = miniplayerColorResult.mutableMethod
val insertIndex = miniplayerColorResult.scanResult.patternScanResult!!.startIndex + 1
val jumpInstruction = miniplayerColorMethod.implementation!!.instructions[insertIndex] as Instruction
with (parentResult.mutableMethod.implementation!!.instructions) {
firstReference =
(elementAt(4) as ReferenceInstruction).reference as FieldReference
val Reference_A_1 =
miniplayerColorParentMethod.let { method ->
(method.implementation!!.instructions.elementAt(4) as ReferenceInstruction).reference as FieldReference
}
val Reference_A_2 =
miniplayerColorParentMethod.let { method ->
(method.implementation!!.instructions.elementAt(5) as ReferenceInstruction).reference as FieldReference
}
val Reference_A_3 =
miniplayerColorParentMethod.let { method ->
(method.implementation!!.instructions.elementAt(6) as ReferenceInstruction).reference as MethodReference
}
val Reference_B_1 =
miniplayerColorParentMethod.let { method ->
(method.implementation!!.instructions.elementAt(10) as ReferenceInstruction).reference as FieldReference
}
val Reference_B_2 =
miniplayerColorParentMethod.let { method ->
(method.implementation!!.instructions.elementAt(11) as ReferenceInstruction).reference as FieldReference
}
val Reference_B_3 =
miniplayerColorParentMethod.let { method ->
(method.implementation!!.instructions.elementAt(12) as ReferenceInstruction).reference as MethodReference
secondReference =
(elementAt(5) as ReferenceInstruction).reference as FieldReference
thirdReference =
(elementAt(6) as ReferenceInstruction).reference as MethodReference
fourthReference =
(elementAt(10) as ReferenceInstruction).reference as FieldReference
fifthReference =
(elementAt(11) as ReferenceInstruction).reference as FieldReference
sixthReference =
(elementAt(12) as ReferenceInstruction).reference as MethodReference
}
miniplayerColorMethod.addInstructions(
insertIndex, """
invoke-static {}, $MUSIC_SETTINGS_PATH->enableColorMatchPlayer()Z
move-result v2
if-eqz v2, :off
iget v0, p0, ${miniplayerColorResult.classDef.type}->${Reference_A_1.name}:${Reference_A_1.type}
if-eq v0, v2, :abswitch
iput v2, p0, ${miniplayerColorResult.classDef.type}->${Reference_A_1.name}:${Reference_A_1.type}
iget-object v0, p0, ${miniplayerColorResult.classDef.type}->${Reference_A_2.name}:${Reference_A_2.type}
invoke-virtual {v0, v2, p2, p3}, $Reference_A_3
:abswitch
iget v0, p0, ${miniplayerColorResult.classDef.type}->${Reference_B_1.name}:${Reference_B_1.type}
if-eq v0, v1, :exit
iput v1, p0, ${miniplayerColorResult.classDef.type}->${Reference_B_1.name}:${Reference_B_1.type}
iget-object v0, p0, ${miniplayerColorResult.classDef.type}->${Reference_B_2.name}:${Reference_B_2.type}
invoke-virtual {v0, v1, p2, p3}, $Reference_B_3
goto :exit
:off
invoke-direct {p0}, ${miniplayerColorResult.classDef.type}->${miniplayerColorParentResult.mutableMethod.name}()V
""", listOf(ExternalLabel("exit", jumpInstruction))
)
MiniplayerColorFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
with (it.mutableMethod) {
val insertIndex = it.scanResult.patternScanResult!!.startIndex + 1
val jumpInstruction = implementation!!.instructions[insertIndex] as Instruction
miniplayerColorMethod.removeInstruction(insertIndex - 1)
val type = it.classDef.type
addInstructions(
insertIndex, """
invoke-static {}, $MUSIC_SETTINGS_PATH->enableColorMatchPlayer()Z
move-result v2
if-eqz v2, :off
iget v0, p0, ${type}->${firstReference.name}:${firstReference.type}
if-eq v0, v2, :abswitch
iput v2, p0, ${type}->${firstReference.name}:${firstReference.type}
iget-object v0, p0, ${type}->${secondReference.name}:${secondReference.type}
invoke-virtual {v0, v2, p2, p3}, $thirdReference
:abswitch
iget v0, p0, ${type}->${fourthReference.name}:${fourthReference.type}
if-eq v0, v1, :exit
iput v1, p0, ${type}->${fourthReference.name}:${fourthReference.type}
iget-object v0, p0, ${type}->${fifthReference.name}:${fifthReference.type}
invoke-virtual {v0, v1, p2, p3}, $sixthReference
goto :exit
:off
invoke-direct {p0}, ${type}->${parentResult.mutableMethod.name}()V
""", listOf(ExternalLabel("exit", jumpInstruction))
)
removeInstruction(insertIndex - 1)
}
} ?: return MiniplayerColorFingerprint.toErrorResult()
} ?: return MiniplayerColorParentFingerprint.toErrorResult()
return PatchResultSuccess()
}
private companion object {
private lateinit var firstReference: FieldReference
private lateinit var secondReference: FieldReference
private lateinit var thirdReference: MethodReference
private lateinit var fourthReference: FieldReference
private lateinit var fifthReference: FieldReference
private lateinit var sixthReference: MethodReference
}
}

View File

@ -5,11 +5,11 @@ 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.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
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.patch.annotations.Patch
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
@ -18,14 +18,14 @@ import app.revanced.shared.extensions.toErrorResult
import app.revanced.shared.patches.mapping.ResourceMappingPatch
import app.revanced.shared.util.integrations.Constants.INTEGRATIONS_PATH
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
@Patch
@DependsOn([MusicIntegrationsPatch::class])
@Name("hide-get-premium")
@Description("Removes all \"Get Premium\" evidences from the avatar menu.")
@DependsOn([MusicIntegrationsPatch::class])
@YouTubeMusicCompatibility
@Version("0.0.1")
class HideGetPremiumPatch : BytecodePatch(

View File

@ -14,20 +14,17 @@ import app.revanced.patcher.util.TypeUtil.traverseClassHierarchy
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.music.layout.shuffle.fingerprints.MusicPlaybackControlsFingerprint
import app.revanced.patches.music.layout.shuffle.fingerprints.ShuffleClassFingerprint
import app.revanced.patches.music.layout.shuffle.fingerprints.ShuffleClassReferenceFingerprint
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.layout.shuffle.fingerprints.*
import app.revanced.patches.music.misc.resourceid.patch.SharedResourcdIdPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import app.revanced.shared.extensions.transformFields
import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
import org.jf.dexlib2.iface.reference.MethodReference
import org.jf.dexlib2.immutable.ImmutableField
import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodImplementation
@ -36,7 +33,12 @@ import org.jf.dexlib2.immutable.ImmutableMethodParameter
@Patch
@Name("enable-force-shuffle")
@Description("Enable force shuffle even if another track is played.")
@DependsOn([MusicIntegrationsPatch::class, MusicSettingsPatch::class, SharedResourcdIdPatch::class])
@DependsOn(
[
MusicSettingsPatch::class,
SharedResourcdIdPatch::class
]
)
@YouTubeMusicCompatibility
@Version("0.0.1")
class EnforceShufflePatch : BytecodePatch(
@ -48,33 +50,33 @@ class EnforceShufflePatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext): PatchResult {
with(ShuffleClassReferenceFingerprint.result!!) {
val startIndex = scanResult.patternScanResult!!.startIndex
val endIndex = scanResult.patternScanResult!!.endIndex
val referenceInstructions = mutableMethod.implementation!!.instructions
ShuffleClassReferenceFingerprint.result?.let { result ->
val startIndex = result.scanResult.patternScanResult!!.startIndex
val endIndex = result.scanResult.patternScanResult!!.endIndex
SHUFFLE_CLASS = result.classDef.type
SHUFFLE_CLASS = classDef.type
firstRef = (referenceInstructions.elementAt(startIndex) as ReferenceInstruction).reference as FieldReference
secondRef = (referenceInstructions.elementAt(startIndex + 1) as ReferenceInstruction).reference as DexBackedMethodReference
thirdRef = (referenceInstructions.elementAt(endIndex) as ReferenceInstruction).reference as FieldReference
with (result.mutableMethod.implementation!!.instructions) {
firstRef = (elementAt(startIndex) as ReferenceInstruction).reference as FieldReference
secondRef = (elementAt(startIndex + 1) as ReferenceInstruction).reference as DexBackedMethodReference
thirdRef = (elementAt(endIndex) as ReferenceInstruction).reference as FieldReference
referenceInstructions.filter { instruction ->
val fieldReference = (instruction as? ReferenceInstruction)?.reference as? FieldReference
fieldReference?.let { it.type == "Landroid/widget/ImageView;" } == true
}.forEach { instruction ->
fourthRef = (instruction as ReferenceInstruction).reference as FieldReference
this.filter { instruction ->
val fieldReference = (instruction as? ReferenceInstruction)?.reference as? FieldReference
fieldReference?.let { it.type == "Landroid/widget/ImageView;" } == true
}.forEach { instruction ->
fourthRef = (instruction as ReferenceInstruction).reference as FieldReference
}
}
}
} ?: return ShuffleClassReferenceFingerprint.toErrorResult()
with(ShuffleClassFingerprint.result!!) {
val insertIndex = scanResult.patternScanResult!!.endIndex
mutableMethod.addInstruction(
insertIndex,
ShuffleClassFingerprint.result?.let {
it.mutableMethod.addInstruction(
it.scanResult.patternScanResult!!.endIndex,
"sput-object p0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleclass:$SHUFFLE_CLASS"
)
context.traverseClassHierarchy(mutableClass) {
context.traverseClassHierarchy(it.mutableClass) {
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL
transformFields {
ImmutableField(
@ -88,18 +90,18 @@ class EnforceShufflePatch : BytecodePatch(
).toMutable()
}
}
}
} ?: return ShuffleClassFingerprint.toErrorResult()
with(MusicPlaybackControlsFingerprint.result!!) {
val referenceInstructions = mutableMethod.implementation!!.instructions
MusicPlaybackControlsFingerprint.result?.let {
with (it.mutableMethod.implementation!!.instructions) {
fifthRef = (elementAt(0) as ReferenceInstruction).reference as FieldReference
sixthRef = (elementAt(1) as ReferenceInstruction).reference as DexBackedMethodReference
}
fifthRef = (referenceInstructions.elementAt(0) as ReferenceInstruction).reference as FieldReference
sixthRef = (referenceInstructions.elementAt(1) as ReferenceInstruction).reference as DexBackedMethodReference
mutableClass.staticFields.add(
it.mutableClass.staticFields.add(
ImmutableField(
mutableMethod.definingClass,
it.mutableMethod.definingClass,
"shuffleclass",
SHUFFLE_CLASS,
AccessFlags.PUBLIC or AccessFlags.STATIC,
@ -109,7 +111,7 @@ class EnforceShufflePatch : BytecodePatch(
).toMutable()
)
mutableMethod.addInstructions(
it.mutableMethod.addInstructions(
0,
"""
invoke-virtual {v0, v1}, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->buttonHook(Z)V
@ -117,9 +119,9 @@ class EnforceShufflePatch : BytecodePatch(
"""
)
mutableClass.methods.add(
it.mutableClass.methods.add(
ImmutableMethod(
classDef.type,
it.classDef.type,
"buttonHook",
listOf(ImmutableMethodParameter("Z", null, null)),
"V",
@ -152,7 +154,7 @@ class EnforceShufflePatch : BytecodePatch(
)
).toMutable()
)
}
} ?: return MusicPlaybackControlsFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -5,17 +5,16 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.annotations.DependsOn
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.patch.annotations.Patch
import app.revanced.patches.music.layout.tabletmode.fingerprints.TabletLayoutFingerprint
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.resourceid.patch.SharedResourcdIdPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
@Patch
@ -23,7 +22,6 @@ import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
@Description("Enable landscape mode on phone.")
@DependsOn(
[
MusicIntegrationsPatch::class,
MusicSettingsPatch::class,
SharedResourcdIdPatch::class
]
@ -36,18 +34,14 @@ class TabletModePatch : BytecodePatch(
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val result = TabletLayoutFingerprint.result!!
val method = result.mutableMethod
val endIndex = result.scanResult.patternScanResult!!.endIndex
val insertIndex = endIndex + 1
method.addInstructions(
insertIndex, """
TabletLayoutFingerprint.result?.let {
it.mutableMethod.addInstructions(
it.scanResult.patternScanResult!!.endIndex + 1, """
invoke-static {p0}, $MUSIC_SETTINGS_PATH->enableTabletMode(Z)Z
move-result p0
"""
)
)
} ?: return TabletLayoutFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -11,6 +11,7 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.music.layout.tastebuilder.fingerprints.TasteBuilderConstructorFingerprint
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
@Patch
@ -24,17 +25,19 @@ class RemoveTasteBuilderPatch : BytecodePatch(
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val result = TasteBuilderConstructorFingerprint.result!!
val method = result.mutableMethod
TasteBuilderConstructorFingerprint.result?.let {
with (it.mutableMethod) {
val insertIndex = it.scanResult.patternScanResult!!.endIndex - 8
val register = (implementation!!.instructions[insertIndex] as Instruction22c).registerA
val insertIndex = result.scanResult.patternScanResult!!.endIndex - 8
val register = (method.implementation!!.instructions[insertIndex] as Instruction22c).registerA
method.addInstructions(
insertIndex, """
const/16 v1, 0x8
invoke-virtual {v${register}, v1}, Landroid/view/View;->setVisibility(I)V
"""
)
addInstructions(
insertIndex, """
const/16 v1, 0x8
invoke-virtual {v${register}, v1}, Landroid/view/View;->setVisibility(I)V
"""
)
}
} ?: return TasteBuilderConstructorFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -12,6 +12,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.music.layout.upgradebutton.fingerprints.PivotBarConstructorFingerprint
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import org.jf.dexlib2.builder.instruction.BuilderInstruction22t
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@ -28,7 +29,7 @@ class RemoveUpgradeButtonPatch : BytecodePatch(
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val result = PivotBarConstructorFingerprint.result!!
val result = PivotBarConstructorFingerprint.result?: return PivotBarConstructorFingerprint.toErrorResult()
val implementation = result.mutableMethod.implementation!!
val pivotBarElementFieldRef =

View File

@ -6,25 +6,25 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.*
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.layout.zenmode.fingerprints.ZenModeFingerprint
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import app.revanced.shared.fingerprints.MiniplayerColorParentFingerprint
import app.revanced.shared.util.integrations.Constants.MUSIC_SETTINGS_PATH
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
@Patch
@Name("enable-zen-mode")
@Description("Adds a grey tint to the video player to reduce eye strain.")
@DependsOn([MusicIntegrationsPatch::class, MusicSettingsPatch::class])
@DependsOn([MusicSettingsPatch::class])
@YouTubeMusicCompatibility
@Version("0.0.1")
class ZenModePatch : BytecodePatch(
@ -34,39 +34,38 @@ class ZenModePatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext): PatchResult {
val miniplayerColorParentResult = MiniplayerColorParentFingerprint.result!!
MiniplayerColorParentFingerprint.result?.let { parentResult ->
ZenModeFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
with (it.mutableMethod) {
val instructions = this.implementation!!.instructions
val startIndex = it.scanResult.patternScanResult!!.startIndex
ZenModeFingerprint.resolve(context, miniplayerColorParentResult.classDef)
val ZenModeResult = ZenModeFingerprint.result!!
val ZenModeMethod = ZenModeResult.mutableMethod
val ZenModeInstructions = ZenModeMethod.implementation!!.instructions
val firstRegister = (instruction(startIndex) as OneRegisterInstruction).registerA
val secondRegister = (instruction(startIndex + 2) as OneRegisterInstruction).registerA
val dummyRegister = secondRegister + 1
val startIndex = ZenModeResult.scanResult.patternScanResult!!.startIndex
val referenceIndex = it.scanResult.patternScanResult!!.endIndex + 1
val fieldReference = (instructions.elementAt(referenceIndex) as ReferenceInstruction).reference as FieldReference
val firstRegister = (ZenModeMethod.instruction(startIndex) as OneRegisterInstruction).registerA
val secondRegister = (ZenModeMethod.instruction(startIndex + 2) as OneRegisterInstruction).registerA
val dummyRegister = secondRegister + 1
val insertIndex = referenceIndex + 1
val referenceIndex = ZenModeResult.scanResult.patternScanResult!!.endIndex + 1
val Ref = (ZenModeInstructions.elementAt(referenceIndex) as ReferenceInstruction).reference as FieldReference
val insertIndex = referenceIndex + 1
ZenModeMethod.addInstructions(
insertIndex, """
invoke-static {}, $MUSIC_SETTINGS_PATH->enableZenMode()Z
move-result v$dummyRegister
if-eqz v$dummyRegister, :off
const v$dummyRegister, -0xfcfcfd
if-ne v$firstRegister, v$dummyRegister, :off
const v$firstRegister, -0xbfbfc0
const v$secondRegister, -0xbfbfc0
:off
sget-object v0, ${Ref.type}->${Ref.name}:${Ref.type}
"""
)
ZenModeMethod.removeInstruction(insertIndex - 1)
addInstructions(
insertIndex, """
invoke-static {}, $MUSIC_SETTINGS_PATH->enableZenMode()Z
move-result v$dummyRegister
if-eqz v$dummyRegister, :off
const v$dummyRegister, -0xfcfcfd
if-ne v$firstRegister, v$dummyRegister, :off
const v$firstRegister, -0xbfbfc0
const v$secondRegister, -0xbfbfc0
:off
sget-object v0, ${fieldReference.type}->${fieldReference.name}:${fieldReference.type}
"""
)
removeInstruction(referenceIndex)
}
} ?: return ZenModeFingerprint.toErrorResult()
} ?: return MiniplayerColorParentFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -0,0 +1,21 @@
package app.revanced.patches.music.misc.backgroundplay.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 BackgroundPlaybackParentFingerprint : MethodFingerprint(
returnType = "V",
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.CONST_4,
Opcode.GOTO,
Opcode.NOP
),
customFingerprint = { it.definingClass.endsWith("/WatchFragment;") }
)

View File

@ -0,0 +1,47 @@
package app.revanced.patches.music.misc.backgroundplay.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.music.misc.backgroundplay.fingerprints.BackgroundPlaybackParentFingerprint
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
@Patch
@Name("background-play")
@Description("Enables playing music in the background.")
@YouTubeMusicCompatibility
@Version("0.0.1")
class BackgroundPlayPatch : BytecodePatch(
listOf(
BackgroundPlaybackParentFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
BackgroundPlaybackParentFingerprint.result?.let {
with(context
.toMethodWalker(it.method)
.nextMethod(it.scanResult.patternScanResult!!.startIndex, true)
.getMethod() as MutableMethod
) {
addInstructions(
0, """
const/4 v0, 0x1
return v0
"""
)
}
} ?: return BackgroundPlaybackParentFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@ -11,7 +11,9 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.music.misc.clientspoof.fingerprints.UserAgentHeaderBuilderFingerprint
import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.extensions.toErrorResult
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch
@ -24,14 +26,13 @@ class ClientSpoofMusicPatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext): PatchResult {
val result = UserAgentHeaderBuilderFingerprint.result!!
val method = result.mutableMethod
val insertIndex = result.scanResult.patternScanResult!!.endIndex - 1
val packageNameRegister = (method.instruction(insertIndex) as FiveRegisterInstruction).registerD
val originalPackageName = "com.google.android.apps.youtube.music"
method.addInstruction(insertIndex, "const-string v$packageNameRegister, \"$originalPackageName\"")
UserAgentHeaderBuilderFingerprint.result?.let {
with (it.mutableMethod) {
val insertIndex = it.scanResult.patternScanResult!!.endIndex - 1
val packageNameRegister = (instruction(insertIndex) as FiveRegisterInstruction).registerD
addInstruction(insertIndex, "const-string v$packageNameRegister, \"$MUSIC_PACKAGE_NAME\"")
}
} ?: return UserAgentHeaderBuilderFingerprint.toErrorResult()
return PatchResultSuccess()
}

View File

@ -8,6 +8,8 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.util.resources.ResourceUtils.copyXmlNode
import org.w3c.dom.Element
@ -15,6 +17,7 @@ import org.w3c.dom.Element
@Patch
@Name("music-settings")
@Description("Adds settings for ReVanced to YouTube Music.")
@DependsOn([MusicIntegrationsPatch::class])
@YouTubeMusicCompatibility
@Version("0.0.1")
class MusicSettingsPatch : ResourcePatch {

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.misc.translations.patch
package app.revanced.patches.music.misc.translations.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
@ -9,15 +9,14 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch
import app.revanced.patches.music.misc.settings.patch.MusicSettingsPatch
import app.revanced.shared.annotation.YouTubeMusicCompatibility
import app.revanced.shared.util.resources.ResourceHelper
@Patch
@DependsOn([MusicIntegrationsPatch::class, MusicSettingsPatch::class])
@Name("translations-music")
@Description("Add Crowdin Translations for YouTube Music")
@DependsOn([MusicSettingsPatch::class])
@YouTubeMusicCompatibility
@Version("0.0.1")
class MusicTranslationsPatch : ResourcePatch {

View File

@ -1,45 +0,0 @@
package app.revanced.patches.music.premium.backgroundplay.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
object BackgroundPlaybackDisableFingerprint : MethodFingerprint(
returnType = "Z",
access = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("L"),
opcodes = listOf(
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET,
Opcode.AND_INT_LIT16,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.CONST,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.GOTO,
Opcode.SGET_OBJECT,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
Opcode.RETURN,
Opcode.RETURN
)
)

View File

@ -1,36 +0,0 @@
package app.revanced.patches.music.premium.backgroundplay.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.music.premium.backgroundplay.fingerprints.BackgroundPlaybackDisableFingerprint
import app.revanced.shared.annotation.YouTubeMusicCompatibility
@Patch
@Name("background-play")
@Description("Enables playing music in the background.")
@YouTubeMusicCompatibility
@Version("0.0.1")
class BackgroundPlayPatch : BytecodePatch(
listOf(
BackgroundPlaybackDisableFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
BackgroundPlaybackDisableFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess()
}
}