chore: Lint code

This commit is contained in:
inotia00 2024-12-17 14:35:06 +09:00
parent b32301fd85
commit 512b2526ba
17 changed files with 219 additions and 142 deletions

View File

@ -49,6 +49,7 @@ val changeVersionCodePatch = resourcePatch(
"Invalid versionCode: $versionCodeString, " + "Invalid versionCode: $versionCodeString, " +
"Version code should be larger than 1 and smaller than $MAX_VALUE." "Version code should be larger than 1 and smaller than $MAX_VALUE."
) )
val versionCodeString = versionCodeOption.valueOrThrow() val versionCodeString = versionCodeOption.valueOrThrow()
val versionCode: Int val versionCode: Int

View File

@ -116,7 +116,8 @@ val actionBarComponentsPatch = bytecodePatch(
.endsWith("Lcom/google/android/libraries/youtube/common/ui/YouTubeButton;-><init>(Landroid/content/Context;)V") .endsWith("Lcom/google/android/libraries/youtube/common/ui/YouTubeButton;-><init>(Landroid/content/Context;)V")
} - 2 } - 2
val replaceInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex) val replaceInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex)
val replaceReference = getInstruction<ReferenceInstruction>(replaceIndex).reference val replaceReference =
getInstruction<ReferenceInstruction>(replaceIndex).reference
addInstructionsWithLabels( addInstructionsWithLabels(
replaceIndex + 1, """ replaceIndex + 1, """
@ -140,7 +141,8 @@ val actionBarComponentsPatch = bytecodePatch(
} }
val spannedRegister = val spannedRegister =
getInstruction<FiveRegisterInstruction>(spannedIndex).registerC getInstruction<FiveRegisterInstruction>(spannedIndex).registerC
val spannedReference = getInstruction<ReferenceInstruction>(spannedIndex).reference val spannedReference =
getInstruction<ReferenceInstruction>(spannedIndex).reference
addInstructionsWithLabels( addInstructionsWithLabels(
spannedIndex + 1, """ spannedIndex + 1, """

View File

@ -12,7 +12,9 @@ internal val dislikeButtonOnClickListenerFingerprint = legacyFingerprint(
parameters = listOf("Landroid/view/View;"), parameters = listOf("Landroid/view/View;"),
customFingerprint = { method, _ -> customFingerprint = { method, _ ->
method.name == "onClick" && method.name == "onClick" &&
(method.containsLiteralInstruction(53465L) || method.containsLiteralInstruction(98173L)) (method.containsLiteralInstruction(53465L) || method.containsLiteralInstruction(
98173L
))
} }
) )

View File

@ -252,8 +252,14 @@ val customBrandingIconPatch = resourcePatch(
} }
mapOf( mapOf(
ADAPTIVE_ICON_BACKGROUND_FILE_NAME to getAdaptiveIconResourceFile("res/mipmap-anydpi/ic_launcher_release.xml", "background"), ADAPTIVE_ICON_BACKGROUND_FILE_NAME to getAdaptiveIconResourceFile(
ADAPTIVE_ICON_FOREGROUND_FILE_NAME to getAdaptiveIconResourceFile("res/mipmap-anydpi/ic_launcher_release.xml", "foreground") "res/mipmap-anydpi/ic_launcher_release.xml",
"background"
),
ADAPTIVE_ICON_FOREGROUND_FILE_NAME to getAdaptiveIconResourceFile(
"res/mipmap-anydpi/ic_launcher_release.xml",
"foreground"
)
).forEach { (oldIconResourceFile, newIconResourceFile) -> ).forEach { (oldIconResourceFile, newIconResourceFile) ->
if (oldIconResourceFile != newIconResourceFile) { if (oldIconResourceFile != newIconResourceFile) {
mipmapDirectories.forEach { mipmapDirectories.forEach {

View File

@ -40,7 +40,8 @@ val DrcAudioPatch = bytecodePatch(
fingerprint.matchOrThrow(formatStreamModelConstructorFingerprint).let { fingerprint.matchOrThrow(formatStreamModelConstructorFingerprint).let {
it.method.apply { it.method.apply {
val insertIndex = it.patternMatch!!.endIndex val insertIndex = it.patternMatch!!.endIndex
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex - 1).registerA val insertRegister =
getInstruction<TwoRegisterInstruction>(insertIndex - 1).registerA
addInstructions( addInstructions(
insertIndex, insertIndex,

View File

@ -823,7 +823,7 @@ val playerComponentsPatch = bytecodePatch(
// region patch for remember repeat state // region patch for remember repeat state
val (repeatTrackMethod, repeatTrackIndex) = repeatTrackFingerprint.matchOrThrow().let { val (repeatTrackMethod, repeatTrackIndex) = repeatTrackFingerprint.matchOrThrow().let {
with (it.method) { with(it.method) {
val targetIndex = it.patternMatch!!.endIndex val targetIndex = it.patternMatch!!.endIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA

View File

@ -80,10 +80,11 @@ val spoofClientPatch = bytecodePatch(
val clientInfoVersionIndex = result.stringMatches!!.first().index val clientInfoVersionIndex = result.stringMatches!!.first().index
val clientInfoVersionRegister = val clientInfoVersionRegister =
getInstruction<OneRegisterInstruction>(clientInfoVersionIndex).registerA getInstruction<OneRegisterInstruction>(clientInfoVersionIndex).registerA
val clientInfoClientVersionFieldIndex = indexOfFirstInstructionOrThrow(clientInfoVersionIndex) { val clientInfoClientVersionFieldIndex =
opcode == Opcode.IPUT_OBJECT && indexOfFirstInstructionOrThrow(clientInfoVersionIndex) {
(this as TwoRegisterInstruction).registerA == clientInfoVersionRegister opcode == Opcode.IPUT_OBJECT &&
} (this as TwoRegisterInstruction).registerA == clientInfoVersionRegister
}
// Client info object's client version field. // Client info object's client version field.
val clientInfoClientVersionField = val clientInfoClientVersionField =
@ -95,27 +96,30 @@ val spoofClientPatch = bytecodePatch(
} }
} }
val clientInfoClientModelField = with (createPlayerRequestBodyWithModelFingerprint.methodOrThrow()) { val clientInfoClientModelField =
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field. with(createPlayerRequestBodyWithModelFingerprint.methodOrThrow()) {
val clientInfoClientModelIndex = indexOfFirstInstructionOrThrow(indexOfModelInstruction(this)) { // The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
val reference = getReference<FieldReference>() val clientInfoClientModelIndex =
opcode == Opcode.IPUT_OBJECT && indexOfFirstInstructionOrThrow(indexOfModelInstruction(this)) {
reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR && val reference = getReference<FieldReference>()
reference.type == "Ljava/lang/String;" opcode == Opcode.IPUT_OBJECT &&
reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR &&
reference.type == "Ljava/lang/String;"
}
getInstruction<ReferenceInstruction>(clientInfoClientModelIndex).reference
} }
getInstruction<ReferenceInstruction>(clientInfoClientModelIndex).reference
}
val clientInfoOsVersionField = with (createPlayerRequestBodyWithVersionReleaseFingerprint.methodOrThrow()) { val clientInfoOsVersionField =
val buildIndex = indexOfBuildInstruction(this) with(createPlayerRequestBodyWithVersionReleaseFingerprint.methodOrThrow()) {
val clientInfoOsVersionIndex = indexOfFirstInstructionOrThrow(buildIndex - 5) { val buildIndex = indexOfBuildInstruction(this)
val reference = getReference<FieldReference>() val clientInfoOsVersionIndex = indexOfFirstInstructionOrThrow(buildIndex - 5) {
opcode == Opcode.IPUT_OBJECT && val reference = getReference<FieldReference>()
reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR && opcode == Opcode.IPUT_OBJECT &&
reference.type == "Ljava/lang/String;" reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR &&
reference.type == "Ljava/lang/String;"
}
getInstruction<ReferenceInstruction>(clientInfoOsVersionIndex).reference
} }
getInstruction<ReferenceInstruction>(clientInfoOsVersionIndex).reference
}
// endregion // endregion
@ -229,7 +233,8 @@ val spoofClientPatch = bytecodePatch(
reference?.returnType == "V" && reference?.returnType == "V" &&
reference.parameterTypes.firstOrNull()?.startsWith("[L") == true reference.parameterTypes.firstOrNull()?.startsWith("[L") == true
} }
val createPlaybackSpeedMenuItemMethod = getWalkerMethod(createPlaybackSpeedMenuItemIndex) val createPlaybackSpeedMenuItemMethod =
getWalkerMethod(createPlaybackSpeedMenuItemIndex)
createPlaybackSpeedMenuItemMethod.apply { createPlaybackSpeedMenuItemMethod.apply {
val shouldCreateMenuIndex = indexOfFirstInstructionOrThrow { val shouldCreateMenuIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>() val reference = getReference<MethodReference>()
@ -237,7 +242,8 @@ val spoofClientPatch = bytecodePatch(
reference?.returnType == "Z" && reference?.returnType == "Z" &&
reference.parameterTypes.isEmpty() reference.parameterTypes.isEmpty()
} + 2 } + 2
val shouldCreateMenuRegister = getInstruction<OneRegisterInstruction>(shouldCreateMenuIndex - 1).registerA val shouldCreateMenuRegister =
getInstruction<OneRegisterInstruction>(shouldCreateMenuIndex - 1).registerA
addInstructions( addInstructions(
shouldCreateMenuIndex, shouldCreateMenuIndex,

View File

@ -111,10 +111,11 @@ private val sponsorBlockBytecodePatch = bytecodePatch(
rectangleFieldName = rectangleFieldName =
musicPlaybackControlsTimeBarOnMeasureFingerprint.matchOrThrow().let { musicPlaybackControlsTimeBarOnMeasureFingerprint.matchOrThrow().let {
with(it.method) { with(it.method) {
val rectangleIndex = indexOfFirstInstructionReversedOrThrow(it.patternMatch!!.endIndex) { val rectangleIndex =
opcode == Opcode.IGET_OBJECT && indexOfFirstInstructionReversedOrThrow(it.patternMatch!!.endIndex) {
getReference<FieldReference>()?.type == "Landroid/graphics/Rect;" opcode == Opcode.IGET_OBJECT &&
} getReference<FieldReference>()?.type == "Landroid/graphics/Rect;"
}
val rectangleReference = val rectangleReference =
getInstruction<ReferenceInstruction>(rectangleIndex).reference getInstruction<ReferenceInstruction>(rectangleIndex).reference
(rectangleReference as FieldReference).name (rectangleReference as FieldReference).name

View File

@ -84,9 +84,9 @@ fun gmsCoreSupportPatch(
key = "gmsCoreVendorGroupId", key = "gmsCoreVendorGroupId",
default = "app.revanced", default = "app.revanced",
values = values =
mapOf( mapOf(
"ReVanced" to "app.revanced", "ReVanced" to "app.revanced",
), ),
title = "GmsCore vendor group ID", title = "GmsCore vendor group ID",
description = "The vendor's group ID for GmsCore.", description = "The vendor's group ID for GmsCore.",
required = true, required = true,

View File

@ -81,50 +81,59 @@ fun baseSpoofStreamingDataPatch(
// region Replace the streaming data. // region Replace the streaming data.
createStreamingDataFingerprint.matchOrThrow(createStreamingDataParentFingerprint).let { result -> createStreamingDataFingerprint.matchOrThrow(createStreamingDataParentFingerprint)
result.method.apply { .let { result ->
val setStreamDataMethodName = "patch_setStreamingData" result.method.apply {
val resultMethodType = result.classDef.type val setStreamDataMethodName = "patch_setStreamingData"
val setStreamingDataIndex = result.patternMatch!!.startIndex val resultMethodType = result.classDef.type
val setStreamingDataField = val setStreamingDataIndex = result.patternMatch!!.startIndex
getInstruction(setStreamingDataIndex).getReference<FieldReference>().toString() val setStreamingDataField =
getInstruction(setStreamingDataIndex).getReference<FieldReference>()
.toString()
val playerProtoClass = val playerProtoClass =
getInstruction(setStreamingDataIndex + 1).getReference<FieldReference>()!!.definingClass getInstruction(setStreamingDataIndex + 1).getReference<FieldReference>()!!.definingClass
val protobufClass = val protobufClass =
protobufClassParseByteBufferFingerprint.definingClassOrThrow() protobufClassParseByteBufferFingerprint.definingClassOrThrow()
val getStreamingDataField = instructions.find { instruction -> val getStreamingDataField = instructions.find { instruction ->
instruction.opcode == Opcode.IGET_OBJECT && instruction.opcode == Opcode.IGET_OBJECT &&
instruction.getReference<FieldReference>()?.definingClass == playerProtoClass instruction.getReference<FieldReference>()?.definingClass == playerProtoClass
}?.getReference<FieldReference>() }?.getReference<FieldReference>()
?: throw PatchException("Could not find getStreamingDataField") ?: throw PatchException("Could not find getStreamingDataField")
val videoDetailsIndex = result.patternMatch!!.endIndex val videoDetailsIndex = result.patternMatch!!.endIndex
val videoDetailsRegister = getInstruction<TwoRegisterInstruction>(videoDetailsIndex).registerA val videoDetailsRegister =
val videoDetailsClass = getInstruction<TwoRegisterInstruction>(videoDetailsIndex).registerA
getInstruction(videoDetailsIndex).getReference<FieldReference>()!!.type val videoDetailsClass =
getInstruction(videoDetailsIndex).getReference<FieldReference>()!!.type
addInstruction( addInstruction(
videoDetailsIndex + 1, videoDetailsIndex + 1,
"invoke-direct { p0, v$videoDetailsRegister }, " + "invoke-direct { p0, v$videoDetailsRegister }, " +
"$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V", "$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V",
) )
result.classDef.methods.add( result.classDef.methods.add(
ImmutableMethod( ImmutableMethod(
resultMethodType, resultMethodType,
setStreamDataMethodName, setStreamDataMethodName,
listOf(ImmutableMethodParameter(videoDetailsClass, annotations, "videoDetails")), listOf(
"V", ImmutableMethodParameter(
AccessFlags.PRIVATE.value or AccessFlags.FINAL.value, videoDetailsClass,
annotations, annotations,
null, "videoDetails"
MutableMethodImplementation(9), )
).toMutable().apply { ),
addInstructionsWithLabels( "V",
0, AccessFlags.PRIVATE.value or AccessFlags.FINAL.value,
""" annotations,
null,
MutableMethodImplementation(9),
).toMutable().apply {
addInstructionsWithLabels(
0,
"""
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->isSpoofingEnabled()Z invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->isSpoofingEnabled()Z
move-result v0 move-result v0
if-eqz v0, :disabled if-eqz v0, :disabled
@ -153,44 +162,52 @@ fun baseSpoofStreamingDataPatch(
:disabled :disabled
return-void return-void
""", """,
) )
}, },
)
}
}
videoStreamingDataConstructorFingerprint.methodOrThrow(videoStreamingDataToStringFingerprint)
.apply {
val formatStreamModelInitIndex = indexOfFormatStreamModelInitInstruction(this)
val getVideoIdIndex =
indexOfFirstInstructionReversedOrThrow(formatStreamModelInitIndex) {
val reference = getReference<FieldReference>()
opcode == Opcode.IGET_OBJECT &&
reference?.type == "Ljava/lang/String;" &&
reference.definingClass == definingClass
}
val getVideoIdReference =
getInstruction<ReferenceInstruction>(getVideoIdIndex).reference
val insertIndex = indexOfFirstInstructionReversedOrThrow(getVideoIdIndex) {
opcode == Opcode.IGET_OBJECT &&
getReference<FieldReference>()?.definingClass == STREAMING_DATA_INTERFACE
}
val (freeRegister, streamingDataRegister) = with(
getInstruction<TwoRegisterInstruction>(
insertIndex
)
) {
Pair(registerA, registerB)
}
val definingClassRegister =
getInstruction<TwoRegisterInstruction>(getVideoIdIndex).registerB
val insertReference = getInstruction<ReferenceInstruction>(insertIndex).reference
replaceInstruction(
insertIndex,
"iget-object v$freeRegister, v$freeRegister, $insertReference"
) )
} addInstructions(
} insertIndex, """
videoStreamingDataConstructorFingerprint.methodOrThrow(videoStreamingDataToStringFingerprint).apply {
val formatStreamModelInitIndex = indexOfFormatStreamModelInitInstruction(this)
val getVideoIdIndex = indexOfFirstInstructionReversedOrThrow(formatStreamModelInitIndex) {
val reference = getReference<FieldReference>()
opcode == Opcode.IGET_OBJECT &&
reference?.type == "Ljava/lang/String;" &&
reference.definingClass == definingClass
}
val getVideoIdReference = getInstruction<ReferenceInstruction>(getVideoIdIndex).reference
val insertIndex = indexOfFirstInstructionReversedOrThrow(getVideoIdIndex) {
opcode == Opcode.IGET_OBJECT &&
getReference<FieldReference>()?.definingClass == STREAMING_DATA_INTERFACE
}
val (freeRegister, streamingDataRegister) = with(getInstruction<TwoRegisterInstruction>(insertIndex)) {
Pair(registerA, registerB)
}
val definingClassRegister = getInstruction<TwoRegisterInstruction>(getVideoIdIndex).registerB
val insertReference = getInstruction<ReferenceInstruction>(insertIndex).reference
replaceInstruction(
insertIndex,
"iget-object v$freeRegister, v$freeRegister, $insertReference"
)
addInstructions(
insertIndex, """
iget-object v$freeRegister, v$definingClassRegister, $getVideoIdReference iget-object v$freeRegister, v$definingClassRegister, $getVideoIdReference
invoke-static { v$freeRegister, v$streamingDataRegister }, $EXTENSION_CLASS_DESCRIPTOR->getOriginalStreamingData(Ljava/lang/String;$STREAMING_DATA_INTERFACE)$STREAMING_DATA_INTERFACE invoke-static { v$freeRegister, v$streamingDataRegister }, $EXTENSION_CLASS_DESCRIPTOR->getOriginalStreamingData(Ljava/lang/String;$STREAMING_DATA_INTERFACE)$STREAMING_DATA_INTERFACE
move-result-object v$freeRegister move-result-object v$freeRegister
""" """
) )
} }
// endregion // endregion

View File

@ -45,6 +45,7 @@ internal val miniplayerModernCloseButtonFingerprint = legacyFingerprint(
) )
internal const val MINIPLAYER_MODERN_FEATURE_KEY = 45622882L internal const val MINIPLAYER_MODERN_FEATURE_KEY = 45622882L
// In later targets this feature flag does nothing and is dead code. // In later targets this feature flag does nothing and is dead code.
internal const val MINIPLAYER_MODERN_FEATURE_LEGACY_KEY = 45630429L internal const val MINIPLAYER_MODERN_FEATURE_LEGACY_KEY = 45630429L
internal const val MINIPLAYER_DOUBLE_TAP_FEATURE_KEY = 45628823L internal const val MINIPLAYER_DOUBLE_TAP_FEATURE_KEY = 45628823L

View File

@ -173,13 +173,15 @@ val navigationBarComponentsPatch = bytecodePatch(
* It was not too hard to fix, so it was implemented as a patch. * It was not too hard to fix, so it was implemented as a patch.
*/ */
if (is_19_28_or_greater) { if (is_19_28_or_greater) {
val cairoNotificationEnumReference = with (imageEnumConstructorFingerprint.methodOrThrow()) { val cairoNotificationEnumReference =
val stringIndex = indexOfFirstStringInstructionOrThrow(TAB_ACTIVITY_CAIRO_STRING) with(imageEnumConstructorFingerprint.methodOrThrow()) {
val cairoNotificationEnumIndex = indexOfFirstInstructionOrThrow(stringIndex) { val stringIndex =
opcode == Opcode.SPUT_OBJECT indexOfFirstStringInstructionOrThrow(TAB_ACTIVITY_CAIRO_STRING)
val cairoNotificationEnumIndex = indexOfFirstInstructionOrThrow(stringIndex) {
opcode == Opcode.SPUT_OBJECT
}
getInstruction<ReferenceInstruction>(cairoNotificationEnumIndex).reference
} }
getInstruction<ReferenceInstruction>(cairoNotificationEnumIndex).reference
}
setEnumMapFingerprint.methodOrThrow().apply { setEnumMapFingerprint.methodOrThrow().apply {
val enumMapIndex = indexOfFirstInstructionReversedOrThrow { val enumMapIndex = indexOfFirstInstructionReversedOrThrow {
@ -189,7 +191,9 @@ val navigationBarComponentsPatch = bytecodePatch(
reference.name == "put" && reference.name == "put" &&
reference.parameterTypes.firstOrNull() == "Ljava/lang/Enum;" reference.parameterTypes.firstOrNull() == "Ljava/lang/Enum;"
} }
val (enumMapRegister, enumRegister) = getInstruction<FiveRegisterInstruction>(enumMapIndex).let { val (enumMapRegister, enumRegister) = getInstruction<FiveRegisterInstruction>(
enumMapIndex
).let {
Pair(it.registerC, it.registerD) Pair(it.registerC, it.registerD)
} }

View File

@ -209,8 +209,14 @@ val customBrandingIconPatch = resourcePatch(
} }
mapOf( mapOf(
ADAPTIVE_ICON_BACKGROUND_FILE_NAME to getAdaptiveIconResourceFile("res/mipmap-anydpi/ic_launcher.xml", "background"), ADAPTIVE_ICON_BACKGROUND_FILE_NAME to getAdaptiveIconResourceFile(
ADAPTIVE_ICON_FOREGROUND_FILE_NAME to getAdaptiveIconResourceFile("res/mipmap-anydpi/ic_launcher.xml", "foreground") "res/mipmap-anydpi/ic_launcher.xml",
"background"
),
ADAPTIVE_ICON_FOREGROUND_FILE_NAME to getAdaptiveIconResourceFile(
"res/mipmap-anydpi/ic_launcher.xml",
"foreground"
)
).forEach { (oldIconResourceFile, newIconResourceFile) -> ).forEach { (oldIconResourceFile, newIconResourceFile) ->
if (oldIconResourceFile != newIconResourceFile) { if (oldIconResourceFile != newIconResourceFile) {
mipmapDirectories.forEach { mipmapDirectories.forEach {

View File

@ -73,6 +73,7 @@ private fun create9BitSeekbarColorStyles(): String = StringBuilder().apply {
fun roundTo3BitHex(channel8Bits: Int) = fun roundTo3BitHex(channel8Bits: Int) =
(channel8Bits * 255 / 7).toString(16).padStart(2, '0') (channel8Bits * 255 / 7).toString(16).padStart(2, '0')
val r = roundTo3BitHex(red) val r = roundTo3BitHex(red)
val g = roundTo3BitHex(green) val g = roundTo3BitHex(green)
val b = roundTo3BitHex(blue) val b = roundTo3BitHex(blue)
@ -261,8 +262,10 @@ val seekbarComponentsPatch = bytecodePatch(
onCreateMethod onCreateMethod
).forEach { method -> ).forEach { method ->
method.apply { method.apply {
val literalIndex = indexOfFirstLiteralInstructionOrThrow(launchScreenLayoutTypeLotteFeatureFlag) val literalIndex =
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT) indexOfFirstLiteralInstructionOrThrow(launchScreenLayoutTypeLotteFeatureFlag)
val resultIndex =
indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA
addInstructions( addInstructions(
@ -282,8 +285,10 @@ val seekbarComponentsPatch = bytecodePatch(
reference?.definingClass == "Landroid/widget/ImageView;" && reference?.definingClass == "Landroid/widget/ImageView;" &&
reference.name == "getDrawable" reference.name == "getDrawable"
} }
val checkCastIndex = indexOfFirstInstructionOrThrow(drawableIndex, Opcode.CHECK_CAST) val checkCastIndex =
val drawableRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA indexOfFirstInstructionOrThrow(drawableIndex, Opcode.CHECK_CAST)
val drawableRegister =
getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
addInstruction( addInstruction(
checkCastIndex + 1, checkCastIndex + 1,
@ -319,7 +324,10 @@ val seekbarComponentsPatch = bytecodePatch(
// instead of allowing 24 bit color the style is restricted to 9-bit (3 bits per color channel) // instead of allowing 24 bit color the style is restricted to 9-bit (3 bits per color channel)
// and the style color closest to the users custom color is used for the splash screen. // and the style color closest to the users custom color is used for the splash screen.
arrayOf( arrayOf(
inputStreamFromBundledResource("youtube/seekbar/values", "attrs.xml")!! to "res/values/attrs.xml", inputStreamFromBundledResource(
"youtube/seekbar/values",
"attrs.xml"
)!! to "res/values/attrs.xml",
ByteArrayInputStream(create9BitSeekbarColorStyles().toByteArray()) to "res/values/styles.xml" ByteArrayInputStream(create9BitSeekbarColorStyles().toByteArray()) to "res/values/styles.xml"
).forEach { (source, destination) -> ).forEach { (source, destination) ->
"resources".copyXmlNode( "resources".copyXmlNode(
@ -328,7 +336,10 @@ val seekbarComponentsPatch = bytecodePatch(
).close() ).close()
} }
fun setSplashDrawablePathFillColor(xmlFileNames: Iterable<String>, vararg resourceNames: String) { fun setSplashDrawablePathFillColor(
xmlFileNames: Iterable<String>,
vararg resourceNames: String
) {
xmlFileNames.forEach { xmlFileName -> xmlFileNames.forEach { xmlFileName ->
context.document(xmlFileName).use { document -> context.document(xmlFileName).use { document ->
resourceNames.forEach { elementId -> resourceNames.forEach { elementId ->
@ -342,7 +353,10 @@ val seekbarComponentsPatch = bytecodePatch(
throw PatchException("Could not find $attribute for $elementId") throw PatchException("Could not find $attribute for $elementId")
} }
element.setAttribute(attribute, "?attr/$splashSeekbarColorAttributeName") element.setAttribute(
attribute,
"?attr/$splashSeekbarColorAttributeName"
)
} }
} }
} }

View File

@ -217,7 +217,8 @@ private val shortsCustomActionsPatch = bytecodePatch(
opcode == Opcode.INVOKE_VIRTUAL && opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.returnType == "Ljava/lang/Object;" getReference<MethodReference>()?.returnType == "Ljava/lang/Object;"
} }
val getObjectReference = getInstruction<ReferenceInstruction>(getObjectIndex).reference as MethodReference val getObjectReference =
getInstruction<ReferenceInstruction>(getObjectIndex).reference as MethodReference
val bottomSheetMenuInitializeIndex = indexOfFirstInstructionOrThrow { val bottomSheetMenuInitializeIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>() val reference = getReference<MethodReference>()
@ -225,17 +226,22 @@ private val shortsCustomActionsPatch = bytecodePatch(
reference?.returnType == "V" && reference?.returnType == "V" &&
reference.parameterTypes[1] == "Ljava/lang/Object;" reference.parameterTypes[1] == "Ljava/lang/Object;"
} }
val bottomSheetMenuObjectRegister = getInstruction<RegisterRangeInstruction>(bottomSheetMenuInitializeIndex).startRegister val bottomSheetMenuObjectRegister =
val bottomSheetMenuObject = (getInstruction<ReferenceInstruction>(bottomSheetMenuInitializeIndex).reference as MethodReference).parameterTypes[0]!! getInstruction<RegisterRangeInstruction>(bottomSheetMenuInitializeIndex).startRegister
val bottomSheetMenuObject =
(getInstruction<ReferenceInstruction>(bottomSheetMenuInitializeIndex).reference as MethodReference).parameterTypes[0]!!
val bottomSheetMenuListIndex = it.patternMatch!!.startIndex val bottomSheetMenuListIndex = it.patternMatch!!.startIndex
val bottomSheetMenuListField = (getInstruction<ReferenceInstruction>(bottomSheetMenuListIndex).reference as FieldReference) val bottomSheetMenuListField =
(getInstruction<ReferenceInstruction>(bottomSheetMenuListIndex).reference as FieldReference)
val bottomSheetMenuClass = bottomSheetMenuListField.definingClass val bottomSheetMenuClass = bottomSheetMenuListField.definingClass
val bottomSheetMenuList = bottomSheetMenuListField.type val bottomSheetMenuList = bottomSheetMenuListField.type
val bottomSheetMenuClassRegister = getInstruction<TwoRegisterInstruction>(bottomSheetMenuListIndex).registerB val bottomSheetMenuClassRegister =
val bottomSheetMenuListRegister = getInstruction<TwoRegisterInstruction>(bottomSheetMenuListIndex).registerA getInstruction<TwoRegisterInstruction>(bottomSheetMenuListIndex).registerB
val bottomSheetMenuListRegister =
getInstruction<TwoRegisterInstruction>(bottomSheetMenuListIndex).registerA
addInstruction( addInstruction(
bottomSheetMenuListIndex + 1, bottomSheetMenuListIndex + 1,
@ -249,10 +255,11 @@ private val shortsCustomActionsPatch = bytecodePatch(
"$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->setFlyoutMenuObject(Ljava/lang/Object;)V" "$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->setFlyoutMenuObject(Ljava/lang/Object;)V"
) )
val addFlyoutMenuMethod = findMethodOrThrow(EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR) { val addFlyoutMenuMethod =
name == "addFlyoutMenu" && findMethodOrThrow(EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR) {
accessFlags == AccessFlags.PRIVATE or AccessFlags.STATIC name == "addFlyoutMenu" &&
} accessFlags == AccessFlags.PRIVATE or AccessFlags.STATIC
}
val customActionClass = with(addFlyoutMenuMethod) { val customActionClass = with(addFlyoutMenuMethod) {
val thirdParameter = parameters[2] val thirdParameter = parameters[2]
@ -277,7 +284,8 @@ private val shortsCustomActionsPatch = bytecodePatch(
val bottomSheetMenuItemBuilderMethod = bottomSheetMenuItemBuilderFingerprint val bottomSheetMenuItemBuilderMethod = bottomSheetMenuItemBuilderFingerprint
.methodOrThrow() .methodOrThrow()
val newParameter = bottomSheetMenuItemBuilderMethod.parameters + listOf(customActionClass) val newParameter =
bottomSheetMenuItemBuilderMethod.parameters + listOf(customActionClass)
it.classDef.methods.add( it.classDef.methods.add(
bottomSheetMenuItemBuilderMethod bottomSheetMenuItemBuilderMethod
@ -291,7 +299,8 @@ private val shortsCustomActionsPatch = bytecodePatch(
opcode == Opcode.INVOKE_DIRECT && opcode == Opcode.INVOKE_DIRECT &&
getReference<MethodReference>()?.returnType == "Landroid/graphics/drawable/Drawable;" getReference<MethodReference>()?.returnType == "Landroid/graphics/drawable/Drawable;"
} }
val drawableRegister = getInstruction<OneRegisterInstruction>(drawableIndex + 1).registerA val drawableRegister =
getInstruction<OneRegisterInstruction>(drawableIndex + 1).registerA
addInstructions( addInstructions(
drawableIndex + 2, """ drawableIndex + 2, """
@ -301,11 +310,14 @@ private val shortsCustomActionsPatch = bytecodePatch(
) )
val charSequenceIndex = indexOfSpannedCharSequenceInstruction(this) val charSequenceIndex = indexOfSpannedCharSequenceInstruction(this)
val charSequenceRegister = getInstruction<OneRegisterInstruction>(charSequenceIndex + 1).registerA val charSequenceRegister =
getInstruction<OneRegisterInstruction>(charSequenceIndex + 1).registerA
val insertIndex = charSequenceIndex + 2 val insertIndex = charSequenceIndex + 2
if (getInstruction<ReferenceInstruction>(insertIndex).reference.toString().startsWith("Lapp/revanced")) { if (getInstruction<ReferenceInstruction>(insertIndex).reference.toString()
.startsWith("Lapp/revanced")
) {
removeInstructions(insertIndex, 2) removeInstructions(insertIndex, 2)
} }

View File

@ -137,7 +137,8 @@ val playerTypeHookPatch = bytecodePatch(
searchQueryClassFingerprint.methodOrThrow().apply { searchQueryClassFingerprint.methodOrThrow().apply {
val searchQueryIndex = indexOfStringIsEmptyInstruction(this) - 1 val searchQueryIndex = indexOfStringIsEmptyInstruction(this) - 1
val searchQueryFieldReference = getInstruction<ReferenceInstruction>(searchQueryIndex).reference val searchQueryFieldReference =
getInstruction<ReferenceInstruction>(searchQueryIndex).reference
val searchQueryClass = (searchQueryFieldReference as FieldReference).definingClass val searchQueryClass = (searchQueryFieldReference as FieldReference).definingClass
findMethodOrThrow(searchQueryClass).apply { findMethodOrThrow(searchQueryClass).apply {

View File

@ -187,7 +187,10 @@ val videoInformationPatch = bytecodePatch(
} }
} }
fun Pair<String, Fingerprint>.getPlayerResponseInstruction(returnType: String, fromString: Boolean? = null): String { fun Pair<String, Fingerprint>.getPlayerResponseInstruction(
returnType: String,
fromString: Boolean? = null
): String {
methodOrThrow().apply { methodOrThrow().apply {
val startIndex = if (fromString == true) val startIndex = if (fromString == true)
matchOrThrow().stringMatches!!.first().index matchOrThrow().stringMatches!!.first().index