MEGA鏈接檢測器

檢測MEGA鏈接是否可用,並在旁邊顯示狀態

目前為 2025-09-05 提交的版本,檢視 最新版本

// ==UserScript==
// @name         MEGA鏈接檢測器
// @name:zh-CN   MEGA链接检测器
// @name:zh-TW   MEGA鏈接檢測器
// @namespace    http://tampermonkey.net/
// @version      0.8
// @description  檢測MEGA鏈接是否可用,並在旁邊顯示狀態
// @description:zh-CN  检测MEGA链接是否可用,并在旁边显示状态
// @description:zh-TW  檢測MEGA鏈接是否可用,並在旁邊顯示狀態
// @author       Mark
// @license      MIT
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @connect      mega.nz
// @connect      mega.io
// @connect      g.api.mega.co.nz
// @connect      *
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';
    
    const DEBUG = true;
    const checkedLinks = new Set();
    let executionCount = 0;
    let observer = null;
    
    function log(message, data) {
        if (!DEBUG) return;
        console.log(`[MEGA檢測器] ${message}`, data || '');
    }
    
    function checkMEGALinks() {
        executionCount++;
        log(`開始檢查MEGA連結 (第${executionCount}次執行)`);
        
        const links = document.querySelectorAll('a');
        let megaLinksCount = 0;
        
        links.forEach(link => {
            const href = link.href;
            if (href && (href.includes('mega.nz') || href.includes('mega.io')) && !checkedLinks.has(href)) {
                checkedLinks.add(href);
                megaLinksCount++;
                log(`發現MEGA連結: ${href}`);
                checkLinkStatus(link, href);
            }
        });
        
        log(`本次檢查發現 ${megaLinksCount} 個新MEGA連結`);
        return megaLinksCount;
    }
    
    function checkLinkStatus(linkElement, url) {
        let statusIndicator = linkElement.nextElementSibling;
        if (!statusIndicator || !statusIndicator.classList.contains('mega-status-indicator')) {
            statusIndicator = document.createElement('span');
            statusIndicator.classList.add('mega-status-indicator');
            statusIndicator.style.marginLeft = '5px';
            statusIndicator.style.padding = '2px 5px';
            statusIndicator.style.borderRadius = '3px';
            statusIndicator.style.fontSize = '12px';
            linkElement.parentNode.insertBefore(statusIndicator, linkElement.nextSibling);
        }
        
        statusIndicator.textContent = '檢查中...';
        statusIndicator.style.backgroundColor = '#f0f0f0';
        statusIndicator.style.color = '#666';
        
        const { fileID, fileKey } = extractMEGAInfo(url);
        
        if (!fileID) {
            updateStatusIndicator(statusIndicator, false);
            return;
        }
        
        if (!fileKey) {
            updateStatusIndicator(statusIndicator, null, true);
            return;
        }
        
        GM_xmlhttpRequest({
            method: 'POST',
            url: 'https://g.api.mega.co.nz/cs',
            data: JSON.stringify([{"a": "g", "g": 1, "p": fileID, "ssl": 0}]),
            headers: {
                'Content-Type': 'application/json'
            },
            timeout: 10000,
            onload: function(response) {
                try {
                    const data = JSON.parse(response.responseText);
                    if (data && Array.isArray(data)) {
                        if (data[0] === -9) {
                            updateStatusIndicator(statusIndicator, false);
                        } else if (data[0] === -11) {
                            updateStatusIndicator(statusIndicator, null, true);
                        } else if (typeof data[0] === 'object' && !data[0].e) {
                            updateStatusIndicator(statusIndicator, true);
                        } else {
                            updateStatusIndicator(statusIndicator, null);
                        }
                    } else {
                        updateStatusIndicator(statusIndicator, null);
                    }
                } catch (e) {
                    updateStatusIndicator(statusIndicator, null);
                }
            },
            onerror: function() {
                updateStatusIndicator(statusIndicator, null);
            },
            ontimeout: function() {
                updateStatusIndicator(statusIndicator, null);
            }
        });
    }
    
    function extractMEGAInfo(url) {
        let match = url.match(/mega\.[a-z]+\/(?:file|folder)\/([a-zA-Z0-9_-]+)(?:#([a-zA-Z0-9_-]+)|$|\?)/i) ||
                    url.match(/mega\.[a-z]+\/#(?:F|)!([a-zA-Z0-9_-]+)(?:!([a-zA-Z0-9_-]+)|$|\?)/i);
        
        return match ? { fileID: match[1], fileKey: match[2] } : { fileID: null, fileKey: null };
    }
    
    function updateStatusIndicator(indicator, isValid, needsDecryption = false) {
        if (isValid === true) {
            indicator.textContent = '可用';
            indicator.style.backgroundColor = '#e6f7e6';
            indicator.style.color = '#2e8b57';
        } else if (isValid === false) {
            indicator.textContent = '已失效';
            indicator.style.backgroundColor = '#ffebee';
            indicator.style.color = '#d32f2f';
        } else if (needsDecryption) {
            indicator.textContent = '需要金鑰';
            indicator.style.backgroundColor = '#e3f2fd';
            indicator.style.color = '#1565c0';
        } else {
            indicator.textContent = '未知';
            indicator.style.backgroundColor = '#fff9c4';
            indicator.style.color = '#ff8f00';
        }
        
        indicator.title = needsDecryption ? '此連結需要正確的解密金鑰才能訪問' : 
                          (isValid === null ? '無法確定連結狀態' : '');
    }
    
    function setupMutationObserver() {
        if (observer) {
            observer.disconnect();
        }
        
        observer = new MutationObserver(function(mutations) {
            let shouldCheck = false;
            for (let mutation of mutations) {
                if (mutation.type === 'childList' || mutation.type === 'subtree') {
                    shouldCheck = true;
                    break;
                }
            }
            
            if (shouldCheck) {
                log('檢測到DOM變化,檢查新的MEGA連結');
                checkMEGALinks();
            }
        });
        
        observer.observe(document.body, {
            childList: true,
            subtree: true,
            attributes: false,
            characterData: false
        });
        
        log('DOM變化監視器已設置');
    }
    
    function initialize() {
        log('MEGA鏈接檢測器腳本初始化');
        
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', onReady);
        } else {
            onReady();
        }
        
        window.addEventListener('load', onLoad);
        window.addEventListener('popstate', onPageChange);
        window.addEventListener('pushstate', onPageChange);
        window.addEventListener('replacestate', onPageChange);
    }
    
    function onReady() {
        log('DOMContentLoaded 或文檔已準備就緒');
        setTimeout(function() {
            checkMEGALinks();
            setupMutationObserver();
        }, 500);
    }
    
    function onLoad() {
        log('頁面完全加載');
        setTimeout(checkMEGALinks, 1000);
    }
    
    function onPageChange() {
        log('檢測到頁面變化');
        setTimeout(function() {
            checkMEGALinks();
            setupMutationObserver();
        }, 500);
    }
    
    // 模擬 pushState 和 replaceState 事件
    function setupHistoryWatcher() {
        const pushState = history.pushState;
        const replaceState = history.replaceState;
        
        history.pushState = function() {
            pushState.apply(history, arguments);
            window.dispatchEvent(new Event('pushstate'));
        };
        
        history.replaceState = function() {
            replaceState.apply(history, arguments);
            window.dispatchEvent(new Event('replacestate'));
        };
    }
    
    setupHistoryWatcher();
    initialize();
    
    // 定期檢查
    setInterval(checkMEGALinks, 30000);
    
    log('MEGA鏈接檢測器腳本已加載');
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址