MediaFire Downloader

Top-center button, selection menu, and location.replace for individual files.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

You will need to install an extension such as Tampermonkey to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         MediaFire Downloader
// @namespace    http://tampermonkey.net/
// @match        *://www.mediafire.com/folder/*
// @match        *://www.mediafire.com/file/*
// @match        *://www.mediafire.com/file_premium/*
// @version      2.0
// @description  Top-center button, selection menu, and location.replace for individual files.
// @author       CizgiciCocuk
// @license      GNU GPL v3
// @grant        none
// ==/UserScript==

/* jshint esversion: 8 */

(function() {
    'use strict';

    const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
    let downloadInitiated = false;

    const escapeHTML = (str) => {
        return str.replace(/[&<>"']/g, (m) => ({
            '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;'
        })[m]);
    };

    const getNameFromLink = (el) => {
        let name = el.querySelector('.filename, .name, .title')?.innerText || el.getAttribute('title') || el.innerText;
        if (!name || name.trim().length === 0 || name.includes('Unknown File')) {
            try {
                const parts = el.href.split('/');
                for (let i = parts.length - 1; i >= 0; i--) {
                    if (parts[i].length > 5 && !['file', 'file_premium'].includes(parts[i])) {
                        name = decodeURIComponent(parts[i].replace(/\+/g, ' '));
                        break;
                    }
                }
            } catch (e) { name = "File"; }
        }
        return (name || "Unknown File").trim();
    };

    // --- FOLDER PAGE LOGIC (KEPT AS IS) ---
    const injectBulkButton = () => {
        if (document.getElementById('mf-universal-bulk-btn')) return;

        const bulkBtn = document.createElement('button');
        bulkBtn.id = 'mf-universal-bulk-btn';
        bulkBtn.innerText = '🚀 SELECT DOWNLOADS';

        Object.assign(bulkBtn.style, {
            position: 'fixed', top: '10px', left: '50%', transform: 'translateX(-50%)',
            zIndex: '2147483647', padding: '12px 20px', backgroundColor: '#28a745',
            color: 'white', border: '2px solid white', borderRadius: '8px',
            fontWeight: 'bold', cursor: 'pointer', boxShadow: '0 4px 15px rgba(0,0,0,0.4)',
            fontFamily: 'sans-serif'
        });

        document.body.appendChild(bulkBtn);
        bulkBtn.onclick = showSelectionMenu;
    };

    const showSelectionMenu = () => {
        const existing = document.getElementById('mf-selection-menu');
        if (existing) existing.remove();

        const linkElements = Array.from(document.querySelectorAll('a[href*="/file/"], a[href*="/file_premium/"]'))
            .filter(a => !a.href.includes('/folder/'));

        const uniqueFiles = [];
        const seen = new Set();
        linkElements.forEach(el => {
            if (!seen.has(el.href)) {
                uniqueFiles.push({ name: getNameFromLink(el), href: el.href });
                seen.add(el.href);
            }
        });

        if (uniqueFiles.length === 0) {
            alert("No files detected. Scroll down to load more content!");
            return;
        }

        const menu = document.createElement('div');
        menu.id = 'mf-selection-menu';
        Object.assign(menu.style, {
            position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)',
            width: '450px', maxHeight: '70vh', backgroundColor: '#ffffff', zIndex: '2147483648',
            padding: '20px', borderRadius: '12px', boxShadow: '0 0 50px rgba(0,0,0,0.5)',
            display: 'flex', flexDirection: 'column', color: '#333', fontFamily: 'sans-serif', border: '1px solid #ccc'
        });

        let listHtml = '';
        uniqueFiles.forEach((f, i) => {
            listHtml += `
                <div style="margin-bottom:8px; display:flex; align-items:center; gap:10px; border-bottom:1px solid #eee; padding-bottom:4px;">
                    <input type="checkbox" id="mf-chk-${i}" data-url="${f.href}" checked style="cursor:pointer; width:16px; height:16px;">
                    <label for="mf-chk-${i}" style="font-size:13px; cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; flex-grow:1;">${escapeHTML(f.name)}</label>
                </div>`;
        });

        menu.innerHTML = `
            <div style="display:flex; justify-content:space-between; margin-bottom:15px;">
                <h3 style="margin:0; font-size:16px;">Batch Download</h3>
                <span style="font-size:12px; color:#666;">${uniqueFiles.length} files</span>
            </div>
            <div style="margin-bottom:10px; display:flex; gap:10px;">
                <button id="mf-select-all" style="flex:1; cursor:pointer;">Select All</button>
                <button id="mf-deselect-all" style="flex:1; cursor:pointer;">None</button>
            </div>
            <div style="overflow-y:auto; flex-grow:1;">${listHtml}</div>
            <div style="margin-top:20px; display:flex; gap:12px;">
                <button id="mf-start" style="flex:2; padding:12px; background:#28a745; color:white; border:none; border-radius:6px; cursor:pointer; font-weight:bold;">START</button>
                <button id="mf-close" style="flex:1; padding:12px; background:#eee; border:none; border-radius:6px; cursor:pointer;">Cancel</button>
            </div>
        `;

        document.body.appendChild(menu);

        document.getElementById('mf-select-all').onclick = () => { menu.querySelectorAll('input[type="checkbox"]').forEach(c => { c.checked = true; }); };
        document.getElementById('mf-deselect-all').onclick = () => { menu.querySelectorAll('input[type="checkbox"]').forEach(c => { c.checked = false; }); };
        document.getElementById('mf-close').onclick = () => { menu.remove(); };

        document.getElementById('mf-start').onclick = async () => {
            const selected = Array.from(menu.querySelectorAll('input[type="checkbox"]:checked'))
                                  .map(c => c.getAttribute('data-url'));

            if (selected.length === 0) return;
            menu.remove();

            for (let i = 0; i < selected.length; i++) {
                window.open(selected[i], '_blank');
                await wait(5000);
            }
        };
    };

    // --- INDIVIDUAL FILE PAGE LOGIC (UPDATED TO REDIRECT) ---
    const handleFilePage = () => {
        if (downloadInitiated) return;

        // Using direct redirect to download URL
        const downloadLinkInput = document.querySelector('.download_link .input') ||
                                 document.querySelector('#downloadButton');

        if (downloadLinkInput) {
            const downloadUrl = downloadLinkInput.getAttribute('href');
            if (downloadUrl) {
                downloadInitiated = true;

                // Redirect immediately (Aditya's focus-retention technique)
                location.replace(downloadUrl);

                // Close after 5 seconds
                setTimeout(() => { window.close(); }, 5000);
            }
        }
    };

    const route = () => {
        const url = window.location.href;
        if (url.includes('/folder/')) {
            injectBulkButton();
        } else if (url.includes('/file/') || url.includes('/file_premium/')) {
            handleFilePage();
        }
    };

    const observer = new MutationObserver(route);
    observer.observe(document.documentElement, { childList: true, subtree: true });
    route();
})();