// ==UserScript==
// @name         WebURL Image Downloader - Test with First 3 Images
// @namespace    http://tampermonkey.net/
// @version      1.8
// @description  Download the first 3 images from the current WebURL page as a ZIP file and log image URLs to the console.
// @author       Your Name
// @match        http://d15.876515.xyz/*
// @match        http://98.987328.xyz/*
// @match        http://97.987327.xyz/*
// @grant        GM_xmlhttpRequest
// @require      https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.0/jszip.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js
// @connect      d15.876515.xyz
// @connect      98.987328.xyz
// @connect      97.987327.xyz
// ==/UserScript==

(async function() {
    'use strict';

    async function fetchImage(url) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                responseType: "blob",
                onload: (response) => {
                    if (response.status === 200) {
                        console.log(`Successfully fetched image: ${url}`);
                        resolve(response.response);
                    } else {
                        reject(new Error(`Failed to load image: ${url} - Status: ${response.status}`));
                    }
                },
                onerror: (err) => {
                    console.warn(`Error fetching image ${url}:`, err);
                    reject(err);
                }
            });
        });
    }

    function createDownloadButton() {
        const button = document.createElement('button');
        button.innerText = 'DOWNLOAD FIRST 3 IMAGES';
        button.classList.add('download-button');
        button.style.marginLeft = '10px';
        button.style.padding = '5px 10px';
        button.style.cursor = 'pointer';
        button.style.backgroundColor = '#28a745';
        button.style.color = '#fff';
        button.style.border = 'none';
        button.style.borderRadius = '4px';
        button.style.fontSize = '14px';
        button.style.transition = 'background-color 0.3s';
        button.addEventListener('mouseenter', () => {
            button.style.backgroundColor = '#218838';
        });
        button.addEventListener('mouseleave', () => {
            button.style.backgroundColor = '#28a745';
        });
        return button;
    }

    function addDownloadButton(targetElement) {
        const button = createDownloadButton();
        button.addEventListener('click', async () => {
            button.disabled = true;
            button.innerText = 'Processing...';
            console.log('DOWNLOAD button clicked. Initiating download.');

            try {
                await downloadImages();
                button.innerText = 'DOWNLOAD FIRST 3 IMAGES';
                button.disabled = false;
                alert('Download completed successfully.');
            } catch (error) {
                console.error('An error occurred during the download process:', error);
                button.innerText = 'DOWNLOAD FIRST 3 IMAGES';
                button.disabled = false;
            }
        });

        targetElement.appendChild(button);
    }

    async function downloadImages() {
        const initialDoc = document;
        console.log('Using current page DOM.');

        const jianjieDiv = initialDoc.querySelector('div.item_title div.jianjie') || initialDoc.querySelector('div.jianjie');
        if (!jianjieDiv) {
            console.error('div.jianjie not found.');
            throw new Error('div.jianjie not found.');
        }
        const jianjieText = jianjieDiv.textContent.trim();
        console.log(`Extracted jianjie text: ${jianjieText}`);

        const titleMatch = jianjieText.match(/(\[XiuRen秀人网\]\s*.*?\[\d+P\])/);
        if (!titleMatch || !titleMatch[1]) {
            console.error('TITLE not found in jianjie text.');
            throw new Error('TITLE not found.');
        }
        const TITLE = titleMatch[1].trim().replace(/[\\/:*?"<>|]/g, '_');
        console.log(`Extracted TITLE for ZIP: ${TITLE}`);

        const zip = new JSZip();
        const contentDivs = initialDoc.querySelectorAll('div.content');
        let imagesInPage = [];

        contentDivs.forEach(div => {
            const imgs = div.querySelectorAll('img[src]');
            imagesInPage.push(...imgs);
        });

        console.log(`Found ${imagesInPage.length} images on current page`);

        if (imagesInPage.length === 0) {
            console.warn('No images found in any div.content on the current page.');
            throw new Error('No images found.');
        }

        const images = new Set();
        for (let img of imagesInPage) {
            const src = img.getAttribute('src');
            if (src) {
                const absoluteImgUrl = makeAbsoluteURL(src, window.location.href);
                images.add(absoluteImgUrl);
                console.log(`Collected Image URL: ${absoluteImgUrl}`);
            }
        }

        const imageArray = Array.from(images).slice(0, 3);
        let counter = 0;

        for (const imgUrl of imageArray) {
            try {
                const blob = await fetchImage(imgUrl);
                const extension = getFileExtension(imgUrl) || 'jpg';
                const validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
                const finalExtension = validExtensions.includes(extension) ? extension : 'jpg';
                const filename = `${String(counter + 1).padStart(3, '0')}.${finalExtension}`;
                zip.file(filename, blob);
                counter++;
                console.log(`Added ${filename} to ZIP (${counter}/${imageArray.length})`);
            } catch (e) {
                console.warn(`Failed to fetch image ${imgUrl}: ${e.message}`);
            }
        }

        if (counter === 0) {
            console.error('No images were successfully downloaded.');
            throw new Error('No images were successfully downloaded.');
        }

        zip.generateAsync({ type: 'blob' }).then((zipBlob) => {
            console.log('ZIP file generated. Preparing to download...');
            saveAs(zipBlob, `${TITLE}.zip`);
        }).catch((err) => {
            console.error('Error generating ZIP file:', err);
            throw err;
        });
    }

    function getFileExtension(url) {
        const match = url.match(/\.([a-zA-Z0-9]+)(?:\?.*)?$/);
        return match ? match[1].toLowerCase() : null;
    }

    function makeAbsoluteURL(url, base) {
        try {
            return new URL(url, base || window.location.origin).href;
        } catch {
            return url;
        }
    }

    function addButtons() {
        const titleSpanElements = document.querySelectorAll('div.title h2 a span');
        titleSpanElements.forEach(span => {
            if (!span.querySelector('button.download-button')) {
                addDownloadButton(span);
            }
        });

        const itemInfoDivs = document.querySelectorAll('div.item_info');
        itemInfoDivs.forEach(div => {
            if (!div.querySelector('button.download-button')) {
                addDownloadButton(div);
            }
        });
    }

    function initialize() {
        addButtons();
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initialize);
    } else {
        initialize();
    }

})();

it says "Download completed successfully" but no zip files are generated.