IMVU Product Download CFL Revisions Dropdown

Adds a single dropdown button with all available CFL revisions for IMVU products, with forced .cfl download.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         IMVU Product Download CFL Revisions Dropdown
// @namespace    http://tampermonkey.net/
// @version      1.3
// @auther       heapsofjoy
// @description  Adds a single dropdown button with all available CFL revisions for IMVU products, with forced .cfl download.
// @match        *://*.imvu.com/shop/product.php?products_id=*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Extract the product ID from the URL
    const urlParams = new URLSearchParams(window.location.search);
    const productId = urlParams.get('products_id');
    if (!productId) return; // Exit if no productId found

    // Set the HTTPS base URL for the product files
    const baseUrl = `https://userimages-akm.imvu.com/productdata/${productId}`;

    // Create the dropdown button
    const dropdownButton = document.createElement('button');
    dropdownButton.innerHTML = 'o';
    dropdownButton.title = 'Download CFL Revisions';
    dropdownButton.style.position = 'fixed';
    dropdownButton.style.bottom = '10px';
    dropdownButton.style.right = '10px';
    dropdownButton.style.width = '40px';
    dropdownButton.style.height = '40px';
    dropdownButton.style.backgroundColor = '#ff69b4';
    dropdownButton.style.color = 'white';
    dropdownButton.style.border = 'none';
    dropdownButton.style.borderRadius = '20px';
    dropdownButton.style.cursor = 'pointer';
    dropdownButton.style.fontFamily = 'Arial, sans-serif';
    dropdownButton.style.fontSize = '20px';
    dropdownButton.style.boxShadow = '0px 4px 10px rgba(0,0,0,0.2)';
    dropdownButton.style.zIndex = '1000';

    // Create the dropdown menu (initially hidden and positioned above the button)
    const dropdownMenu = document.createElement('div');
    dropdownMenu.style.display = 'none';
    dropdownMenu.style.position = 'fixed';
    dropdownMenu.style.bottom = '60px';
    dropdownMenu.style.right = '10px';
    dropdownMenu.style.width = '250px';
    dropdownMenu.style.backgroundColor = 'rgba(0, 0, 0, 0.85)';
    dropdownMenu.style.color = 'white';
    dropdownMenu.style.padding = '10px';
    dropdownMenu.style.border = '1px solid #ddd';
    dropdownMenu.style.borderRadius = '10px';
    dropdownMenu.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)';
    dropdownMenu.style.zIndex = '1001';

    // Toggle dropdown menu visibility and button expansion on click
    dropdownButton.onclick = () => {
        dropdownMenu.style.display = dropdownMenu.style.display === 'none' ? 'block' : 'none';
        dropdownButton.style.width = dropdownMenu.style.display === 'none' ? '40px' : '60px';
        dropdownButton.style.height = dropdownMenu.style.display === 'none' ? '40px' : '40px';
        dropdownButton.innerHTML = dropdownMenu.style.display === 'none' ? '📥' : 'Close ▼';
    };

function addRevisionLink(revision) {
    const revisionLink = document.createElement('a');
    revisionLink.textContent = `View Revision ${revision}`;
    revisionLink.style.display = 'block';
    revisionLink.style.padding = '8px 0';
    revisionLink.style.color = '#ff69b4';
    revisionLink.style.textDecoration = 'none';
    revisionLink.style.borderBottom = '1px solid #444';

    // Just open the JSON file in a new tab
    revisionLink.href = `${baseUrl}/${revision}/_contents.json`;
    revisionLink.target = '_blank';
    revisionLink.rel = 'noopener noreferrer';

    dropdownMenu.appendChild(revisionLink);
}


    // Function to check if a revision exists
    function checkRevision(revision, misses = 0, maxMisses = 10) {
        const url = `${baseUrl}/${revision}/_contents.json`;
        fetch(url, { method: 'HEAD' })
            .then((response) => {
                if (response.ok) {
                    addRevisionLink(revision);
                    checkRevision(revision + 1, 0, maxMisses); // Reset misses on success
                } else {
                    if (misses < maxMisses) {
                        checkRevision(revision + 1, misses + 1, maxMisses);
                    }
                }
            })
            .catch(() => {
                if (misses < maxMisses) {
                    checkRevision(revision + 1, misses + 1, maxMisses);
                }
            });
    }    

    checkRevision(1, 0, 10);

    // Append the dropdown button and menu to the page
    document.body.appendChild(dropdownButton);
    document.body.appendChild(dropdownMenu);

    // Hide dropdown if clicked outside
    document.addEventListener('click', (event) => {
        if (!dropdownButton.contains(event.target) && !dropdownMenu.contains(event.target)) {
            dropdownMenu.style.display = 'none';
            dropdownButton.innerHTML = 'o';
            dropdownButton.style.width = '40px';
            dropdownButton.style.height = '40px';
        }
    });
})();