Toggle Features

Enable or disable features which may or may not be experimental/web version only.

Version au 25/04/2025. Voir la dernière version.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name        Toggle Features
// @description Enable or disable features which may or may not be experimental/web version only.
// @author      bertigert
// @version     1.0.2
// @icon        https://www.google.com/s2/favicons?sz=64&domain=deezer.com
// @namespace   Violentmonkey Scripts
// @match       https://www.deezer.com/*
// @grant       none
// @run-at      document-start
// ==/UserScript==


(function() {
    "use strict";
    // ======= Settings START =======

    const LOG_ALL_FEATURES_DEBUG = true; // useful to see all features (gets logged in the (dev tools) console, use https://github.com/bertigert/DeezMod/blob/main/plugins/enable_dev_mode.js to view)

    const DEEZER_CUSTOM_FEATURES = {
        // gapless_playback: true,
        deeztools: true, // simple way to toggle most of the custom features
    }

    const SPECIAL_FEATURES = {
        spoof_family: false, // Spoof your account to be the head of a family plan if you are a child account of a family account, opening up more features for you. (e.g. linking to last.fm)
    }

    // ======= Settings END =======



    function log(...args) {
        console.log("[Toggle Features]", ...args);
    }
    function error(...args) {
        console.error("[Toggle Features]", ...args);
    }
    function debug(...args) {
        console.debug("[Toggle Features]", ...args);
    }

    const original_fetch = window.fetch;

    log("Hooking fetch");
    window.fetch = async function (...args) {
        try {
            const url = new URL(args[0]);

            if (url.pathname !== "/ajax/gw-light.php" ||
                url.searchParams.get("method") !== "deezer.getUserData" ||
                url.searchParams.get("api_token") !== "" ||
                !url.searchParams.has("cid") ||
                typeof args[1].body !== "string"
            ) {
                return original_fetch.apply(window, args);
            }

            debug('Catched user data fetch call');

            const response = await original_fetch.apply(window, args);
            const resp_json = await response.json();

            if (resp_json.results) {
                // Special features
                if (SPECIAL_FEATURES.spoof_family) {
                    resp_json.results.USER.MULTI_ACCOUNT = {"ENABLED": true,"ACTIVE": true,"CHILD_COUNT": 0,"MAX_CHILDREN": 0,"PARENT": null,"IS_KID": false,"IS_SUB_ACCOUNT": false}
                }


                // Deezer custom features
                const features = resp_json.results.__DZR_GATEKEEPS__;

                if (LOG_ALL_FEATURES_DEBUG) {
                    log('All Features:', features, "Special Features:", SPECIAL_FEATURES);
                }

                for (let feature of Object.entries(DEEZER_CUSTOM_FEATURES)) {
                    features[feature[0]] = feature[1];
                    log(feature[1] ? 'Enabled' : 'Disabled', feature[0]);
                }
            }

            // since this request is only made once, we can unhook now
            log("Unhooking fetch");
            window.fetch = original_fetch;

            return new Response(JSON.stringify(resp_json), {
                status: response.status,
                statusText: response.statusText,
                headers: response.headers,
            });
        } catch (e) {
            error("Error in fetch hook:", e);
            return original_fetch.apply(window, args);
        }
    }
})();