mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-27 12:41:03 +00:00
original -> immutable
This commit is contained in:
@@ -35,7 +35,7 @@ val `Hide music video ads` by creatingBytecodePatch(
|
||||
SwitchPreference("revanced_music_hide_video_ads"),
|
||||
)
|
||||
|
||||
navigate(showVideoAdsParentMethod.originalMethod)
|
||||
navigate(showVideoAdsParentMethod.immutableMethod)
|
||||
.to(showVideoAdsParentMethod.instructionMatches.first().index + 1)
|
||||
.stop()
|
||||
.addInstructions(
|
||||
|
||||
@@ -75,7 +75,7 @@ val `Change miniplayer color` by creatingBytecodePatch(
|
||||
miniPlayerConstructorMethod.classDef.methods.single { method ->
|
||||
method.accessFlags == AccessFlags.PUBLIC.value or AccessFlags.FINAL.value &&
|
||||
method.returnType == "V" &&
|
||||
method.parameters == it.originalMethod.parameters
|
||||
method.parameters == it.immutableMethod.parameters
|
||||
}.apply {
|
||||
val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.INVOKE_DIRECT)
|
||||
val freeRegister = findFreeRegister(insertIndex)
|
||||
|
||||
@@ -19,7 +19,7 @@ private val customThemeBytecodePatch = bytecodePatch {
|
||||
dependsOn(sharedExtensionPatch)
|
||||
|
||||
apply {
|
||||
val colorSpaceUtilsClassDef = colorSpaceUtilsClassMethod.originalClassDef
|
||||
val colorSpaceUtilsClassDef = colorSpaceUtilsClassMethod.immutableClassDef
|
||||
|
||||
// Hook a util method that converts ARGB to RGBA in the sRGB color space to replace hardcoded accent colors.
|
||||
convertArgbToRgbaMethod.match(colorSpaceUtilsClassDef).method.apply {
|
||||
|
||||
@@ -17,7 +17,7 @@ val `Fix Facebook login` by creatingBytecodePatch(
|
||||
// Override the Facebook SDK to always handle the login using the web browser, which does not perform
|
||||
// signature checks.
|
||||
|
||||
val katanaProxyLoginMethodHandlerClass = katanaProxyLoginMethodHandlerClassMethod.originalClassDef
|
||||
val katanaProxyLoginMethodHandlerClass = katanaProxyLoginMethodHandlerClassMethod.immutableClassDef
|
||||
// Always return 0 (no Intent was launched) as the result of trying to authorize with the Facebook app to
|
||||
// make the login fallback to a web browser window.
|
||||
katanaProxyLoginMethodTryAuthorizeMethod
|
||||
|
||||
@@ -59,7 +59,7 @@ val `Change lyrics provider` by creatingBytecodePatch(
|
||||
}
|
||||
|
||||
apply {
|
||||
val httpClientBuilderMethod = httpClientBuilderMethod.originalMethod
|
||||
val httpClientBuilderMethod = httpClientBuilderMethod.immutableMethod
|
||||
|
||||
// region Create a modified copy of the HTTP client builder method with the custom lyrics provider host.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ val `Sanitize sharing links` by creatingBytecodePatch(
|
||||
val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" +
|
||||
"sanitizeSharingLink(Ljava/lang/String;)Ljava/lang/String;"
|
||||
|
||||
val copyFingerprint = if (shareCopyUrlMethod.originalMethodOrNull != null) {
|
||||
val copyFingerprint = if (shareCopyUrlMethod.immutableMethodOrNull != null) {
|
||||
shareCopyUrlMethod
|
||||
} else {
|
||||
oldShareCopyUrlMethod
|
||||
@@ -48,8 +48,8 @@ val `Sanitize sharing links` by creatingBytecodePatch(
|
||||
|
||||
// Android native share sheet is used for all other quick share types (X, WhatsApp, etc).
|
||||
val shareUrlParameter: String
|
||||
val shareSheetFingerprint = if (formatAndroidShareSheetUrlMethod.originalMethodOrNull != null) {
|
||||
val methodAccessFlags = formatAndroidShareSheetUrlMethod.originalMethod
|
||||
val shareSheetFingerprint = if (formatAndroidShareSheetUrlMethod.immutableMethodOrNull != null) {
|
||||
val methodAccessFlags = formatAndroidShareSheetUrlMethod.immutableMethod
|
||||
shareUrlParameter = if (AccessFlags.STATIC.isSet(methodAccessFlags.accessFlags)) {
|
||||
// In newer implementations the method is static, so p0 is not `this`.
|
||||
"p1"
|
||||
|
||||
@@ -18,8 +18,8 @@ val `Disable subscription suggestions` by creatingBytecodePatch {
|
||||
val label = "original"
|
||||
|
||||
val className = getModulesMethodMatch.classDef.type
|
||||
val originalMethod = getModulesMethodMatch.method
|
||||
val returnType = originalMethod.returnType
|
||||
val immutableMethod = getModulesMethodMatch.method
|
||||
val returnType = immutableMethod.returnType
|
||||
|
||||
getModulesMethodMatch.classDef.methods.add(
|
||||
ImmutableMethod(
|
||||
@@ -51,8 +51,8 @@ val `Disable subscription suggestions` by creatingBytecodePatch {
|
||||
)
|
||||
|
||||
val getModulesIndex = getModulesMethodMatch.indices.first()
|
||||
originalMethod.removeInstruction(getModulesIndex)
|
||||
originalMethod.addInstructions(
|
||||
immutableMethod.removeInstruction(getModulesIndex)
|
||||
immutableMethod.addInstructions(
|
||||
getModulesIndex,
|
||||
"""
|
||||
invoke-direct {p0}, $className->$helperMethodName()$returnType
|
||||
|
||||
@@ -43,7 +43,7 @@ val `Playback speed` by creatingBytecodePatch(
|
||||
"""
|
||||
# Video playback location (e.g. home page, following page or search result page) retrieved using getEnterFrom method.
|
||||
const/4 v0, 0x1
|
||||
invoke-virtual { p0, v0 }, ${getEnterFromMethod.originalMethod}
|
||||
invoke-virtual { p0, v0 }, ${getEnterFromMethod.immutableMethod}
|
||||
move-result-object v0
|
||||
|
||||
# Model of current video retrieved using getCurrentAweme method.
|
||||
|
||||
@@ -24,15 +24,15 @@ val overrideFeatureFlagsPatch = bytecodePatch(
|
||||
) {
|
||||
|
||||
apply {
|
||||
val configurationClass = getFeatureValueMethod.originalMethod.definingClass
|
||||
val featureClass = getFeatureValueMethod.originalMethod.parameterTypes[0].toString()
|
||||
val configurationClass = getFeatureValueMethod.immutableMethod.definingClass
|
||||
val featureClass = getFeatureValueMethod.immutableMethod.parameterTypes[0].toString()
|
||||
|
||||
// The method we want to inject into does not have enough registers, so we inject a helper method
|
||||
// and inject more instructions into it later, see addOverride.
|
||||
// This is not in an extension since the unused variable would get compiled away and the method would
|
||||
// get compiled to only have one register, which is not enough for our later injected instructions.
|
||||
val helperMethod = ImmutableMethod(
|
||||
getFeatureValueMethod.originalMethod.definingClass,
|
||||
getFeatureValueMethod.immutableMethod.definingClass,
|
||||
"getValueOverride",
|
||||
listOf(ImmutableMethodParameter(featureClass, null, "feature")),
|
||||
"Ljava/lang/String;",
|
||||
|
||||
@@ -56,7 +56,7 @@ val `Disable double tap actions` by creatingBytecodePatch(
|
||||
val doubleTapInfoGetSeekSourceFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameterTypes("Z")
|
||||
returnType(seekTypeEnumMethod.originalClassDef.type)
|
||||
returnType(seekTypeEnumMethod.immutableClassDef.type)
|
||||
opcodes(
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.SGET_OBJECT,
|
||||
|
||||
@@ -53,7 +53,7 @@ val `Change form factor` by creatingBytecodePatch(
|
||||
instructions(
|
||||
fieldAccess(smali = "Landroid/os/Build;->MODEL:Ljava/lang/String;"),
|
||||
fieldAccess(
|
||||
definingClass = formFactorEnumConstructorMethod.originalClassDef.type,
|
||||
definingClass = formFactorEnumConstructorMethod.immutableClassDef.type,
|
||||
type = "I",
|
||||
afterAtMost(50),
|
||||
),
|
||||
|
||||
@@ -45,12 +45,12 @@ val `Hide end screen suggested video` by creatingBytecodePatch(
|
||||
)
|
||||
|
||||
removeOnLayoutChangeListenerMethod.let {
|
||||
val endScreenMethod = navigate(it.originalMethod).to(it.indices.last()).stop() // TODO
|
||||
val endScreenMethod = navigate(it.immutableMethod).to(it.indices.last()).stop() // TODO
|
||||
|
||||
endScreenMethod.apply {
|
||||
val autoNavStatusMethodName = autoNavStatusMethod.match(
|
||||
autoNavConstructorMethod.classDef,
|
||||
).originalMethod.name
|
||||
).immutableMethod.name
|
||||
|
||||
val invokeIndex = indexOfFirstInstructionOrThrow {
|
||||
val reference = getReference<MethodReference>()
|
||||
|
||||
@@ -270,7 +270,7 @@ val `Hide layout components` by creatingBytecodePatch(
|
||||
// region Watermark (legacy code for old versions of YouTube)
|
||||
|
||||
showWatermarkMethod.match(
|
||||
playerOverlayMethod.originalClassDef,
|
||||
playerOverlayMethod.immutableClassDef,
|
||||
).method.apply {
|
||||
val index = implementation!!.instructions.size - 5
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ val `Hide info cards` by creatingBytecodePatch(
|
||||
)
|
||||
|
||||
// Edit: This old non litho code may be obsolete and no longer used by any supported versions.
|
||||
infocardsIncognitoMethod.match(infocardsIncognitoParentMethod.originalClassDef).method.apply {
|
||||
infocardsIncognitoMethod.match(infocardsIncognitoParentMethod.immutableClassDef).method.apply {
|
||||
val invokeInstructionIndex = implementation!!.instructions.indexOfFirst {
|
||||
it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal &&
|
||||
((it as ReferenceInstruction).reference.toString() == "Landroid/view/View;->setVisibility(I)V")
|
||||
|
||||
@@ -43,7 +43,7 @@ val `Hide related video overlay` by creatingBytecodePatch(
|
||||
)
|
||||
|
||||
relatedEndScreenResultsMethod.match(
|
||||
relatedEndScreenResultsParentMethod.originalClassDef,
|
||||
relatedEndScreenResultsParentMethod.immutableClassDef,
|
||||
).method.apply {
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
|
||||
@@ -207,7 +207,7 @@ val `Hide Shorts componentsby creatingBytecodePatch(
|
||||
|
||||
// Hook to get the pivotBar view.
|
||||
setPivotBarVisibilityMethod.match(
|
||||
setPivotBarVisibilityParentMethod.originalClassDef,
|
||||
setPivotBarVisibilityParentMethod.immutableClassDef,
|
||||
).let { result ->
|
||||
result.method.apply {
|
||||
val insertIndex = result.indices.last()
|
||||
@@ -230,7 +230,7 @@ val `Hide Shorts componentsby creatingBytecodePatch(
|
||||
} else {
|
||||
legacyRenderBottomNavigationBarLegacyParentMethod
|
||||
}
|
||||
).originalClassDef,
|
||||
).immutableClassDef,
|
||||
).method.addInstruction(
|
||||
0,
|
||||
"invoke-static { p1 }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar(Ljava/lang/String;)V",
|
||||
|
||||
@@ -236,7 +236,7 @@ val Miniplayer by creatingBytecodePatch(
|
||||
|
||||
if (!is_20_37_or_greater) {
|
||||
miniplayerOverrideNoContextMethod.match(
|
||||
miniplayerDimensionsCalculatorParentMethod.originalClassDef,
|
||||
miniplayerDimensionsCalculatorParentMethod.immutableClassDef,
|
||||
).method.apply {
|
||||
findReturnIndicesReversed().forEach { index ->
|
||||
insertLegacyTabletMiniplayerOverride(
|
||||
@@ -250,7 +250,7 @@ val Miniplayer by creatingBytecodePatch(
|
||||
// region Legacy tablet miniplayer hooks.
|
||||
miniplayerOverrideMethod.let {
|
||||
val appNameStringIndex = it.indices.last()
|
||||
navigate(it.originalMethod).to(appNameStringIndex).stop().apply {
|
||||
navigate(it.immutableMethod).to(appNameStringIndex).stop().apply {
|
||||
findReturnIndicesReversed().forEach { index ->
|
||||
insertLegacyTabletMiniplayerOverride(
|
||||
index,
|
||||
@@ -368,7 +368,7 @@ val Miniplayer by creatingBytecodePatch(
|
||||
// Fix this, by swapping the drawable resource values with each other.
|
||||
if (!is_19_17_or_greater) {
|
||||
miniplayerModernExpandCloseDrawablesMethod.match(
|
||||
miniplayerModernViewParentMethod.originalClassDef,
|
||||
miniplayerModernViewParentMethod.immutableClassDef,
|
||||
).method.apply {
|
||||
listOf(
|
||||
ytOutlinePictureInPictureWhite24 to ytOutlineXWhite24,
|
||||
|
||||
@@ -121,16 +121,16 @@ val `Return YouTube Dislike` by creatingBytecodePatch(
|
||||
// This hook handles all situations, as it's where the created Spans are stored and later reused.
|
||||
|
||||
// Find the field name of the conversion context.
|
||||
val conversionContextClass = conversionContextToStringMethod.originalClassDef
|
||||
val textComponentConversionContextField = textComponentConstructorMethod.originalClassDef.fields.find {
|
||||
val conversionContextClass = conversionContextToStringMethod.immutableClassDef
|
||||
val textComponentConversionContextField = textComponentConstructorMethod.immutableClassDef.fields.find {
|
||||
it.type == conversionContextClass.type ||
|
||||
// 20.41+ uses superclass field type.
|
||||
it.type == conversionContextClass.superclass
|
||||
} ?: throw PatchException("Could not find conversion context field")
|
||||
|
||||
textComponentLookupMethod.match(textComponentConstructorMethod.originalClassDef).method.apply {
|
||||
textComponentLookupMethod.match(textComponentConstructorMethod.immutableClassDef).method.apply {
|
||||
// Find the instruction for creating the text data object.
|
||||
val textDataClassType = textComponentDataMethod.originalClassDef.type
|
||||
val textDataClassType = textComponentDataMethod.immutableClassDef.type
|
||||
|
||||
val insertIndex: Int
|
||||
val charSequenceRegister: Int
|
||||
@@ -267,7 +267,7 @@ val `Return YouTube Dislike` by creatingBytecodePatch(
|
||||
// Additional text measurement method. Used if YouTube decides not to animate the likes count
|
||||
// and sometimes used for initial video load.
|
||||
rollingNumberMeasureStaticLabelMethod.match(
|
||||
rollingNumberMeasureStaticLabelParentMethod.originalClassDef,
|
||||
rollingNumberMeasureStaticLabelParentMethod.immutableClassDef,
|
||||
).let {
|
||||
val measureTextIndex = it.instructionMatches.first().index + 1
|
||||
it.method.apply {
|
||||
|
||||
@@ -64,7 +64,7 @@ val `Wide search bar` by creatingBytecodePatch(
|
||||
|
||||
setWordmarkHeaderMethod.let {
|
||||
// Navigate to the method that checks if the YT logo is shown beside the search bar.
|
||||
val shouldShowLogoMethod = with(it.originalMethod) {
|
||||
val shouldShowLogoMethod = with(it.immutableMethod) {
|
||||
val invokeStaticIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_STATIC &&
|
||||
getReference<MethodReference>()?.returnType == "Z"
|
||||
|
||||
@@ -58,7 +58,7 @@ val seekbarColorPatch = bytecodePatch(
|
||||
it.method.addColorChangeInstructions(it.instructionMatches.first().index)
|
||||
}
|
||||
|
||||
setSeekbarClickedColorMethod.originalMethod.let {
|
||||
setSeekbarClickedColorMethod.immutableMethod.let {
|
||||
val setColorMethodIndex = setSeekbarClickedColorMethod.instructionMatches.first().index + 1
|
||||
|
||||
navigate(it).to(setColorMethodIndex).stop().apply {
|
||||
@@ -154,7 +154,7 @@ val seekbarColorPatch = bytecodePatch(
|
||||
// Hook the splash animation to set the a seekbar color.
|
||||
mainActivityOnCreateMethod.apply {
|
||||
val setAnimationIntMethodName =
|
||||
lottieAnimationViewSetAnimationIntMethod.originalMethod.name
|
||||
lottieAnimationViewSetAnimationIntMethod.immutableMethod.name
|
||||
|
||||
findInstructionIndicesReversedOrThrow {
|
||||
val reference = getReference<MethodReference>()
|
||||
@@ -176,7 +176,7 @@ val seekbarColorPatch = bytecodePatch(
|
||||
lottieAnimationViewSetAnimationIntMethod.classDef.methods.apply {
|
||||
val addedMethodName = "patch_setAnimation"
|
||||
val setAnimationIntName = lottieAnimationViewSetAnimationIntMethod
|
||||
.originalMethod.name
|
||||
.immutableMethod.name
|
||||
|
||||
add(
|
||||
ImmutableMethod(
|
||||
@@ -202,8 +202,8 @@ val seekbarColorPatch = bytecodePatch(
|
||||
val factoryStreamName: CharSequence
|
||||
val factoryStreamReturnType: CharSequence
|
||||
lottieCompositionFactoryFromJsonInputStreamMethod.match(
|
||||
lottieCompositionFactoryZipMethod.originalClassDef,
|
||||
).originalMethod.apply {
|
||||
lottieCompositionFactoryZipMethod.immutableClassDef,
|
||||
).immutableMethod.apply {
|
||||
factoryStreamClass = definingClass
|
||||
factoryStreamName = name
|
||||
factoryStreamReturnType = returnType
|
||||
@@ -214,11 +214,11 @@ val seekbarColorPatch = bytecodePatch(
|
||||
parameterTypes(factoryStreamReturnType.toString())
|
||||
returnType("V")
|
||||
custom { _, classDef ->
|
||||
classDef.type == lottieAnimationViewSetAnimationIntMethod.originalClassDef.type
|
||||
classDef.type == lottieAnimationViewSetAnimationIntMethod.immutableClassDef.type
|
||||
}
|
||||
}
|
||||
val setAnimationStreamName = lottieAnimationViewSetAnimationStreamFingerprint
|
||||
.originalMethod.name
|
||||
.immutableMethod.name
|
||||
|
||||
add(
|
||||
ImmutableMethod(
|
||||
|
||||
@@ -81,7 +81,7 @@ val `Remove background playback restrictions` by creatingBytecodePatch(
|
||||
}
|
||||
|
||||
// Enable background playback option in YouTube settings
|
||||
backgroundPlaybackSettingsMethod.originalMethod.apply {
|
||||
backgroundPlaybackSettingsMethod.immutableMethod.apply {
|
||||
val booleanCalls = instructions.withIndex().filter {
|
||||
it.value.getReference<MethodReference>()?.returnType == "Z"
|
||||
}
|
||||
|
||||
@@ -31,13 +31,13 @@ val cronetImageUrlHookPatch = bytecodePatch(
|
||||
|
||||
apply {
|
||||
loadImageUrlMethod = messageDigestImageUrlMethod
|
||||
.match(messageDigestImageUrlParentMethod.originalClassDef).method
|
||||
.match(messageDigestImageUrlParentMethod.immutableClassDef).method
|
||||
|
||||
loadImageSuccessCallbackMethod = onSucceededMethod
|
||||
.match(onResponseStartedMethod.originalClassDef).method
|
||||
.match(onResponseStartedMethod.immutableClassDef).method
|
||||
|
||||
loadImageErrorCallbackMethod = onFailureMethod
|
||||
.match(onResponseStartedMethod.originalClassDef).method
|
||||
.match(onResponseStartedMethod.immutableClassDef).method
|
||||
|
||||
// The URL is required for the failure callback hook, but the URL field is obfuscated.
|
||||
// Add a helper get method that returns the URL field.
|
||||
|
||||
@@ -115,7 +115,7 @@ val lithoFilterPatch = bytecodePatch(
|
||||
val conversionContextIdentifierField = conversionContextToStringMethod.method
|
||||
.findFieldFromToString("identifierProperty=")
|
||||
|
||||
val conversionContextPathBuilderField = conversionContextToStringMethod.originalClassDef
|
||||
val conversionContextPathBuilderField = conversionContextToStringMethod.immutableClassDef
|
||||
.fields.single { field -> field.type == "Ljava/lang/StringBuilder;" }
|
||||
|
||||
// Find class and methods to create an empty component.
|
||||
|
||||
@@ -169,7 +169,7 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
|
||||
interfaces.add(EXTENSION_TOOLBAR_INTERFACE)
|
||||
|
||||
val definingClass = type
|
||||
val obfuscatedMethodName = it.originalMethod.name
|
||||
val obfuscatedMethodName = it.immutableMethod.name
|
||||
val returnType = "Landroid/graphics/drawable/Drawable;"
|
||||
|
||||
methods.add(
|
||||
|
||||
@@ -6,6 +6,7 @@ import app.revanced.patcher.extensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.immutableClassDef
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
@@ -90,21 +91,20 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
||||
// region Force old video quality menu.
|
||||
|
||||
// Replace the speeds float array with custom speeds.
|
||||
speedArrayGeneratorMethod.let {
|
||||
val matches = it.instructionMatches
|
||||
speedArrayGeneratorMethodMatch.let {
|
||||
it.method.apply {
|
||||
val playbackSpeedsArrayType = "$EXTENSION_CLASS_DESCRIPTOR->customPlaybackSpeeds:[F"
|
||||
// Apply changes from last index to first to preserve indexes.
|
||||
|
||||
val originalArrayFetchIndex = matches[5].index
|
||||
val originalArrayFetchDestination = matches[5].getInstruction<OneRegisterInstruction>().registerA
|
||||
val originalArrayFetchIndex = it.indices[5]
|
||||
val originalArrayFetchDestination = getInstruction<OneRegisterInstruction>(it.indices[5]).registerA
|
||||
replaceInstruction(
|
||||
originalArrayFetchIndex,
|
||||
"sget-object v$originalArrayFetchDestination, $playbackSpeedsArrayType",
|
||||
)
|
||||
|
||||
val arrayLengthConstDestination = matches[3].getInstruction<OneRegisterInstruction>().registerA
|
||||
val newArrayIndex = matches[4].index
|
||||
val arrayLengthConstDestination = getInstruction<OneRegisterInstruction>(it.indices[3]).registerA
|
||||
val newArrayIndex = it.indices[4]
|
||||
addInstructions(
|
||||
newArrayIndex,
|
||||
"""
|
||||
@@ -113,7 +113,7 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
||||
""",
|
||||
)
|
||||
|
||||
val sizeCallIndex = matches[0].index + 1
|
||||
val sizeCallIndex = it.indices[0] + 1
|
||||
val sizeCallResultRegister = getInstruction<OneRegisterInstruction>(sizeCallIndex).registerA
|
||||
replaceInstruction(sizeCallIndex, "const/4 v$sizeCallResultRegister, 0x0")
|
||||
}
|
||||
@@ -123,9 +123,9 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
||||
// This is later used to call "showOldPlaybackSpeedMenu" on the instance.
|
||||
|
||||
val instanceField = ImmutableField(
|
||||
getOldPlaybackSpeedsMethod.originalClassDef.type,
|
||||
getOldPlaybackSpeedsMethod.immutableClassDef.type,
|
||||
"INSTANCE",
|
||||
getOldPlaybackSpeedsMethod.originalClassDef.type,
|
||||
getOldPlaybackSpeedsMethod.immutableClassDef.type,
|
||||
AccessFlags.PUBLIC.value or AccessFlags.STATIC.value,
|
||||
null,
|
||||
null,
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
package app.revanced.patches.youtube.video.speed.custom
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.opcodes
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.getOldPlaybackSpeedsMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.getOldPlaybackSpeedsMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"menu_item_playback_speed",
|
||||
) {
|
||||
parameterTypes("[L", "I")
|
||||
strings("menu_item_playback_speed")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.showOldPlaybackSpeedMenuMethod by gettingFirstMethodDeclaratively {
|
||||
@@ -25,10 +19,10 @@ internal val BytecodePatchContext.showOldPlaybackSpeedMenuMethod by gettingFirst
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.showOldPlaybackSpeedMenuExtensionMethod by gettingFirstMethodDeclaratively {
|
||||
custom { method, _ -> method.name == "showOldPlaybackSpeedMenu" }
|
||||
name("showOldPlaybackSpeedMenu")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.serverSideMaxSpeedFeatureFlagMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.serverSideMaxSpeedFeatureFlagMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
instructions(
|
||||
@@ -36,17 +30,17 @@ internal val BytecodePatchContext.serverSideMaxSpeedFeatureFlagMethod by getting
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.speedArrayGeneratorMethod by gettingFirstMethodDeclaratively {
|
||||
internal val speedArrayGeneratorMethodMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returnType("[L")
|
||||
parameterTypes("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;")
|
||||
instructions(
|
||||
methodCall(name = "size", returnType = "I"),
|
||||
newInstance("Ljava/text/DecimalFormat;"),
|
||||
method { name == "size" && returnType == "I" },
|
||||
allOf(Opcode.NEW_INSTANCE(), type("Ljava/text/DecimalFormat;")),
|
||||
"0.0#"(),
|
||||
7L(),
|
||||
Opcode.NEW_ARRAY(),
|
||||
fieldAccess(definingClass = "/PlayerConfigModel;", type = "[F"),
|
||||
field { definingClass == "/PlayerConfigModel;" && type == "[F" },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -58,8 +52,8 @@ internal val BytecodePatchContext.speedLimiterMethod by gettingFirstMutableMetho
|
||||
returnType("V")
|
||||
parameterTypes("F", "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;")
|
||||
instructions(
|
||||
0.25f(),
|
||||
4.0f(),
|
||||
0.25f.toRawBits().toLong()(),
|
||||
4.0f.toRawBits().toLong()(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ val videoIdPatch = bytecodePatch(
|
||||
)
|
||||
|
||||
apply {
|
||||
videoIdMethod.match(videoIdParentFingerprint.originalClassDef).let {
|
||||
videoIdMethod.match(videoIdParentFingerprint.immutableClassDef).let {
|
||||
it.method.apply {
|
||||
videoIdMethod = this
|
||||
val index = it.instructionMatches.first().index
|
||||
|
||||
Reference in New Issue
Block a user