Honeycome Auto Downloader

全自动翻页下载器(支持跨页持续下载)

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         Honeycome Auto Downloader
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  全自动翻页下载器(支持跨页持续下载)
// @author       Grok
// @match        *://honeycome-uploader.illgames.jp/list/chara*
// @grant        GM_download
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @connect      honeycome-uploader.illgames.jp
// @license MIT 
// ==/UserScript==

(function() {
    'use strict';

    // 样式配置
    GM_addStyle(`
        #autoDownloadBtn {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 10px 20px;
            background: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            z-index: 9999;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            transition: all 0.3s;
        }
        #autoDownloadBtn:hover { background: #45a049; }
        #autoDownloadBtn.disabled {
            background: #666 !important;
            cursor: not-allowed;
        }
    `);

    // 主程序
    window.addEventListener('load', function() {
        const STATE = {
            isDownloading: GM_getValue('autoDownload', false),
            currentPage: GM_getValue('currentPage', 1),
            totalDownloaded: GM_getValue('totalDownloaded', 0)
        };

        // 创建控制按钮
        const btn = createControlButton();
        let observer = null;

        // 自动启动检测
        if (STATE.isDownloading) {
            startDownloadProcess();
        }

        function createControlButton() {
            const button = document.createElement('button');
            button.id = 'autoDownloadBtn';
            updateButtonState(button);

            button.addEventListener('click', () => {
                if (!STATE.isDownloading) {
                    STATE.isDownloading = true;
                    STATE.currentPage = 1;
                    STATE.totalDownloaded = 0;
                    GM_setValue('autoDownload', true);
                    startDownloadProcess();
                } else {
                    stopDownloadProcess();
                }
                updateButtonState(button);
            });

            document.body.appendChild(button);
            return button;
        }

        async function startDownloadProcess() {
            btn.classList.add('disabled');
            initMutationObserver();

            try {
                const links = await waitForLinks();
                STATE.totalDownloaded += links.length;
                await processDownloads(links);

                const nextPage = getNextPageLink();
                if (nextPage) {
                    GM_setValue('currentPage', STATE.currentPage + 1);
                    window.location.href = nextPage;
                } else {
                    finalizeDownload();
                }
            } catch (error) {
                console.error('下载流程出错:', error);
                stopDownloadProcess();
            }
        }

        function stopDownloadProcess() {
            STATE.isDownloading = false;
            GM_setValue('autoDownload', false);
            if (observer) observer.disconnect();
            updateButtonState(btn);
            btn.classList.remove('disabled');
        }

        function finalizeDownload() {
            stopDownloadProcess();
            GM_setValue('totalDownloaded', 0);
            alert(`全部下载完成!共下载 ${STATE.totalDownloaded} 个文件`);
        }

        // 工具函数
        function initMutationObserver() {
            observer = new MutationObserver(mutations => {
                mutations.forEach(mutation => {
                    if (mutation.addedNodes.length) {
                        console.log('检测到DOM变化,重新扫描下载链接...');
                    }
                });
            });
            observer.observe(document.body, { subtree: true, childList: true });
        }

        function waitForLinks() {
            return new Promise(resolve => {
                const checkLinks = () => {
                    const links = [...document.querySelectorAll('a[title="クリックしてダウンロード"]')];
                    if (links.length > 0) {
                        console.log(`找到 ${links.length} 个下载链接`);
                        resolve(links);
                    } else {
                        setTimeout(checkLinks, 1000);
                    }
                };
                checkLinks();
            });
        }

        async function processDownloads(links) {
            for (const [index, link] of links.entries()) {
                const url = link.href;
                const filename = `${STATE.currentPage}_${index}_${url.split('/').pop().split('&')[0]}`;

                btn.textContent = `下载中 ${index+1}/${links.length} (共${STATE.totalDownloaded}个)`;
                await downloadWithRetry(url, filename);
                await new Promise(resolve => setTimeout(resolve, 2500)); // 节流控制
            }
        }

        async function downloadWithRetry(url, filename, retries = 3) {
            try {
                await new Promise((resolve, reject) => {
                    GM_download({
                        url: url,
                        name: filename,
                        onload: resolve,
                        onerror: err => reject(err)
                    });
                });
                console.log(`✓ 成功下载: ${filename}`);
            } catch (error) {
                if (retries > 0) {
                    console.warn(`⚠ 重试下载 (${4-retries}/3): ${filename}`);
                    await new Promise(resolve => setTimeout(resolve, 5000));
                    return downloadWithRetry(url, filename, retries - 1);
                }
                throw new Error(`× 下载失败: ${filename} (${error})`);
            }
        }

        function getNextPageLink() {
            const nextBtn = document.querySelector('.pager__link--next:not(.disable)');
            return nextBtn ? nextBtn.href : null;
        }

        function updateButtonState(button) {
            button.textContent = STATE.isDownloading
                ? `停止下载 (已下载 ${STATE.totalDownloaded} 个)`
                : '开始自动下载';
            button.style.backgroundColor = STATE.isDownloading ? '#666' : '#4CAF50';
        }
    });
})();