62 lines
2.7 KiB
Kotlin
62 lines
2.7 KiB
Kotlin
package app.revanced.patches.spotify.premium_navbar_tab.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.removeInstruction
|
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
|
import app.revanced.patcher.patch.PatchResult
|
|
import app.revanced.patcher.patch.PatchResultSuccess
|
|
import app.revanced.patcher.patch.annotations.DependsOn
|
|
import app.revanced.patcher.patch.annotations.Patch
|
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
|
import app.revanced.patches.spotify.premium_navbar_tab.annotations.PremiumNavbarTabCompatibility
|
|
import app.revanced.patches.spotify.premium_navbar_tab.fingerprints.AddPremiumNavbarTabFingerprint
|
|
import app.revanced.patches.spotify.premium_navbar_tab.fingerprints.AddPremiumNavbarTabParentFingerprint
|
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
|
import org.jf.dexlib2.Opcode
|
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
|
|
|
@Patch
|
|
@Name("hide-premium-navbar")
|
|
@Description("Removes the premium tab from the navbar.")
|
|
@PremiumNavbarTabCompatibility
|
|
@Version("0.0.1")
|
|
@DependsOn([ResourceMappingResourcePatch::class])
|
|
class PremiumNavbarTabPatch : BytecodePatch(
|
|
listOf(
|
|
AddPremiumNavbarTabParentFingerprint
|
|
)
|
|
) {
|
|
override fun execute(data: BytecodeData): PatchResult {
|
|
val parentResult = AddPremiumNavbarTabParentFingerprint.result!!
|
|
AddPremiumNavbarTabFingerprint.resolve(data, parentResult.classDef)
|
|
|
|
val result = AddPremiumNavbarTabFingerprint.result!!
|
|
|
|
val method = result.mutableMethod
|
|
val methodInstructions = method.implementation!!.instructions
|
|
val lastInstructionIdx = methodInstructions.size - 1
|
|
|
|
val premiumTabId = ResourceMappingResourcePatch.resourceMappings.single{it.type == "id" && it.name == "premium_tab"}.id
|
|
|
|
var removeAmount = 2
|
|
// 2nd const remove method
|
|
for ((i, instruction) in methodInstructions.asReversed().withIndex()) {
|
|
if (instruction.opcode.ordinal != Opcode.CONST.ordinal) continue
|
|
if ((instruction as WideLiteralInstruction).wideLiteral != premiumTabId) continue
|
|
|
|
val findThreshold = 10
|
|
val constIndex = lastInstructionIdx - i
|
|
val invokeInstruction = methodInstructions.subList(constIndex, constIndex + findThreshold).first {
|
|
it.opcode.ordinal == Opcode.INVOKE_VIRTUAL_RANGE.ordinal
|
|
}
|
|
method.removeInstruction(methodInstructions.indexOf(invokeInstruction))
|
|
|
|
if (--removeAmount == 0) break
|
|
}
|
|
|
|
return PatchResultSuccess()
|
|
}
|
|
} |