feat(youtube): add support version v18.29.38

This commit is contained in:
inotia00 2023-07-30 08:46:51 +09:00
parent 2ade6e49d9
commit 0b09058328
9 changed files with 167 additions and 42 deletions

View File

@ -12,7 +12,6 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.litho.patch.LithoFilterPatch import app.revanced.patches.youtube.utils.litho.patch.LithoFilterPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch.Companion.belowAndroid1820
import app.revanced.util.integrations.Constants.PATCHES_PATH import app.revanced.util.integrations.Constants.PATCHES_PATH
@Patch @Patch
@ -29,7 +28,7 @@ import app.revanced.util.integrations.Constants.PATCHES_PATH
class ButtonContainerPatch : ResourcePatch { class ButtonContainerPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
if (belowAndroid1820) { if (SettingsPatch.below1820) {
LithoFilterPatch.addFilter("$PATCHES_PATH/ads/ActionButtonsFilter;") LithoFilterPatch.addFilter("$PATCHES_PATH/ads/ActionButtonsFilter;")
SettingsPatch.addPreference( SettingsPatch.addPreference(
arrayOf( arrayOf(

View File

@ -3,7 +3,7 @@ package app.revanced.patches.youtube.misc.splashanimation.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.util.bytecode.isWide32LiteralExists import app.revanced.util.bytecode.isWide32LiteralExists
object SplashAnimationBuilderFingerprint : MethodFingerprint( object WatchWhileActivityWithInFlagsFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
parameters = listOf("Landroid/os/Bundle;"), parameters = listOf("Landroid/os/Bundle;"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->

View File

@ -0,0 +1,37 @@
package app.revanced.patches.youtube.misc.splashanimation.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.DarkSplashAnimation
import app.revanced.util.bytecode.isWideLiteralExists
import com.android.tools.smali.dexlib2.Opcode
object WatchWhileActivityWithOutFlagsFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("Landroid/os/Bundle;"),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.IF_NE, // target
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ, // target
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ // target
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/WatchWhileActivity;")
&& methodDef.name == "onCreate"
&& methodDef.isWideLiteralExists(DarkSplashAnimation)
}
)

View File

@ -1,6 +1,5 @@
package app.revanced.patches.youtube.misc.splashanimation.patch package app.revanced.patches.youtube.misc.splashanimation.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
@ -9,44 +8,79 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
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.PatchResultError
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.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.misc.splashanimation.fingerprints.SplashAnimationBuilderFingerprint import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.misc.splashanimation.fingerprints.WatchWhileActivityWithInFlagsFingerprint
import app.revanced.patches.youtube.misc.splashanimation.fingerprints.WatchWhileActivityWithOutFlagsFingerprint
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.DarkSplashAnimation
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.bytecode.getWide32LiteralIndex import app.revanced.util.bytecode.getWide32LiteralIndex
import app.revanced.util.bytecode.getWideLiteralIndex
import app.revanced.util.integrations.Constants.MISC_PATH import app.revanced.util.integrations.Constants.MISC_PATH
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@Patch @Patch
@Name("Enable new splash animation") @Name("Enable new splash animation")
@Description("Enables a new type of splash animation on Android 12+ devices.") @Description("Enables a new type of splash animation on Android 12+ devices.")
@DependsOn([SettingsPatch::class]) @DependsOn(
[
SettingsPatch::class,
SharedResourceIdPatch::class
]
)
@YouTubeCompatibility @YouTubeCompatibility
@Version("0.0.1") @Version("0.0.1")
class NewSplashAnimationPatch : BytecodePatch( class NewSplashAnimationPatch : BytecodePatch(
listOf(SplashAnimationBuilderFingerprint) listOf(
WatchWhileActivityWithInFlagsFingerprint,
WatchWhileActivityWithOutFlagsFingerprint
)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
SplashAnimationBuilderFingerprint.result?.let { WatchWhileActivityWithInFlagsFingerprint.result
?: WatchWhileActivityWithOutFlagsFingerprint.result
?: throw PatchResultError("Failed to resolve fingerprints")
/**
* ~YouTube v18.27.36
*/
WatchWhileActivityWithInFlagsFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
var targetIndex = getWide32LiteralIndex(45407550) + 3 var targetIndex = getWide32LiteralIndex(45407550) + 3
if (getInstruction(targetIndex).opcode == Opcode.MOVE_RESULT) if (getInstruction(targetIndex).opcode == Opcode.MOVE_RESULT)
targetIndex += 1 targetIndex += 1
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA inject(targetIndex)
addInstructions(
targetIndex, """
invoke-static {}, $MISC_PATH/SplashAnimationPatch;->enableNewSplashAnimation()Z
move-result v$targetRegister
"""
)
} }
} ?: return SplashAnimationBuilderFingerprint.toErrorResult() }
/**
* YouTube v18.28.xx~
*/
WatchWhileActivityWithOutFlagsFingerprint.result?.let {
it.mutableMethod.apply {
for (index in getWideLiteralIndex(DarkSplashAnimation) - 1 downTo 0) {
if (getInstruction(index).opcode != Opcode.IF_EQZ)
continue
arrayOf(
index,
index - 8,
index - 14
).forEach { insertIndex -> inject(insertIndex) }
break
}
}
}
/** /**
* Add settings * Add settings
@ -61,4 +95,36 @@ class NewSplashAnimationPatch : BytecodePatch(
return PatchResultSuccess() return PatchResultSuccess()
} }
companion object {
fun MutableMethod.inject(
index: Int
) {
if (getInstruction(index).opcode == Opcode.IF_NE)
injectInt(index)
else
injectBoolean(index)
}
private fun MutableMethod.injectBoolean(index: Int) {
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructions(
index, """
invoke-static {}, $MISC_PATH/SplashAnimationPatch;->enableNewSplashAnimationBoolean()Z
move-result v$register
"""
)
}
private fun MutableMethod.injectInt(index: Int) {
val register = getInstruction<TwoRegisterInstruction>(index).registerA
addInstructions(
index, """
invoke-static {}, $MISC_PATH/SplashAnimationPatch;->enableNewSplashAnimationInt()I
move-result v$register
"""
)
}
}
} }

View File

@ -5,7 +5,6 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name 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.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
@ -77,36 +76,52 @@ class HideFilmstripOverlayPatch : BytecodePatch(
val jumpIndex = setOnClickListenerIndex + 3 val jumpIndex = setOnClickListenerIndex + 3
val initialIndex = setOnClickListenerIndex - 1 val initialIndex = setOnClickListenerIndex - 1
val fixRegister = getInstruction<FiveRegisterInstruction>(initialIndex).registerE
var fixValue = 12
var isFound = false
for (index in initialIndex downTo insertIndex) { if (SettingsPatch.upward1828) {
if (getInstruction(index).opcode != Opcode.CONST_16) continue for (index in insertIndex .. initialIndex) {
if (getInstruction(index).opcode != Opcode.CONST_16 && getInstruction(index).opcode != Opcode.CONST) continue
val register = getInstruction<OneRegisterInstruction>(index).registerA val register = getInstruction<OneRegisterInstruction>(index).registerA
val value = getInstruction<WideLiteralInstruction>(index).wideLiteral.toInt()
if (register != fixRegister) continue val line =
when (getInstruction(index).opcode) {
Opcode.CONST_16 -> """
const/16 v$register, $value
""".trimIndent()
Opcode.CONST -> """
const v$register, $value
""".trimIndent()
else -> ""
}
fixValue = getInstruction<WideLiteralInstruction>(index).wideLiteral.toInt() fixComponent += line
isFound = true }
break } else {
val fixRegister = getInstruction<FiveRegisterInstruction>(initialIndex).registerE
for (index in initialIndex downTo insertIndex) {
if (getInstruction(index).opcode != Opcode.CONST_16) continue
val register = getInstruction<OneRegisterInstruction>(index).registerA
if (register != fixRegister) continue
val fixValue = getInstruction<WideLiteralInstruction>(index).wideLiteral.toInt()
fixComponent = "const/16 v$fixRegister, $fixValue"
break
}
} }
addInstructionsWithLabels( addInstructionsWithLabels(
insertIndex, """ insertIndex, fixComponent + """
invoke-static {}, $PLAYER->hideFilmstripOverlay()Z invoke-static {}, $PLAYER->hideFilmstripOverlay()Z
move-result v$insertRegister move-result v$insertRegister
if-nez v$insertRegister, :hidden if-nez v$insertRegister, :hidden
""", ExternalLabel("hidden", getInstruction(jumpIndex)) """, ExternalLabel("hidden", getInstruction(jumpIndex))
) )
if (isFound) {
addInstruction(
insertIndex,
"const/16 v$fixRegister, $fixValue"
)
}
} }
} ?: return YouTubeControlsOverlayFingerprint.toErrorResult() } ?: return YouTubeControlsOverlayFingerprint.toErrorResult()
@ -127,6 +142,8 @@ class HideFilmstripOverlayPatch : BytecodePatch(
} }
private companion object { private companion object {
var fixComponent: String = ""
fun MutableMethod.injectHook() { fun MutableMethod.injectHook() {
addInstructionsWithLabels( addInstructionsWithLabels(
0, """ 0, """

View File

@ -12,7 +12,8 @@ import app.revanced.patcher.annotation.Package
"18.23.36", "18.23.36",
"18.24.37", "18.24.37",
"18.25.40", "18.25.40",
"18.27.36" "18.27.36",
"18.29.38"
) )
)] )]
) )

View File

@ -45,7 +45,7 @@ class LithoFilterPatch : BytecodePatch(
"sput-object p0, $ADS_PATH/LowLevelFilter;->byteBuffer:Ljava/nio/ByteBuffer;" "sput-object p0, $ADS_PATH/LowLevelFilter;->byteBuffer:Ljava/nio/ByteBuffer;"
) ?: return ByteBufferFingerprint.toErrorResult() ) ?: return ByteBufferFingerprint.toErrorResult()
if (SettingsPatch.belowAndroid1820) if (SettingsPatch.below1820)
legacyHook("$ADS_PATH/LithoFilterPatch;->filters") legacyHook("$ADS_PATH/LithoFilterPatch;->filters")
else else
generalHook("$ADS_PATH/LithoFilterPatch;->filters") generalHook("$ADS_PATH/LithoFilterPatch;->filters")

View File

@ -36,6 +36,7 @@ class SharedResourceIdPatch : ResourcePatch {
var CompactLink: Long = -1 var CompactLink: Long = -1
var ControlsLayoutStub: Long = -1 var ControlsLayoutStub: Long = -1
var CoreContainer: Long = -1 var CoreContainer: Long = -1
var DarkSplashAnimation: Long = -1
var DislikeButton: Long = -1 var DislikeButton: Long = -1
var DonationCompanion: Long = -1 var DonationCompanion: Long = -1
var EasySeekEduContainer: Long = -1 var EasySeekEduContainer: Long = -1
@ -108,6 +109,7 @@ class SharedResourceIdPatch : ResourcePatch {
CompactLink = find(LAYOUT, "compact_link") CompactLink = find(LAYOUT, "compact_link")
ControlsLayoutStub = find(ID, "controls_layout_stub") ControlsLayoutStub = find(ID, "controls_layout_stub")
CoreContainer = find(ID, "core_container") CoreContainer = find(ID, "core_container")
DarkSplashAnimation = find(ID, "dark_splash_animation")
DislikeButton = find(ID, "dislike_button") DislikeButton = find(ID, "dislike_button")
DonationCompanion = find(LAYOUT, "donation_companion") DonationCompanion = find(LAYOUT, "donation_companion")
EasySeekEduContainer = find(ID, "easy_seek_edu_container") EasySeekEduContainer = find(ID, "easy_seek_edu_container")

View File

@ -70,10 +70,12 @@ class SettingsPatch : AbstractSettingsResourcePatch(
if (node.nodeName != "integer" || !node.getAttribute("name") if (node.nodeName != "integer" || !node.getAttribute("name")
.startsWith("google_play_services_version") .startsWith("google_play_services_version")
) ) continue
continue
belowAndroid1820 = node.textContent.toInt() <= 232100000 val playServicesVersion = node.textContent.toInt()
below1820 = playServicesVersion <= 232100000
upward1828 = playServicesVersion >= 232900000
break break
} }
@ -182,7 +184,8 @@ class SettingsPatch : AbstractSettingsResourcePatch(
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT) private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
internal lateinit var contexts: ResourceContext internal lateinit var contexts: ResourceContext
internal var belowAndroid1820: Boolean = false internal var below1820: Boolean = false
internal var upward1828: Boolean = false
internal fun addPreference(settingArray: Array<String>) { internal fun addPreference(settingArray: Array<String>) {
contexts.addPreference(settingArray) contexts.addPreference(settingArray)