mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-04-30 06:34:28 +02:00
fix(Spotify - Unlock Premium): Override additional attributes (#4651)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
This commit is contained in:
parent
5f4c42bfa9
commit
568b40da96
@ -1,3 +1,16 @@
|
|||||||
dependencies {
|
dependencies {
|
||||||
|
compileOnly(project(":extensions:shared:library"))
|
||||||
compileOnly(project(":extensions:spotify:stub"))
|
compileOnly(project(":extensions:spotify:stub"))
|
||||||
|
compileOnly(libs.annotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = 24
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,38 +2,57 @@ package app.revanced.extension.spotify.misc;
|
|||||||
|
|
||||||
import com.spotify.remoteconfig.internal.AccountAttribute;
|
import com.spotify.remoteconfig.internal.AccountAttribute;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @noinspection unused
|
* @noinspection unused
|
||||||
*/
|
*/
|
||||||
public final class UnlockPremiumPatch {
|
public final class UnlockPremiumPatch {
|
||||||
private static final Map<String, Object> OVERRIDES = Map.of(
|
|
||||||
// Disables player and app ads.
|
|
||||||
"ads", false,
|
|
||||||
// Works along on-demand, allows playing any song without restriction.
|
|
||||||
"player-license", "premium",
|
|
||||||
// Disables shuffle being initially enabled when first playing a playlist.
|
|
||||||
"shuffle", false,
|
|
||||||
// Allows playing any song on-demand, without a shuffled order.
|
|
||||||
"on-demand", true,
|
|
||||||
// Make sure playing songs is not disabled remotely and playlists show up.
|
|
||||||
"streaming", true,
|
|
||||||
// Allows adding songs to queue and removes the smart shuffle mode restriction,
|
|
||||||
// allowing to pick any of the other modes.
|
|
||||||
"pick-and-shuffle", false,
|
|
||||||
// Disables shuffle-mode streaming-rule, which forces songs to be played shuffled
|
|
||||||
// and breaks the player when other patches are applied.
|
|
||||||
"streaming-rules", "",
|
|
||||||
// Enables premium UI in settings and removes the premium button in the nav-bar.
|
|
||||||
"nft-disabled", "1"
|
|
||||||
);
|
|
||||||
|
|
||||||
|
private static final Map<String, Object> OVERRIDES = new HashMap<>() {{
|
||||||
|
// Disables player and app ads.
|
||||||
|
put("ads", false);
|
||||||
|
// Works along on-demand, allows playing any song without restriction.
|
||||||
|
put("player-license", "premium");
|
||||||
|
// Disables shuffle being initially enabled when first playing a playlist.
|
||||||
|
put("shuffle", false);
|
||||||
|
// Allows playing any song on-demand, without a shuffled order.
|
||||||
|
put("on-demand", true);
|
||||||
|
// Make sure playing songs is not disabled remotely and playlists show up.
|
||||||
|
put("streaming", true);
|
||||||
|
// Allows adding songs to queue and removes the smart shuffle mode restriction,
|
||||||
|
// allowing to pick any of the other modes.
|
||||||
|
put("pick-and-shuffle", false);
|
||||||
|
// Disables shuffle-mode streaming-rule, which forces songs to be played shuffled
|
||||||
|
// and breaks the player when other patches are applied.
|
||||||
|
put("streaming-rules", "");
|
||||||
|
// Enables premium UI in settings and removes the premium button in the nav-bar.
|
||||||
|
put("nft-disabled", "1");
|
||||||
|
// Enable Cross-Platform Spotify Car Thing.
|
||||||
|
put("can_use_superbird", true);
|
||||||
|
// Removes the premium button in the nav-bar for tablet users.
|
||||||
|
put("tablet-free", false);
|
||||||
|
}};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
public static void overrideAttribute(Map<String, AccountAttribute> attributes) {
|
public static void overrideAttribute(Map<String, AccountAttribute> attributes) {
|
||||||
for (var entry : OVERRIDES.entrySet()) {
|
try {
|
||||||
var attribute = Objects.requireNonNull(attributes.get(entry.getKey()));
|
for (var entry : OVERRIDES.entrySet()) {
|
||||||
attribute.value_ = entry.getValue();
|
var key = entry.getKey();
|
||||||
|
var attribute = attributes.get(key);
|
||||||
|
if (attribute == null) {
|
||||||
|
Logger.printException(() -> "Account attribute not found: " + key);
|
||||||
|
} else {
|
||||||
|
attribute.value_ = entry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "overrideAttribute failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -820,6 +820,10 @@ public final class app/revanced/patches/spotify/misc/UnlockPremiumPatchKt {
|
|||||||
public static final fun getUnlockPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getUnlockPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/spotify/misc/extension/ExtensionPatchKt {
|
||||||
|
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
||||||
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import org.w3c.dom.Element
|
|||||||
val customThemePatch = resourcePatch(
|
val customThemePatch = resourcePatch(
|
||||||
name = "Custom theme",
|
name = "Custom theme",
|
||||||
description = "Applies a custom theme.",
|
description = "Applies a custom theme.",
|
||||||
|
use = false,
|
||||||
) {
|
) {
|
||||||
compatibleWith("com.spotify.music")
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
|
@ -4,9 +4,12 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/spotify/misc/UnlockPremiumPatch;"
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val unlockPremiumPatch = bytecodePatch(
|
val unlockPremiumPatch = bytecodePatch(
|
||||||
name = "Unlock Spotify Premium",
|
name = "Unlock Spotify Premium",
|
||||||
@ -14,11 +17,12 @@ val unlockPremiumPatch = bytecodePatch(
|
|||||||
) {
|
) {
|
||||||
compatibleWith("com.spotify.music")
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
extendWith("extensions/spotify.rve")
|
dependsOn(sharedExtensionPatch)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
// Make _value accessible so that it can be overridden in the extension.
|
// Make _value accessible so that it can be overridden in the extension.
|
||||||
accountAttributeFingerprint.classDef.fields.first { it.name == "value_" }.apply {
|
accountAttributeFingerprint.classDef.fields.first { it.name == "value_" }.apply {
|
||||||
|
// Add public flag and remove private.
|
||||||
accessFlags = accessFlags.or(AccessFlags.PUBLIC.value).and(AccessFlags.PRIVATE.value.inv())
|
accessFlags = accessFlags.or(AccessFlags.PUBLIC.value).and(AccessFlags.PRIVATE.value.inv())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +32,7 @@ val unlockPremiumPatch = bytecodePatch(
|
|||||||
productStateProtoFingerprint.method.addInstruction(
|
productStateProtoFingerprint.method.addInstruction(
|
||||||
instantiateUnmodifiableMapIndex,
|
instantiateUnmodifiableMapIndex,
|
||||||
"invoke-static { v$attributesMapRegister }," +
|
"invoke-static { v$attributesMapRegister }," +
|
||||||
"Lapp/revanced/extension/spotify/misc/UnlockPremiumPatch;->overrideAttribute(Ljava/util/Map;)V",
|
"$EXTENSION_CLASS_DESCRIPTOR->overrideAttribute(Ljava/util/Map;)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Add the query parameter trackRows to show popular tracks in the artist page.
|
// Add the query parameter trackRows to show popular tracks in the artist page.
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package app.revanced.patches.spotify.misc.extension
|
||||||
|
|
||||||
|
import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
|
||||||
|
|
||||||
|
val sharedExtensionPatch = sharedExtensionPatch("spotify", spotifyMainActivityOnCreate)
|
@ -0,0 +1,10 @@
|
|||||||
|
package app.revanced.patches.spotify.misc.extension
|
||||||
|
|
||||||
|
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||||
|
|
||||||
|
internal val spotifyMainActivityOnCreate = extensionHook {
|
||||||
|
custom { method, classDef ->
|
||||||
|
classDef.type == "Lcom/spotify/music/SpotifyMainActivity;" &&
|
||||||
|
method.name == "onCreate"
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user