mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 05:07:41 +02:00
add suport YouTube v18.06.35
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user