mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-08 02:24:35 +02:00
add suport YouTube v18.06.35
This commit is contained in:
parent
9030abe616
commit
8427f28208
@ -3,7 +3,7 @@ package app.revanced.patches.shared.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.05.40"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.06.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class YouTubeCompatibility
|
||||
|
@ -1,13 +1,10 @@
|
||||
package app.revanced.patches.shared.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object MainstreamVideoAdsFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
parameters = listOf("L","Z"),
|
||||
opcodes = listOf(
|
||||
Opcode.IGET_OBJECT,
|
||||
|
@ -10,7 +10,6 @@ import org.jf.dexlib2.Opcode
|
||||
object PivotBarCreateButtonViewFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Z"),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
|
@ -8,6 +8,7 @@ import app.revanced.patcher.data.toMethodWalker
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
@ -26,34 +27,30 @@ class GeneralVideoAdsPatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val LegacyVideoAdsResult = LegacyVideoAdsFingerprint.result ?: return LegacyVideoAdsFingerprint.toErrorResult()
|
||||
val legacyVideoAdsResult = LegacyVideoAdsFingerprint.result ?: return LegacyVideoAdsFingerprint.toErrorResult()
|
||||
|
||||
LegacyVideoAdsMethod =
|
||||
context.toMethodWalker(LegacyVideoAdsResult.method)
|
||||
legacyVideoAdsMethod =
|
||||
context.toMethodWalker(legacyVideoAdsResult.method)
|
||||
.nextMethod(13, true)
|
||||
.getMethod() as MutableMethod
|
||||
|
||||
MainstreamVideoAdsFingerprint.resolve(context, MainstreamVideoAdsParentFingerprint.result!!.classDef)
|
||||
|
||||
val MainstreamAdsResult = MainstreamVideoAdsFingerprint.result ?: return MainstreamVideoAdsFingerprint.toErrorResult()
|
||||
|
||||
MainstreamVideoAdsMethod = MainstreamAdsResult.mutableMethod
|
||||
|
||||
InsertIndex = MainstreamAdsResult.scanResult.patternScanResult!!.endIndex
|
||||
MainstreamVideoAdsParentFingerprint.result?.let { parentResult ->
|
||||
MainstreamVideoAdsFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
|
||||
mainstreamVideoAdsResult = it
|
||||
} ?: return MainstreamVideoAdsFingerprint.toErrorResult()
|
||||
} ?: return MainstreamVideoAdsParentFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
var InsertIndex: Int = 0
|
||||
|
||||
lateinit var LegacyVideoAdsMethod: MutableMethod
|
||||
lateinit var MainstreamVideoAdsMethod: MutableMethod
|
||||
lateinit var legacyVideoAdsMethod: MutableMethod
|
||||
lateinit var mainstreamVideoAdsResult: MethodFingerprintResult
|
||||
|
||||
fun injectLegacyAds(
|
||||
descriptor: String
|
||||
) {
|
||||
LegacyVideoAdsMethod.addInstructions(
|
||||
legacyVideoAdsMethod.addInstructions(
|
||||
0, """
|
||||
invoke-static {}, $descriptor
|
||||
move-result v1
|
||||
@ -64,13 +61,16 @@ class GeneralVideoAdsPatch : BytecodePatch(
|
||||
fun injectMainstreamAds(
|
||||
descriptor: String
|
||||
) {
|
||||
MainstreamVideoAdsMethod.addInstructions(
|
||||
InsertIndex, """
|
||||
val mainstreamVideoAdsMethod = mainstreamVideoAdsResult.mutableMethod
|
||||
val insertIndex = mainstreamVideoAdsResult.scanResult.patternScanResult!!.endIndex
|
||||
|
||||
mainstreamVideoAdsMethod.addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {}, $descriptor
|
||||
move-result v1
|
||||
if-nez v1, :show_video_ads
|
||||
return-void
|
||||
""", listOf(ExternalLabel("show_video_ads", MainstreamVideoAdsMethod.instruction(InsertIndex)))
|
||||
""", listOf(ExternalLabel("show_video_ads", mainstreamVideoAdsMethod.instruction(insertIndex)))
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,9 @@ import app.revanced.patches.youtube.layout.fullscreen.fullscreenpanels.fingerpri
|
||||
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch
|
||||
import app.revanced.util.integrations.Constants.FULLSCREEN_LAYOUT
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction21c
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||
|
||||
@Patch
|
||||
@ -57,6 +59,29 @@ class HideFullscreenPanelsPatch : BytecodePatch(
|
||||
}
|
||||
} ?: return FullscreenViewAdderFingerprint.toErrorResult()
|
||||
|
||||
LayoutConstructorFingerprint.result?.mutableMethod?.let { method ->
|
||||
val instructions = method.implementation!!.instructions
|
||||
val registerIndex = instructions.indexOfFirst {
|
||||
it.opcode == Opcode.CONST_STRING &&
|
||||
(it as BuilderInstruction21c).reference.toString() == "1.0x"
|
||||
}
|
||||
val dummyRegister = (instructions[registerIndex] as Instruction21c).registerA
|
||||
|
||||
val invokeIndex = method.implementation!!.instructions.indexOfFirst {
|
||||
it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal &&
|
||||
((it as? BuilderInstruction35c)?.reference.toString() ==
|
||||
"Landroid/widget/FrameLayout;->addView(Landroid/view/View;)V")
|
||||
}
|
||||
|
||||
method.addInstructions(
|
||||
invokeIndex, """
|
||||
invoke-static {}, $FULLSCREEN_LAYOUT->hideFullscreenPanel()Z
|
||||
move-result v$dummyRegister
|
||||
if-nez v$dummyRegister, :hidden
|
||||
""", listOf(ExternalLabel("hidden", method.instruction(invokeIndex + 1)))
|
||||
)
|
||||
} ?: return LayoutConstructorFingerprint.toErrorResult()
|
||||
|
||||
/*
|
||||
* Add settings
|
||||
*/
|
||||
@ -70,22 +95,6 @@ class HideFullscreenPanelsPatch : BytecodePatch(
|
||||
|
||||
SettingsPatch.updatePatchStatus("hide-fullscreen-panels")
|
||||
|
||||
LayoutConstructorFingerprint.result?.mutableMethod?.let { method ->
|
||||
val invokeIndex = method.implementation!!.instructions.indexOfFirst {
|
||||
it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal &&
|
||||
((it as? BuilderInstruction35c)?.reference.toString() ==
|
||||
"Landroid/widget/FrameLayout;->addView(Landroid/view/View;)V")
|
||||
}
|
||||
|
||||
method.addInstructions(
|
||||
invokeIndex, """
|
||||
invoke-static {}, $FULLSCREEN_LAYOUT->hideFullscreenPanel()Z
|
||||
move-result v15
|
||||
if-nez v15, :hidden
|
||||
""", listOf(ExternalLabel("hidden", method.instruction(invokeIndex + 1)))
|
||||
)
|
||||
} ?: return LayoutConstructorFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package app.revanced.patches.youtube.layout.general.crowdfundingbox.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
|
||||
object CrowdfundingBoxFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IPUT_OBJECT
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.donationCompanionResourceId
|
||||
} == true
|
||||
}
|
||||
)
|
@ -1,90 +1,66 @@
|
||||
package app.revanced.patches.youtube.layout.general.crowdfundingbox.patch
|
||||
|
||||
import app.revanced.extensions.findMutableMethodOf
|
||||
import app.revanced.extensions.injectHideCall
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.patches.shared.patch.mapping.ResourceMappingPatch
|
||||
import app.revanced.patches.youtube.layout.general.crowdfundingbox.fingerprints.CrowdfundingBoxFingerprint
|
||||
import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch
|
||||
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
|
||||
import app.revanced.util.integrations.Constants.GENERAL_LAYOUT
|
||||
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
|
||||
@Patch
|
||||
@Name("hide-crowdfunding-box")
|
||||
@Description("Hides the crowdfunding box between the player and video description.")
|
||||
@DependsOn(
|
||||
[
|
||||
ResourceMappingPatch::class,
|
||||
SettingsPatch::class
|
||||
SettingsPatch::class,
|
||||
SharedResourcdIdPatch::class
|
||||
]
|
||||
)
|
||||
@YouTubeCompatibility
|
||||
@Version("0.0.1")
|
||||
class CrowdfundingBoxPatch : BytecodePatch() {
|
||||
|
||||
// list of resource names to get the id of
|
||||
private val resourceIds = arrayOf(
|
||||
"donation_companion"
|
||||
).map { name ->
|
||||
ResourceMappingPatch.resourceMappings.single { it.name == name }.id
|
||||
}
|
||||
private var patchSuccessArray = Array(resourceIds.size) {false}
|
||||
|
||||
class CrowdfundingBoxPatch : BytecodePatch(
|
||||
listOf(
|
||||
CrowdfundingBoxFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
context.classes.forEach { classDef ->
|
||||
classDef.methods.forEach { method ->
|
||||
with(method.implementation) {
|
||||
this?.instructions?.forEachIndexed { index, instruction ->
|
||||
when (instruction.opcode) {
|
||||
Opcode.CONST -> {
|
||||
when ((instruction as Instruction31i).wideLiteral) {
|
||||
resourceIds[0] -> { // crowdfunding
|
||||
val insertIndex = index + 3
|
||||
val iPutInstruction = instructions.elementAt(insertIndex)
|
||||
if (iPutInstruction.opcode != Opcode.IPUT_OBJECT) return@forEachIndexed
|
||||
|
||||
val mutableMethod = context.proxy(classDef).mutableClass.findMutableMethodOf(method)
|
||||
CrowdfundingBoxFingerprint.result?.let {
|
||||
with (it.mutableMethod) {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val register = (instruction(insertIndex) as TwoRegisterInstruction).registerA
|
||||
|
||||
val viewRegister = (iPutInstruction as Instruction22c).registerA
|
||||
mutableMethod.implementation!!.injectHideCall(insertIndex, viewRegister, "layout/GeneralLayoutPatch", "hideCrowdfundingBox")
|
||||
patchSuccessArray[0] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> return@forEachIndexed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val errorIndex: Int = patchSuccessArray.indexOf(false)
|
||||
|
||||
if (errorIndex == -1) {
|
||||
/*
|
||||
* Add settings
|
||||
*/
|
||||
SettingsPatch.addPreference(
|
||||
arrayOf(
|
||||
"PREFERENCE: GENERAL_LAYOUT_SETTINGS",
|
||||
"SETTINGS: HIDE_CROWDFUNDING_BOX"
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static {v$register}, $GENERAL_LAYOUT->hideCrowdfundingBox(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
} ?: return CrowdfundingBoxFingerprint.toErrorResult()
|
||||
|
||||
/*
|
||||
* Add settings
|
||||
*/
|
||||
SettingsPatch.addPreference(
|
||||
arrayOf(
|
||||
"PREFERENCE: GENERAL_LAYOUT_SETTINGS",
|
||||
"SETTINGS: HIDE_CROWDFUNDING_BOX"
|
||||
)
|
||||
)
|
||||
|
||||
SettingsPatch.updatePatchStatus("hide-crowdfunding-box")
|
||||
SettingsPatch.updatePatchStatus("hide-crowdfunding-box")
|
||||
|
||||
return PatchResultSuccess()
|
||||
} else
|
||||
return PatchResultError("Instruction not found: $errorIndex")
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
|
||||
object MiniPlayerDimensionsCalculatorFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any {
|
||||
it.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
|
@ -9,5 +9,5 @@ object MiniPlayerOverrideFingerprint : MethodFingerprint(
|
||||
returnType = "Z",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(Opcode.RETURN), // anchor to insert the instruction
|
||||
opcodes = listOf(Opcode.INVOKE_STATIC), // anchor to insert the instruction
|
||||
)
|
@ -0,0 +1,12 @@
|
||||
package app.revanced.patches.youtube.layout.general.tabletminiplayer.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object MiniPlayerOverrideParentFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
parameters = listOf("L"),
|
||||
strings = listOf("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT")
|
||||
)
|
@ -5,6 +5,7 @@ import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.data.toMethodWalker
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||
@ -19,6 +20,7 @@ import app.revanced.patches.youtube.layout.general.tabletminiplayer.fingerprints
|
||||
import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch
|
||||
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch
|
||||
import app.revanced.util.integrations.Constants.GENERAL_LAYOUT
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@Patch
|
||||
@ -35,31 +37,33 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
class TabletMiniPlayerPatch : BytecodePatch(
|
||||
listOf(
|
||||
MiniPlayerDimensionsCalculatorFingerprint,
|
||||
MiniPlayerResponseModelSizeCheckFingerprint
|
||||
MiniPlayerResponseModelSizeCheckFingerprint,
|
||||
MiniPlayerOverrideParentFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
|
||||
MiniPlayerDimensionsCalculatorFingerprint.result?.let { parentResult ->
|
||||
// first resolve the fingerprints via the parent fingerprint
|
||||
val miniPlayerClass = parentResult.classDef
|
||||
|
||||
arrayOf(
|
||||
MiniPlayerOverrideNoContextFingerprint,
|
||||
MiniPlayerOverrideFingerprint,
|
||||
MiniPlayerResponseModelSizeCheckFingerprint
|
||||
).map {
|
||||
it to (it.also { it.resolve(context, miniPlayerClass) }.result ?: return it.toErrorResult())
|
||||
}.forEach { (fingerprint, result) ->
|
||||
if (fingerprint == MiniPlayerOverrideNoContextFingerprint) {
|
||||
val (method, _, parameterRegister) = result.addProxyCall()
|
||||
method.insertOverride(method.implementation!!.instructions.size - 1, parameterRegister)
|
||||
} else {
|
||||
val (_, _, _) = result.addProxyCall()
|
||||
}
|
||||
}
|
||||
MiniPlayerOverrideNoContextFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { result ->
|
||||
val (method, _, parameterRegister) = result.addProxyCall()
|
||||
method.insertOverride(method.implementation!!.instructions.size - 1, parameterRegister)
|
||||
} ?: return MiniPlayerOverrideNoContextFingerprint.toErrorResult()
|
||||
} ?: return MiniPlayerDimensionsCalculatorFingerprint.toErrorResult()
|
||||
|
||||
MiniPlayerOverrideParentFingerprint.result?.let { parentResult ->
|
||||
MiniPlayerOverrideFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { result ->
|
||||
(context.toMethodWalker(result.method)
|
||||
.nextMethod(result.scanResult.patternScanResult!!.startIndex, true)
|
||||
.getMethod() as MutableMethod)
|
||||
.instructionProxyCall()
|
||||
} ?: return MiniPlayerOverrideFingerprint.toErrorResult()
|
||||
|
||||
} ?: return MiniPlayerOverrideParentFingerprint.toErrorResult()
|
||||
|
||||
MiniPlayerResponseModelSizeCheckFingerprint.result?.let {
|
||||
val (_, _, _) = it.addProxyCall()
|
||||
} ?: return MiniPlayerResponseModelSizeCheckFingerprint.toErrorResult()
|
||||
|
||||
/*
|
||||
* Add settings
|
||||
*/
|
||||
@ -94,6 +98,17 @@ class TabletMiniPlayerPatch : BytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
fun MutableMethod.instructionProxyCall() {
|
||||
val insertInstructions = this.implementation!!.instructions
|
||||
for ((index, instruction) in insertInstructions.withIndex()) {
|
||||
if (instruction.opcode != Opcode.RETURN) continue
|
||||
val parameterRegister = (instruction as OneRegisterInstruction).registerA
|
||||
this.insertOverride(index, parameterRegister)
|
||||
this.insertOverride(insertInstructions.size - 1, parameterRegister)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fun MethodFingerprintResult.unwrap(): Triple<MutableMethod, Int, Int> {
|
||||
val scanIndex = this.scanResult.patternScanResult!!.endIndex
|
||||
val method = this.mutableMethod
|
||||
|
@ -17,9 +17,12 @@ import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
|
||||
import app.revanced.patches.shared.patch.mapping.ResourceMappingPatch
|
||||
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch
|
||||
import app.revanced.util.integrations.Constants.PLAYER_LAYOUT
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction21c
|
||||
import org.jf.dexlib2.iface.instruction.Instruction
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
|
||||
import org.jf.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch
|
||||
@ -46,6 +49,12 @@ class HideAutoplayButtonPatch : BytecodePatch(
|
||||
|
||||
LayoutConstructorFingerprint.result?.mutableMethod?.let { method ->
|
||||
with (method.implementation!!.instructions) {
|
||||
val registerIndex = indexOfFirst {
|
||||
it.opcode == Opcode.CONST_STRING &&
|
||||
(it as BuilderInstruction21c).reference.toString() == "1.0x"
|
||||
}
|
||||
val dummyRegister = (this[registerIndex] as Instruction21c).registerA
|
||||
|
||||
// where to insert the branch instructions and ...
|
||||
val insertIndex = this.indexOfFirst {
|
||||
(it as? WideLiteralInstruction)?.wideLiteral == autoNavPreviewStubId
|
||||
@ -60,8 +69,8 @@ class HideAutoplayButtonPatch : BytecodePatch(
|
||||
method.addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {}, $PLAYER_LAYOUT->hideAutoPlayButton()Z
|
||||
move-result v15
|
||||
if-nez v15, :hidden
|
||||
move-result v$dummyRegister
|
||||
if-nez v$dummyRegister, :hidden
|
||||
""", listOf(ExternalLabel("hidden", jumpInstruction))
|
||||
)
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class SharedResourcdIdPatch : ResourcePatch {
|
||||
var bottompaneloverlaytextLabelId: Long = -1
|
||||
var bottomUiContainerResourceId: Long = -1
|
||||
var controlsLayoutStubResourceId: Long = -1
|
||||
var donationCompanionResourceId: Long = -1
|
||||
var educationTextViewResourceId: Long = -1
|
||||
var emptycolorLabelId: Long = -1
|
||||
var floatybarQueueLabelId: Long = -1
|
||||
@ -53,6 +54,7 @@ class SharedResourcdIdPatch : ResourcePatch {
|
||||
bottompaneloverlaytextLabelId = findSharedResourceId("id", "bottom_panel_overlay_text")
|
||||
bottomUiContainerResourceId = findSharedResourceId("id", "bottom_ui_container_stub")
|
||||
controlsLayoutStubResourceId = findSharedResourceId("id", "controls_layout_stub")
|
||||
donationCompanionResourceId = findSharedResourceId("layout", "donation_companion")
|
||||
educationTextViewResourceId = findSharedResourceId("id", "user_education_text_view")
|
||||
emptycolorLabelId = findSharedResourceId("color", "inline_time_bar_colorized_bar_empty_color_dark")
|
||||
floatybarQueueLabelId = findSharedResourceId("string", "floaty_bar_queue_status")
|
||||
|
@ -1,11 +1,8 @@
|
||||
package app.revanced.patches.youtube.misc.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object DislikeFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf("like/dislike")
|
||||
)
|
@ -1,11 +1,8 @@
|
||||
package app.revanced.patches.youtube.misc.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object LikeFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf("like/like")
|
||||
)
|
@ -1,11 +1,8 @@
|
||||
package app.revanced.patches.youtube.misc.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object RemoveLikeFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf("like/removelike")
|
||||
)
|
@ -10,6 +10,13 @@ object ShortsTextComponentParentFingerprint : MethodFingerprint(
|
||||
access = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
parameters = listOf("L", "L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.GOTO,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.RETURN_VOID,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.IGET_BOOLEAN,
|
||||
|
@ -1,17 +1,17 @@
|
||||
package app.revanced.patches.youtube.misc.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object TextComponentSpecFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
access = AccessFlags.STATIC.getValue(),
|
||||
opcodes = listOf(Opcode.CMPL_FLOAT),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation!!.instructions.any {
|
||||
((it as? NarrowLiteralInstruction)?.narrowLiteral == 16842907)
|
||||
}
|
||||
}
|
||||
returnType = "V",
|
||||
access = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC_RANGE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_DIRECT
|
||||
)
|
||||
)
|
@ -0,0 +1,11 @@
|
||||
package app.revanced.patches.youtube.misc.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object TextComponentSpecParentFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PRIVATE or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf("TextComponent")
|
||||
)
|
@ -7,10 +7,11 @@ import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.data.toMethodWalker
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
@ -20,7 +21,13 @@ import app.revanced.patches.youtube.misc.returnyoutubedislike.fingerprints.*
|
||||
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.videoid.mainstream.patch.MainstreamVideoIdPatch
|
||||
import app.revanced.util.integrations.Constants.UTILS_PATH
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction3rc
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import org.jf.dexlib2.iface.reference.FieldReference
|
||||
import org.jf.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch
|
||||
@Name("return-youtube-dislike")
|
||||
@ -39,7 +46,7 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
LikeFingerprint,
|
||||
RemoveLikeFingerprint,
|
||||
ShortsTextComponentParentFingerprint,
|
||||
TextComponentSpecFingerprint
|
||||
TextComponentSpecParentFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
@ -60,7 +67,7 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
}
|
||||
|
||||
ShortsTextComponentParentFingerprint.result?.let {
|
||||
with(context
|
||||
with (context
|
||||
.toMethodWalker(it.method)
|
||||
.nextMethod(it.scanResult.patternScanResult!!.endIndex, true)
|
||||
.getMethod() as MutableMethod
|
||||
@ -69,30 +76,57 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
val insertIndex = insertInstructions.size - 1
|
||||
val insertRegister = (insertInstructions.elementAt(insertIndex) as OneRegisterInstruction).registerA
|
||||
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {v$insertRegister}, ${INTEGRATIONS_RYD_CLASS_DESCRIPTOR}->onShortsComponentCreated(Landroid/text/Spanned;)Landroid/text/Spanned;
|
||||
move-result-object v$insertRegister
|
||||
"""
|
||||
)
|
||||
this.insertShorts(insertIndex, insertRegister)
|
||||
}
|
||||
|
||||
with (it.mutableMethod) {
|
||||
val insertInstructions = this.implementation!!.instructions
|
||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2
|
||||
val insertRegister = (insertInstructions.elementAt(insertIndex - 1) as OneRegisterInstruction).registerA
|
||||
|
||||
this.insertShorts(insertIndex, insertRegister)
|
||||
}
|
||||
} ?: return ShortsTextComponentParentFingerprint.toErrorResult()
|
||||
|
||||
val createComponentResult = TextComponentSpecFingerprint.result ?: return PatchResultError("Failed to find TextComponentSpecFingerprint method.")
|
||||
val createComponentMethod = createComponentResult.mutableMethod
|
||||
TextComponentSpecParentFingerprint.result?.let { parentResult ->
|
||||
TextComponentSpecFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
|
||||
with (it.mutableMethod) {
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
|
||||
val conversionContextParam = 5
|
||||
val textRefParam = createComponentMethod.parameters.size - 2
|
||||
val dummyRegister = (instruction(startIndex) as BuilderInstruction3rc).registerCount +
|
||||
(instruction(startIndex) as BuilderInstruction3rc).startRegister - 1
|
||||
val targetRegister = (instruction(endIndex) as Instruction35c).registerC
|
||||
|
||||
createComponentMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
move-object/from16 v7, p$conversionContextParam
|
||||
move-object/from16 v8, p$textRefParam
|
||||
invoke-static {v7, v8}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V
|
||||
"""
|
||||
)
|
||||
val instructions = implementation!!.instructions
|
||||
val targetString =
|
||||
((instructions.elementAt(startIndex) as ReferenceInstruction).reference as MethodReference).parameterTypes.first().toString()
|
||||
|
||||
for ((index, instruction) in instructions.withIndex()) {
|
||||
if (instruction.opcode != Opcode.IGET_OBJECT) continue
|
||||
|
||||
val indexReference = (instruction as ReferenceInstruction).reference as FieldReference
|
||||
|
||||
if (indexReference.type != targetString) continue
|
||||
targetReference = indexReference
|
||||
targetIndex = index
|
||||
break
|
||||
}
|
||||
|
||||
if (targetIndex == 0) return TextComponentSpecFingerprint.toErrorResult()
|
||||
|
||||
val conversionContextParam = 0
|
||||
|
||||
addInstructions(
|
||||
endIndex + 1, """
|
||||
move-object/from16 v$dummyRegister, p$conversionContextParam
|
||||
iget-object v$dummyRegister, v$dummyRegister, ${definingClass}->${targetReference.name}:${targetReference.type}
|
||||
invoke-static {v$dummyRegister, v$targetRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: return TextComponentSpecFingerprint.toErrorResult()
|
||||
} ?: return TextComponentSpecParentFingerprint.toErrorResult()
|
||||
|
||||
MainstreamVideoIdPatch.injectCall("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V")
|
||||
|
||||
@ -108,6 +142,9 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
private companion object {
|
||||
const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR =
|
||||
"$UTILS_PATH/ReturnYouTubeDislikePatch;"
|
||||
|
||||
var targetIndex: Int = 0
|
||||
private lateinit var targetReference: FieldReference
|
||||
}
|
||||
|
||||
private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind)
|
||||
@ -119,4 +156,13 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
DISLIKE(-1),
|
||||
REMOVE_LIKE(0)
|
||||
}
|
||||
|
||||
private fun MutableMethod.insertShorts(index: Int, register: Int) {
|
||||
addInstructions(
|
||||
index, """
|
||||
invoke-static {v$register}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onShortsComponentCreated(Landroid/text/Spanned;)Landroid/text/Spanned;
|
||||
move-result-object v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,10 @@ package app.revanced.patches.youtube.video.quality.bytecode.fingerprints
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object VideoQualitySetterFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("[L", "I", "I", "Z", "I"),
|
||||
opcodes = listOf(
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
)
|
||||
parameters = listOf("L"),
|
||||
strings = listOf("VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT")
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.youtube.video.quality.bytecode.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object VideoQualitySettingsFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.IGET_OBJECT
|
||||
)
|
||||
)
|
@ -0,0 +1,12 @@
|
||||
package app.revanced.patches.youtube.video.quality.bytecode.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object VideoQualitySettingsParentFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("[L", "I", "Z"),
|
||||
strings = listOf("menu_item_video_quality")
|
||||
)
|
@ -3,16 +3,9 @@ package app.revanced.patches.youtube.video.quality.bytecode.fingerprints
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object VideoUserQualityChangeFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("L","L","I","J"),
|
||||
opcodes = listOf(
|
||||
Opcode.MOVE,
|
||||
Opcode.MOVE_WIDE,
|
||||
Opcode.INVOKE_INTERFACE_RANGE,
|
||||
Opcode.RETURN_VOID
|
||||
)
|
||||
customFingerprint = { it.name == "onItemClick" }
|
||||
)
|
@ -13,9 +13,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.shared.annotation.YouTubeCompatibility
|
||||
import app.revanced.patches.youtube.misc.videoid.legacy.patch.LegacyVideoIdPatch
|
||||
import app.revanced.patches.youtube.video.quality.bytecode.fingerprints.VideoQualityReferenceFingerprint
|
||||
import app.revanced.patches.youtube.video.quality.bytecode.fingerprints.VideoQualitySetterFingerprint
|
||||
import app.revanced.patches.youtube.video.quality.bytecode.fingerprints.VideoUserQualityChangeFingerprint
|
||||
import app.revanced.patches.youtube.video.quality.bytecode.fingerprints.*
|
||||
import app.revanced.util.integrations.Constants.VIDEO_PATH
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.reference.FieldReference
|
||||
@ -26,36 +24,44 @@ import org.jf.dexlib2.iface.reference.FieldReference
|
||||
@Version("0.0.1")
|
||||
class VideoQualityBytecodePatch : BytecodePatch(
|
||||
listOf(
|
||||
VideoQualitySetterFingerprint
|
||||
VideoQualitySetterFingerprint,
|
||||
VideoQualitySettingsParentFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
VideoQualitySetterFingerprint.result?.let { parentResult ->
|
||||
VideoQualityReferenceFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { result ->
|
||||
val instructions = result.method.implementation!!.instructions
|
||||
val qualityFieldReference =
|
||||
|
||||
qualityFieldReference =
|
||||
(instructions.elementAt(0) as ReferenceInstruction).reference as FieldReference
|
||||
|
||||
val qIndexMethodName =
|
||||
qIndexMethodName =
|
||||
context.classes.single { it.type == qualityFieldReference.type }.methods.single { it.parameterTypes.first() == "I" }.name
|
||||
|
||||
parentResult.mutableMethod.addInstructions(
|
||||
0, """
|
||||
iget-object v0, p0, ${result.classDef.type}->${qualityFieldReference.name}:${qualityFieldReference.type}
|
||||
const-string v1, "$qIndexMethodName"
|
||||
invoke-static {p1, p2, v0, v1}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I
|
||||
move-result p2
|
||||
""",
|
||||
)
|
||||
} ?: return VideoQualityReferenceFingerprint.toErrorResult()
|
||||
|
||||
VideoUserQualityChangeFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.addInstruction(
|
||||
0,
|
||||
"invoke-static {p3}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userChangedQuality(I)V"
|
||||
0,
|
||||
"invoke-static {p3}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userChangedQuality(I)V"
|
||||
) ?: return VideoUserQualityChangeFingerprint.toErrorResult()
|
||||
|
||||
} ?: return VideoQualitySetterFingerprint.toErrorResult()
|
||||
|
||||
VideoQualitySettingsParentFingerprint.result?.let { parentResult ->
|
||||
VideoQualitySettingsFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.let {
|
||||
relayFieldReference = (it.implementation!!.instructions.elementAt(0) as ReferenceInstruction).reference as FieldReference
|
||||
} ?: return VideoQualitySettingsFingerprint.toErrorResult()
|
||||
|
||||
parentResult.mutableMethod.addInstructions(
|
||||
0, """
|
||||
iget-object v0, p0, ${parentResult.classDef.type}->${relayFieldReference.name}:${relayFieldReference.type}
|
||||
iget-object v1, v0, ${relayFieldReference.type}->${qualityFieldReference.name}:${qualityFieldReference.type}
|
||||
const-string v2, "$qIndexMethodName"
|
||||
invoke-static {p1, p2, v1, v2}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I
|
||||
move-result p2
|
||||
"""
|
||||
)
|
||||
} ?: return VideoQualitySettingsParentFingerprint.toErrorResult()
|
||||
|
||||
LegacyVideoIdPatch.injectCall("$INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V")
|
||||
|
||||
return PatchResultSuccess()
|
||||
@ -63,5 +69,11 @@ class VideoQualityBytecodePatch : BytecodePatch(
|
||||
private companion object {
|
||||
const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR =
|
||||
"$VIDEO_PATH/VideoQualityPatch;"
|
||||
|
||||
private lateinit var qIndexMethodName: String
|
||||
|
||||
private lateinit var relayFieldReference: FieldReference
|
||||
private lateinit var qualityFieldReference: FieldReference
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user