nhentai Super Filter

Filtering nhentai.net comics to preference

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         nhentai Super Filter
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  Filtering nhentai.net comics to preference
// @author       Tristan Reeves
// @match        https://nhentai.net/g/*
// @match        https://nhentai.net/*
// @grant        GM_xmlhttpRequest
// @connect      nhentai.net
// ==/UserScript==

(function() {
    'use strict';


    // Values for filtering
    //tag1 shouldnt be empty
    const tag1 = 'yuri';
    let tag2 = 'big breasts';
    let tag3 = '';
    let tag4 = '';
    //Tags that you dont want
    const nontag1 = 'yaoi';
    const nontag2 = 'males only';
    //No of pages
    const noofpage = 20;


    // Queue for comic URLs
    const comicQueue = [];
    let isProcessing = false; // Flag to check if we are currently processing

    // Function to add status indicator at the top of the page
    function createStatusIndicator() {
        const statusDiv = document.createElement('div');
        statusDiv.id = 'script-status';
        statusDiv.style.position = 'fixed';
        statusDiv.style.top = '60px';
        statusDiv.style.left = '10px';
        statusDiv.style.padding = '5px 10px';
        statusDiv.style.backgroundColor = 'red';
        statusDiv.style.color = 'white';
        statusDiv.style.fontSize = '12px';
        statusDiv.style.fontFamily = 'Arial, sans-serif';
        statusDiv.style.zIndex = '9999';
        statusDiv.style.borderRadius = '5px';
        statusDiv.style.boxShadow = '0 0 5px rgba(0, 0, 0, 0.2)';
        statusDiv.innerText = 'Analyzing comics...';
        document.body.appendChild(statusDiv);
    }

    // Function to update the status indicator when finished
    function updateStatusIndicator(isComplete) {
        const statusDiv = document.getElementById('script-status');
        if (isComplete) {
            statusDiv.innerText = 'Analysis complete!';
            statusDiv.style.backgroundColor = 'green';
            setTimeout(() => {
                statusDiv.style.opacity = '0'; // Fade out
                setTimeout(() => {
                    statusDiv.remove();
                }, 5000);
            }, 5000);
        }
    }

    function analyzeComicPage(url) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: function(response) {
                    if (response.status === 200) {
                        const parser = new DOMParser();
                        const doc = parser.parseFromString(response.responseText, 'text/html');

                        if (tag2 === '') tag2 = tag1;
                        if (tag3 === '') tag3 = tag1;
                        if (tag4 === '') tag4 = tag1;

                        const tagsSection = doc.querySelector('#info #tags');
                        let hasTag1 = false;
                        let hasTag2 = false;
                        let hasTag3 = false;
                        let hasTag4 = false;
                        let hasNontag1 = true;
                        let hasNontag2 = true;

                        if (tagsSection) {
                            const tagContainers = tagsSection.querySelectorAll('.tag-container.field-name');
                            tagContainers.forEach(container => {
                                if (container.textContent.includes('Tags:')) {
                                    const tagLinks = container.querySelectorAll('.tags a');
                                    tagLinks.forEach(link => {
                                        const tagName = link.querySelector('.name').textContent.toLowerCase();
                                        if (tagName === tag1) hasTag1 = true;
                                        if (tagName === tag2) hasTag2 = true;
                                        if (tagName === tag3) hasTag3 = true;
                                        if (tagName === tag4) hasTag4 = true;
                                        if (tagName === nontag1) hasNontag1 = false;
                                        if (tagName === nontag2) hasNontag2 = false;
                                    });
                                }
                            });
                        }

                        const languagesSection = doc.querySelector('#info-block #info');
                        let hasEnglish = false;

                        if (languagesSection) {
                            const languageContainers = languagesSection.querySelectorAll('.tag-container.field-name');
                            languageContainers.forEach(container => {
                                if (container.textContent.includes('Languages:')) {
                                    const languageLinks = container.querySelectorAll('.tags a');
                                    languageLinks.forEach(link => {
                                        const href = link.getAttribute('href');
                                        if (href && href.includes('/language/english/')) {
                                            hasEnglish = true;
                                        }
                                    });
                                }
                            });
                        }

                        const pagesSection = doc.querySelector('#info-block #info');
                        let pageCount = 0;

                        if (pagesSection) {
                            const pageContainers = pagesSection.querySelectorAll('.tag-container.field-name');
                            pageContainers.forEach(container => {
                                if (container.textContent.includes('Pages:')) {
                                    const pageSpan = container.querySelector('.tags a .name');
                                    if (pageSpan) {
                                        const pageText = pageSpan.textContent.trim();
                                        const pageCountMatch = pageText.match(/\d+/);
                                        if (pageCountMatch) {
                                            pageCount = parseInt(pageCountMatch[0], 10);
                                        }
                                    }
                                }
                            });
                        }


                        if (hasTag1 && hasTag2 && hasTag3 && hasTag4 && hasNontag1 && hasNontag2 && hasEnglish && pageCount > noofpage) {
                            resolve(url);
                        } else {
                            resolve(null); // Resolve with null if it does not match
                        }
                    } else {
                        reject(`Failed to fetch: ${response.status}`);
                    }
                },
                onerror: function(error) {
                    reject('Error fetching the page:', error);
                }
            });
        });
    }

    // Function to process the queue
    async function processQueue() {
        if (isProcessing) return; // Prevent re-entry if already processing
        isProcessing = true; // Mark as processing

        while (comicQueue.length > 0) {
            const url = comicQueue.shift();
            try {
                const result = await analyzeComicPage(url);
                if (result) {
                    window.open(result, '_blank');
                }
            } catch (error) {
                console.error(error); // Handle error
            }
        }


        updateStatusIndicator(true);
        isProcessing = false; // Mark as not processing
    }


    function fetchComics() {
        const galleries = document.querySelectorAll('.container.index-container .gallery');

        galleries.forEach(gallery => {
            const link = gallery.querySelector('a[href^="/g/"]');
            if (link) {
                const fullUrl = "https://nhentai.net" + link.getAttribute('href');
                comicQueue.push(fullUrl);
            }
        });

        // Start processing the queue
        processQueue();
    }

    // Main function
    function main() {
        const currentUrl = window.location.href;

        if (currentUrl.startsWith('https://nhentai.net/')) {
            createStatusIndicator();
            fetchComics();
        }
    }

    // Execute the main function
    main();
})();