Greasy Fork

Greasy Fork is available in English.

Iwara ID 黑名单

在 iwara.tv 上根据作者 Profile ID 进行屏蔽 (作品和评论区),永久有效。支持在作者主页一键拉黑ID。

当前为 2025-07-11 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Iwara ID 黑名单
// @namespace    http://tampermonkey.net/
// @version      3.1
// @license      MIT
// @description  在 iwara.tv 上根据作者 Profile ID 进行屏蔽 (作品和评论区),永久有效。支持在作者主页一键拉黑ID。
// @author       Gemini
// @match        https://*.iwara.tv/*
// @grant        GM_getValue
// @grant        GM_setValue
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // --- 使用统一的存储键来保存基于ID的黑名单 ---
    const BLACKLIST_KEY = 'iwara_id_blacklist';

    const getBlacklist = () => new Set(JSON.parse(GM_getValue(BLACKLIST_KEY, '[]')));
    const saveBlacklist = (blacklistSet) => GM_setValue(BLACKLIST_KEY, JSON.stringify(Array.from(blacklistSet)));


    /**
     * 根据 Profile ID 隐藏作品列表中的项目
     */
    const hideBlacklistedWorks = () => {
        const blacklist = getBlacklist();
        if (blacklist.size === 0) return;

        const works = document.querySelectorAll('.page-videoList__item:not([data-id-checked])');
        for (const work of works) {
            work.dataset.idChecked = 'true';

            const authorLink = work.querySelector('a.username');
            if (authorLink) {
                const href = authorLink.getAttribute('href');
                const parts = href.split('/profile/');
                if (parts.length > 1) {
                    const profileId = parts[1];
                    if (blacklist.has(profileId)) {
                        console.log(`[Iwara ID 黑名单] 已隐藏 ID: ${profileId} (作者: ${authorLink.title}) 的作品`);
                        work.style.display = 'none';
                    }
                }
            }
        }
    };

    /**
     * 根据 Profile ID 隐藏评论区中的评论 (新增功能)
     */
    const hideBlacklistedComments = () => {
        const blacklist = getBlacklist();
        if (blacklist.size === 0) return;

        // 选取所有尚未检查过的评论元素
        const comments = document.querySelectorAll('.comment:not([data-id-checked])');
        for (const comment of comments) {
            comment.dataset.idChecked = 'true'; // 标记为已检查

            const authorLink = comment.querySelector('a.username');
            if (authorLink) {
                const href = authorLink.getAttribute('href');
                const parts = href.split('/profile/');
                if (parts.length > 1) {
                    const profileId = parts[1];
                    if (blacklist.has(profileId)) {
                        // 找到该评论最外层的容器并隐藏它,以确保布局正确
                        const commentContainer = comment.closest('.col-12');
                        if (commentContainer) {
                             console.log(`[Iwara ID 黑名单] 已隐藏 ID: ${profileId} (作者: ${authorLink.title}) 的评论`);
                             commentContainer.style.display = 'none';
                        }
                    }
                }
            }
        }
    };


    /**
     * 在作者主页根据 Profile ID 添加“拉黑ID”按钮
     */
    const addBlockButton = () => {
        if (!window.location.pathname.startsWith('/profile/')) return;

        const container = document.querySelector('.page-profile__header__middle .d-flex.align-items-center');
        if (!container || document.querySelector('#author-id-block-btn')) return;

        const urlParts = window.location.pathname.split('/profile/');
        if (urlParts.length <= 1) return;
        const currentProfileId = urlParts[1];

        const blockButton = document.createElement('div');
        blockButton.id = 'author-id-block-btn';
        Object.assign(blockButton.style, {
            marginLeft: '16px', padding: '4px 10px', border: '1px solid #ccc',
            borderRadius: '5px', cursor: 'pointer', fontSize: '14px',
            fontWeight: 'bold', userSelect: 'none', transition: 'all 0.2s ease'
        });

        const updateButtonState = (isBlocked) => {
            if (isBlocked) {
                blockButton.textContent = `✓ 已拉黑此ID (移除)`;
                blockButton.style.borderColor = '#e91e63';
                blockButton.style.color = '#e91e63';
                blockButton.style.backgroundColor = '#fce4ec';
            } else {
                blockButton.textContent = `🚫 拉黑此ID`;
                blockButton.style.borderColor = '#ccc';
                blockButton.style.color = '#555';
                blockButton.style.backgroundColor = '#f0f0f0';
            }
        };

        let blacklist = getBlacklist();
        updateButtonState(blacklist.has(currentProfileId));

        blockButton.addEventListener('mouseenter', () => { blockButton.style.opacity = '0.8'; });
        blockButton.addEventListener('mouseleave', () => { blockButton.style.opacity = '1'; });

        blockButton.addEventListener('click', (e) => {
            e.stopPropagation();
            let currentBlacklist = getBlacklist();
            if (currentBlacklist.has(currentProfileId)) {
                currentBlacklist.delete(currentProfileId);
                updateButtonState(false);
            } else {
                currentBlacklist.add(currentProfileId);
                updateButtonState(true);
            }
            saveBlacklist(currentBlacklist);
        });

        container.appendChild(blockButton);
    };

    // --- 脚本启动与动态内容监控 ---
    const observer = new MutationObserver(() => {
        // 每次页面DOM发生变化时,都执行所有检查和屏蔽操作
        hideBlacklistedWorks();
        hideBlacklistedComments(); // <--- 调用新增的评论屏蔽函数
        addBlockButton();
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();