feat(music/remember-shuffle-state): change patch name enable-force-shuffleremember-shuffle-state

This commit is contained in:
inotia00 2023-09-25 11:06:32 +09:00
parent ff895f6f66
commit 6601d4539c
9 changed files with 243 additions and 284 deletions

View File

@ -7,20 +7,20 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.player.colormatchplayer.fingerprints.ColorMatchPlayerFingerprint
import app.revanced.patches.music.utils.annotations.MusicCompatibility
import app.revanced.patches.music.utils.fingerprints.ColorMatchPlayerParentFingerprint
import app.revanced.patches.music.utils.fingerprints.PlayerColorFingerprint
import app.revanced.patches.music.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.enum.CategoryType
import app.revanced.util.integrations.Constants.MUSIC_PLAYER
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import kotlin.properties.Delegates
@Patch
@Name("Enable color match player")
@ -28,50 +28,44 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@DependsOn([SettingsPatch::class])
@MusicCompatibility
class ColorMatchPlayerPatch : BytecodePatch(
listOf(ColorMatchPlayerParentFingerprint)
listOf(PlayerColorFingerprint)
) {
override fun execute(context: BytecodeContext) {
ColorMatchPlayerParentFingerprint.result?.let { parentResult ->
ColorMatchPlayerFingerprint.also {
it.resolve(
context,
parentResult.classDef
)
}.result?.let {
PlayerColorFingerprint.result?.let {
it.mutableMethod.apply {
targetMethod = parentResult.mutableMethod
val insertIndex = it.scanResult.patternScanResult!!.startIndex + 1
relativeIndex = it.scanResult.patternScanResult!!.startIndex
val insertIndex = implementation!!.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.IPUT_OBJECT
}
val jumpInstruction = getInstruction<Instruction>(insertIndex)
val type = it.classDef.type
val replaceReference =
getInstruction<ReferenceInstruction>(insertIndex - 1).reference
addInstructionsWithLabels(
insertIndex, """
invoke-static {}, $MUSIC_PLAYER->enableColorMatchPlayer()Z
move-result v2
if-eqz v2, :off
iget v0, p0, ${descriptor(4)}
if-eq v0, v2, :abswitch
iput v2, p0, ${descriptor(4)}
iget-object v0, p0, ${descriptor(5)}
invoke-virtual {v0, v2, p2, p3}, ${descriptor(6)}
:abswitch
iget v0, p0, ${descriptor(10)}
iget v0, p0, ${descriptor(2)}
if-eq v0, v2, :switch
iput v2, p0, ${descriptor(2)}
iget-object v0, p0, ${descriptor(3)}
invoke-virtual {v0, v2, p2, p3}, ${descriptor(4)}
:switch
iget v0, p0, ${descriptor(7)}
if-eq v0, v1, :exit
iput v1, p0, ${descriptor(10)}
iget-object v0, p0, ${descriptor(11)}
invoke-virtual {v0, v1, p2, p3}, ${descriptor(12)}
iput v1, p0, ${descriptor(7)}
iget-object v0, p0, ${descriptor(8)}
invoke-virtual {v0, v1, p2, p3}, ${descriptor(9)}
goto :exit
:off
invoke-direct {p0}, ${type}->${parentResult.mutableMethod.name}()V
invoke-direct {p0}, $replaceReference
""", ExternalLabel("exit", jumpInstruction)
)
removeInstruction(insertIndex - 1)
}
} ?: throw ColorMatchPlayerFingerprint.exception
} ?: throw ColorMatchPlayerParentFingerprint.exception
} ?: throw PlayerColorFingerprint.exception
SettingsPatch.addMusicPreference(
CategoryType.PLAYER,
@ -82,10 +76,10 @@ class ColorMatchPlayerPatch : BytecodePatch(
}
private companion object {
private lateinit var targetMethod: MutableMethod
var relativeIndex by Delegates.notNull<Int>()
fun descriptor(index: Int): String {
return targetMethod.getInstruction<ReferenceInstruction>(index).reference.toString()
fun MutableMethod.descriptor(index: Int): String {
return getInstruction<ReferenceInstruction>(relativeIndex + index).reference.toString()
}
}
}

View File

@ -13,7 +13,7 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.player.oldstyleminiplayer.fingerprints.NextButtonVisibilityFingerprint
import app.revanced.patches.music.player.oldstyleminiplayer.fingerprints.SwipeToCloseFingerprint
import app.revanced.patches.music.utils.annotations.MusicCompatibility
import app.revanced.patches.music.utils.fingerprints.ColorMatchPlayerParentFingerprint
import app.revanced.patches.music.utils.fingerprints.PlayerColorFingerprint
import app.revanced.patches.music.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.enum.CategoryType
import app.revanced.util.integrations.Constants.MUSIC_PLAYER
@ -26,13 +26,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@MusicCompatibility
class OldStyleMiniPlayerPatch : BytecodePatch(
listOf(
ColorMatchPlayerParentFingerprint,
PlayerColorFingerprint,
SwipeToCloseFingerprint
)
) {
override fun execute(context: BytecodeContext) {
ColorMatchPlayerParentFingerprint.result?.let { parentResult ->
PlayerColorFingerprint.result?.let { parentResult ->
NextButtonVisibilityFingerprint.also {
it.resolve(
context,
@ -52,7 +52,7 @@ class OldStyleMiniPlayerPatch : BytecodePatch(
)
}
} ?: throw NextButtonVisibilityFingerprint.exception
} ?: throw ColorMatchPlayerParentFingerprint.exception
} ?: throw PlayerColorFingerprint.exception
SwipeToCloseFingerprint.result?.let {
it.mutableMethod.apply {

View File

@ -1,27 +0,0 @@
package app.revanced.patches.music.player.shuffle.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.patch.SharedResourceIdPatch.Companion.DisabledIconAlpha
import app.revanced.util.bytecode.isWideLiteralExists
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object ShuffleClassFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IPUT,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
),
customFingerprint = { methodDef, _ ->
methodDef.name == "<init>" && methodDef.isWideLiteralExists(
DisabledIconAlpha
)
}
)

View File

@ -1,187 +0,0 @@
package app.revanced.patches.music.player.shuffle.patch
import app.revanced.extensions.exception
import app.revanced.extensions.transformFields
import app.revanced.extensions.traverseClassHierarchy
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
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.player.shuffle.fingerprints.MusicPlaybackControlsFingerprint
import app.revanced.patches.music.player.shuffle.fingerprints.ShuffleClassFingerprint
import app.revanced.patches.music.player.shuffle.fingerprints.ShuffleClassReferenceFingerprint
import app.revanced.patches.music.utils.annotations.MusicCompatibility
import app.revanced.patches.music.utils.resourceid.patch.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.enum.CategoryType
import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.Reference
import com.android.tools.smali.dexlib2.immutable.ImmutableField
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
@Patch
@Name("Enable force shuffle")
@Description("Enable force shuffle even if another track is played.")
@DependsOn(
[
SettingsPatch::class,
SharedResourceIdPatch::class
]
)
@MusicCompatibility
class EnforceShufflePatch : BytecodePatch(
listOf(
MusicPlaybackControlsFingerprint,
ShuffleClassFingerprint,
ShuffleClassReferenceFingerprint
)
) {
override fun execute(context: BytecodeContext) {
ShuffleClassReferenceFingerprint.result?.let {
it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex
val endIndex = it.scanResult.patternScanResult!!.endIndex
val imageViewIndex = implementation!!.instructions.indexOfFirst { instruction ->
((instruction as? ReferenceInstruction)?.reference as? FieldReference)?.type == "Landroid/widget/ImageView;"
}
SHUFFLE_CLASS = it.classDef.type
shuffleReference1 = getInstruction(startIndex).descriptor
shuffleReference2 = getInstruction(startIndex + 1).descriptor
shuffleReference3 = getInstruction(endIndex).descriptor
shuffleReference4 = getInstruction(imageViewIndex).descriptor
}
} ?: throw ShuffleClassReferenceFingerprint.exception
ShuffleClassFingerprint.result?.let {
it.mutableMethod.apply {
addInstruction(
it.scanResult.patternScanResult!!.endIndex,
"sput-object p0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleclass:$SHUFFLE_CLASS"
)
}
context.traverseClassHierarchy(it.mutableClass) {
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL
transformFields {
ImmutableField(
definingClass,
name,
type,
AccessFlags.PUBLIC or AccessFlags.PUBLIC,
null,
annotations,
null
).toMutable()
}
}
} ?: throw ShuffleClassFingerprint.exception
MusicPlaybackControlsFingerprint.result?.let {
it.mutableMethod.apply {
shuffleReference5 = getInstruction(0).descriptor
shuffleReference6 = getInstruction(1).descriptor
addInstructions(
0, """
invoke-virtual {v0, v1}, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->buttonHook(Z)V
return-void
"""
)
}
it.mutableClass.apply {
staticFields.add(
ImmutableField(
it.mutableMethod.definingClass,
"shuffleclass",
SHUFFLE_CLASS,
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
annotations,
null
).toMutable()
)
val shuffleFieldReference = shuffleReference3 as FieldReference
methods.add(
ImmutableMethod(
it.classDef.type,
"buttonHook",
listOf(ImmutableMethodParameter("Z", annotations, null)),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
annotations,
null,
ImmutableMethodImplementation(
5, """
invoke-static {}, $MUSIC_MISC_PATH/ForceShufflePatch;->enableForceShuffle()Z
move-result v0
if-eqz v0, :cond_0
new-instance v0, $SHUFFLE_CLASS
sget-object v0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleclass:$SHUFFLE_CLASS
iget-object v1, v0, $shuffleReference1
invoke-interface {v1}, $shuffleReference2
move-result-object v1
check-cast v1, ${shuffleFieldReference.definingClass}
iget-object v1, v1, $shuffleReference3
invoke-virtual {v1}, ${shuffleFieldReference.type}->ordinal()I
move-result v1
iget-object v2, v0, $shuffleReference4
invoke-virtual {v2}, Landroid/widget/ImageView;->performClick()Z
if-eqz v1, :cond_0
invoke-virtual {v2}, Landroid/widget/ImageView;->performClick()Z
:cond_0
iput-boolean v4, v3, $shuffleReference5
invoke-virtual {v3}, $shuffleReference6
return-void
""".toInstructions(), null, null
)
).toMutable()
)
}
} ?: throw MusicPlaybackControlsFingerprint.exception
SettingsPatch.addMusicPreference(
CategoryType.PLAYER,
"revanced_enable_force_shuffle",
"true"
)
}
private companion object {
const val MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR =
"Lcom/google/android/apps/youtube/music/watchpage/MusicPlaybackControls;"
lateinit var SHUFFLE_CLASS: String
lateinit var shuffleReference1: Reference
lateinit var shuffleReference2: Reference
lateinit var shuffleReference3: Reference
lateinit var shuffleReference4: Reference
lateinit var shuffleReference5: Reference
lateinit var shuffleReference6: Reference
val Instruction.descriptor
get() = (this as ReferenceInstruction).reference
}
}

View File

@ -0,0 +1,180 @@
package app.revanced.patches.music.player.shuffle.patch
import app.revanced.extensions.exception
import app.revanced.extensions.transformFields
import app.revanced.extensions.traverseClassHierarchy
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.music.player.shuffle.fingerprints.MusicPlaybackControlsFingerprint
import app.revanced.patches.music.player.shuffle.fingerprints.ShuffleClassReferenceFingerprint
import app.revanced.patches.music.utils.annotations.MusicCompatibility
import app.revanced.patches.music.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.enum.CategoryType
import app.revanced.util.integrations.Constants.MUSIC_PLAYER
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.Reference
import com.android.tools.smali.dexlib2.immutable.ImmutableField
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.util.MethodUtil
@Patch
@Name("Remember shuffle state")
@Description("Remembers the state of the shuffle.")
@DependsOn([SettingsPatch::class])
@MusicCompatibility
class RememberShufflePatch : BytecodePatch(
listOf(
MusicPlaybackControlsFingerprint,
ShuffleClassReferenceFingerprint
)
) {
override fun execute(context: BytecodeContext) {
ShuffleClassReferenceFingerprint.result?.let {
it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex
val endIndex = it.scanResult.patternScanResult!!.endIndex
val imageViewIndex = implementation!!.instructions.indexOfFirst { instruction ->
((instruction as? ReferenceInstruction)?.reference as? FieldReference)?.type == "Landroid/widget/ImageView;"
}
SHUFFLE_CLASS = it.classDef.type
val shuffleReference1 = descriptor(startIndex)
val shuffleReference2 = descriptor(startIndex + 1)
val shuffleReference3 = descriptor(endIndex)
val shuffleFieldReference = shuffleReference3 as FieldReference
imageViewReference = descriptor(imageViewIndex)
shuffleStateLabel = """
iget-object v1, v0, $shuffleReference1
invoke-interface {v1}, $shuffleReference2
move-result-object v1
check-cast v1, ${shuffleFieldReference.definingClass}
iget-object v1, v1, $shuffleReference3
invoke-virtual {v1}, ${shuffleFieldReference.type}->ordinal()I
move-result v1
"""
}
val constructorMethod =
it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) }
val onClickMethod = it.mutableClass.methods.first { method -> method.name == "onClick" }
constructorMethod.apply {
addInstruction(
implementation!!.instructions.size - 1,
"sput-object p0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$SHUFFLE_CLASS"
)
}
onClickMethod.apply {
addInstructions(
0, """
move-object v0, p0
""" + shuffleStateLabel + """
invoke-static {v1}, $MUSIC_PLAYER->setShuffleState(I)V
"""
)
}
context.traverseClassHierarchy(it.mutableClass) {
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL
transformFields {
ImmutableField(
definingClass,
name,
type,
AccessFlags.PUBLIC or AccessFlags.PUBLIC,
null,
annotations,
null
).toMutable()
}
}
} ?: throw ShuffleClassReferenceFingerprint.exception
MusicPlaybackControlsFingerprint.result?.let {
it.mutableMethod.apply {
addInstruction(
0,
"invoke-virtual {v0}, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->rememberShuffleState()V"
)
val shuffleField = ImmutableField(
definingClass,
"shuffleClass",
SHUFFLE_CLASS,
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
annotations,
null
).toMutable()
val shuffleMethod = ImmutableMethod(
definingClass,
"rememberShuffleState",
emptyList(),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
annotations, null,
MutableMethodImplementation(5)
).toMutable()
shuffleMethod.addInstructionsWithLabels(
0, """
invoke-static {}, $MUSIC_PLAYER->getShuffleState()I
move-result v2
if-nez v2, :dont_shuffle
sget-object v0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$SHUFFLE_CLASS
""" + shuffleStateLabel + """
iget-object v3, v0, $imageViewReference
invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z
if-eqz v1, :dont_shuffle
invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z
:dont_shuffle
return-void
"""
)
it.mutableClass.methods.add(shuffleMethod)
it.mutableClass.staticFields.add(shuffleField)
}
} ?: throw MusicPlaybackControlsFingerprint.exception
SettingsPatch.addMusicPreference(
CategoryType.PLAYER,
"revanced_remember_shuffle_state",
"true"
)
}
private companion object {
const val MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR =
"Lcom/google/android/apps/youtube/music/watchpage/MusicPlaybackControls;"
lateinit var SHUFFLE_CLASS: String
lateinit var imageViewReference: Reference
lateinit var shuffleStateLabel: String
fun MutableMethod.descriptor(index: Int): Reference {
return getInstruction<ReferenceInstruction>(index).reference
}
}
}

View File

@ -13,7 +13,7 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.player.zenmode.fingerprints.ZenModeFingerprint
import app.revanced.patches.music.utils.annotations.MusicCompatibility
import app.revanced.patches.music.utils.fingerprints.ColorMatchPlayerParentFingerprint
import app.revanced.patches.music.utils.fingerprints.PlayerColorFingerprint
import app.revanced.patches.music.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.enum.CategoryType
import app.revanced.util.integrations.Constants.MUSIC_PLAYER
@ -26,11 +26,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@DependsOn([SettingsPatch::class])
@MusicCompatibility
class ZenModePatch : BytecodePatch(
listOf(ColorMatchPlayerParentFingerprint)
listOf(PlayerColorFingerprint)
) {
override fun execute(context: BytecodeContext) {
ColorMatchPlayerParentFingerprint.result?.let { parentResult ->
PlayerColorFingerprint.result?.let { parentResult ->
ZenModeFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex
@ -40,11 +40,11 @@ class ZenModePatch : BytecodePatch(
getInstruction<OneRegisterInstruction>(startIndex + 2).registerA
val dummyRegister = secondRegister + 1
val referenceIndex = it.scanResult.patternScanResult!!.endIndex + 1
val targetReference =
getInstruction<ReferenceInstruction>(referenceIndex).reference.toString()
val replaceReferenceIndex = it.scanResult.patternScanResult!!.endIndex + 1
val replaceReference =
getInstruction<ReferenceInstruction>(replaceReferenceIndex).reference
val insertIndex = referenceIndex + 1
val insertIndex = replaceReferenceIndex + 1
addInstructionsWithLabels(
insertIndex, """
@ -56,13 +56,13 @@ class ZenModePatch : BytecodePatch(
const v$firstRegister, -0xbfbfc0
const v$secondRegister, -0xbfbfc0
:off
sget-object v0, $targetReference
sget-object v0, $replaceReference
"""
)
removeInstruction(referenceIndex)
removeInstruction(replaceReferenceIndex)
}
} ?: throw ZenModeFingerprint.exception
} ?: throw ColorMatchPlayerParentFingerprint.exception
} ?: throw PlayerColorFingerprint.exception
SettingsPatch.addMusicPreference(
CategoryType.PLAYER,

View File

@ -5,22 +5,23 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object ColorMatchPlayerParentFingerprint : MethodFingerprint(
object PlayerColorFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L", "J"),
opcodes = listOf(
Opcode.IGET,
Opcode.IGET,
Opcode.CONST_WIDE_16,
Opcode.IF_EQ,
Opcode.IPUT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET,
Opcode.IGET,
Opcode.IF_EQ,
Opcode.IPUT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ
)
)

View File

@ -22,7 +22,6 @@ class SharedResourceIdPatch : ResourcePatch {
var ChipCloud: Long = -1
var ColorGrey: Long = -1
var DialogSolid: Long = -1
var DisabledIconAlpha: Long = -1
var InlineTimeBarAdBreakMarkerColor: Long = -1
var IsTablet: Long = -1
var MenuEntry: Long = -1
@ -49,7 +48,6 @@ class SharedResourceIdPatch : ResourcePatch {
ChipCloud = find(LAYOUT, "chip_cloud")
ColorGrey = find(COLOR, "ytm_color_grey_12")
DialogSolid = find(STYLE, "Theme.YouTubeMusic.Dialog.Solid")
DisabledIconAlpha = find(DIMEN, "disabled_icon_alpha")
InlineTimeBarAdBreakMarkerColor = find(COLOR, "inline_time_bar_ad_break_marker_color")
IsTablet = find(BOOL, "is_tablet")
MenuEntry = find(LAYOUT, "menu_entry")

View File

@ -32,8 +32,6 @@
<string name="revanced_enable_flyout_panel_playback_speed_title">Enable playback speed</string>
<string name="revanced_enable_force_minimized_player_summary">Keep player permanently minimized even if another track is played.</string>
<string name="revanced_enable_force_minimized_player_title">Enable force minimized player</string>
<string name="revanced_enable_force_shuffle_summary">Enable force shuffle even if another track is played.</string>
<string name="revanced_enable_force_shuffle_title">Enable force shuffle</string>
<string name="revanced_enable_landscape_mode_summary">Enables entry into landscape mode by screen rotation on the phone.</string>
<string name="revanced_enable_landscape_mode_title">Enable landscape mode</string>
<string name="revanced_enable_new_layout_summary">Enable new player layouts.</string>
@ -129,6 +127,8 @@
<string name="revanced_replace_flyout_panel_dismiss_queue_continue_watch_title">Continue watching</string>
<string name="revanced_replace_flyout_panel_dismiss_queue_summary">Replaces dismiss queue menu to watch on YouTube.</string>
<string name="revanced_replace_flyout_panel_dismiss_queue_title">Replace dismiss queue</string>
<string name="revanced_remember_shuffle_state_summary">Remembers the state of the shuffle.</string>
<string name="revanced_remember_shuffle_state_title">Remember shuffle state</string>
<string name="revanced_reset">Reset</string>
<string name="revanced_ryd_about">About</string>
<string name="revanced_ryd_attribution_summary">Data is provided by the Return YouTube Dislike API. Tap here to learn more.</string>