diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt new file mode 100644 index 000000000..741e23b86 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.spotify.lite.ondemand.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package("com.spotify.lite")] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class OnDemandCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt new file mode 100644 index 000000000..099eaa438 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt @@ -0,0 +1,25 @@ +package app.revanced.patches.spotify.lite.ondemand.fingerprints + +import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +@FuzzyPatternScanMethod(2) +object OnDemandFingerprint : MethodFingerprint( + "L", + parameters = listOf(), + opcodes = listOf( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IF_EQZ, + Opcode.SGET_OBJECT, + Opcode.GOTO, + Opcode.SGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IPUT, + Opcode.RETURN_OBJECT + ) +) diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt new file mode 100644 index 000000000..bbb5159ef --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt @@ -0,0 +1,34 @@ +package app.revanced.patches.spotify.lite.ondemand.patch + +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.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.spotify.lite.ondemand.annotations.OnDemandCompatibility +import app.revanced.patches.spotify.lite.ondemand.fingerprints.OnDemandFingerprint + +@Patch +@Name("enable-on-demand") +@Description("Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.") +@OnDemandCompatibility +@Version("0.0.1") +class OnDemandPatch : BytecodePatch( + listOf( + OnDemandFingerprint + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + OnDemandFingerprint.result?.apply { + val insertIndex = scanResult.patternScanResult!!.endIndex - 1 + // Spoof a premium account + mutableMethod.addInstruction(insertIndex, "const/4 v0, 0x2") + } ?: return OnDemandFingerprint.toErrorResult() + return PatchResultSuccess() + } +}