mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 13:17:46 +02:00
feat: default-video-quality
patch (#141)
This commit is contained in:
@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.misc.quality.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf("17.22.36", "17.24.35", "17.26.35", "17.27.39")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class DefaultVideoQualityCompatibility
|
@ -0,0 +1,21 @@
|
||||
package app.revanced.patches.youtube.misc.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
|
||||
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||
import app.revanced.patches.youtube.misc.quality.annotations.DefaultVideoQualityCompatibility
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
@Name("video-quality-reference-fingerprint")
|
||||
@MatchingMethod("Lkec;", "b")
|
||||
@DirectPatternScanMethod
|
||||
@DefaultVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoQualityReferenceFingerprint : MethodFingerprint(
|
||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf(
|
||||
Opcode.IPUT_OBJECT, Opcode.RETURN_VOID
|
||||
)
|
||||
)
|
@ -0,0 +1,32 @@
|
||||
|
||||
package app.revanced.patches.youtube.misc.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||
import app.revanced.patches.youtube.misc.quality.annotations.DefaultVideoQualityCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-quality-setter-fingerprint")
|
||||
@MatchingMethod(
|
||||
"Lkec", "a"
|
||||
)
|
||||
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
|
||||
@DefaultVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoQualitySetterFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
listOf("[L", "I", "I", "Z", "I"),
|
||||
listOf(
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
)
|
||||
)
|
@ -0,0 +1,29 @@
|
||||
|
||||
package app.revanced.patches.youtube.misc.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
|
||||
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||
import app.revanced.patches.youtube.misc.quality.annotations.DefaultVideoQualityCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-user-quality-change-fingerprint")
|
||||
@MatchingMethod("Lkec;", "onItemClick")
|
||||
@DirectPatternScanMethod
|
||||
@DefaultVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoUserQualityChangeFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
listOf("L","L","I","J"),
|
||||
listOf(
|
||||
Opcode.MOVE,
|
||||
Opcode.MOVE_WIDE,
|
||||
Opcode.INVOKE_INTERFACE_RANGE,
|
||||
Opcode.RETURN_VOID
|
||||
)
|
||||
)
|
@ -0,0 +1,81 @@
|
||||
package app.revanced.patches.youtube.misc.quality.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.impl.BytecodeData
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Dependencies
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.quality.annotations.DefaultVideoQualityCompatibility
|
||||
import app.revanced.patches.youtube.misc.quality.fingerprints.VideoQualityReferenceFingerprint
|
||||
import app.revanced.patches.youtube.misc.quality.fingerprints.VideoQualitySetterFingerprint
|
||||
import app.revanced.patches.youtube.misc.quality.fingerprints.VideoUserQualityChangeFingerprint
|
||||
import app.revanced.patches.youtube.misc.videoid.fingerprint.VideoIdFingerprint
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.reference.FieldReference
|
||||
|
||||
@Patch(false)
|
||||
@Dependencies(
|
||||
dependencies = [IntegrationsPatch::class]
|
||||
)
|
||||
@Name("default-video-quality")
|
||||
@Description("Adds the ability to select preferred video quality.")
|
||||
@DefaultVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
class DefaultVideoQualityPatch : BytecodePatch(
|
||||
listOf(
|
||||
VideoQualitySetterFingerprint,
|
||||
VideoIdFingerprint
|
||||
)
|
||||
|
||||
) {
|
||||
override fun execute(data: BytecodeData): PatchResult {
|
||||
val offset = 4
|
||||
val setterMethod = VideoQualitySetterFingerprint.result!!
|
||||
|
||||
VideoUserQualityChangeFingerprint.resolve(data, setterMethod.classDef)
|
||||
val userQualityMethod = VideoUserQualityChangeFingerprint.result!!
|
||||
|
||||
VideoQualityReferenceFingerprint.resolve(data, setterMethod.classDef)
|
||||
val qualityFieldReference =
|
||||
VideoQualityReferenceFingerprint.result!!.method.let { method ->
|
||||
(method.implementation!!.instructions.elementAt(0) as ReferenceInstruction).reference as FieldReference
|
||||
}
|
||||
|
||||
val qIndexMethodName =
|
||||
data.classes.single { it.type == qualityFieldReference.type }.methods.single { it.parameterTypes.first() == "I" }.name
|
||||
|
||||
setterMethod.mutableMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
iget-object v0, p0, ${setterMethod.classDef.type}->${qualityFieldReference.name}:${qualityFieldReference.type}
|
||||
const-string v1, "$qIndexMethodName"
|
||||
invoke-static {p1, p2, v0, v1}, Lapp/revanced/integrations/patches/VideoQualityPatch;->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I
|
||||
move-result p2
|
||||
""",
|
||||
)
|
||||
|
||||
val newVideoMethod = VideoIdFingerprint.result!!
|
||||
val newVideoIndex = newVideoMethod.patternScanResult!!.endIndex + offset
|
||||
newVideoMethod.mutableMethod.addInstructions(
|
||||
newVideoIndex, """
|
||||
const/4 v6, 0x1
|
||||
invoke-static {v6}, Lapp/revanced/integrations/utils/ReVancedUtils;->setNewVideo(Z)V
|
||||
"""
|
||||
)
|
||||
|
||||
userQualityMethod.mutableMethod.addInstruction(
|
||||
0,
|
||||
"invoke-static {p3}, Lapp/revanced/integrations/patches/VideoQualityPatch;->userChangedQuality(I)V"
|
||||
)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user