Greasy Fork

Greasy Fork is available in English.

夸克懒得点 (屏蔽版+日志记录)

夸克懒得点.. 修复误判,组合“头像Hash+昵称”进行精准屏蔽,并记录自动保存的日志(含网址)

当前为 2025-12-05 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         夸克懒得点 (屏蔽版+日志记录)
// @namespace    http://greasyfork.icu/users/158417
// @version      0.22
// @description  夸克懒得点.. 修复误判,组合“头像Hash+昵称”进行精准屏蔽,并记录自动保存的日志(含网址)
// @author       JIEMO
// @match        *://pan.quark.cn/*
// @icon         https://pan.quark.cn/favicon.ico
// @license      GPL-3.0 License
// @run-at       document-end
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_setClipboard
// ==/UserScript==

(function() {
    'use strict';

    // ================= 配置区域 =================
    const STORAGE_KEY = "blocked_users_v2"; // 屏蔽列表键名
    const LOG_KEY = "auto_save_logs";       // 日志存储键名
    const MAX_LOGS = 200;                   // 最大保留日志条数
    const DEFAULT_BLOCKED = [];
    // ===========================================

    // ============================================================
    // 1. 基础工具
    // ============================================================

    function getBlockedList() {
        return GM_getValue(STORAGE_KEY, DEFAULT_BLOCKED);
    }

    function setBlockedList(list) {
        GM_setValue(STORAGE_KEY, list);
    }

    // 获取日志列表
    function getLogs() {
        return GM_getValue(LOG_KEY, []);
    }

    // 写入日志列表
    function setLogs(list) {
        GM_setValue(LOG_KEY, list);
    }

    // 格式化时间
    function formatTime(date) {
        const y = date.getFullYear();
        const m = String(date.getMonth() + 1).padStart(2, '0');
        const d = String(date.getDate()).padStart(2, '0');
        const h = String(date.getHours()).padStart(2, '0');
        const min = String(date.getMinutes()).padStart(2, '0');
        const s = String(date.getSeconds()).padStart(2, '0');
        return `${y}-${m}-${d} ${h}:${min}:${s}`;
    }

    // 字符串转 Hash 算法
    function computeStringHash(str) {
        if (!str) return "null";
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = (hash << 5) - hash + char;
            hash |= 0;
        }
        return "u" + Math.abs(hash);
    }

    // ============================================================
    // 2. 核心逻辑:提取信息
    // ============================================================

    function getTargetSharerInfo() {
        const shareContainer = document.querySelector('.share-info-wrap');
        if (!shareContainer) return null;

        const imgElement = shareContainer.querySelector('img');
        if (!imgElement || !imgElement.src) return null;
        const hashID = computeStringHash(imgElement.src);

        const nameElement = shareContainer.querySelector('.author-name');
        let nickName = "Unknown";
        if (nameElement) {
            nickName = nameElement.innerText.trim();
        } else {
            const possibleNames = shareContainer.querySelectorAll('div');
            if(possibleNames.length > 1) {
                nickName = possibleNames[1].innerText.trim();
            }
        }
        return { name: nickName, hash: hashID };
    }

    function getFileTitle() {
        const titleEl = document.querySelector('.filename-text');
        if (titleEl) {
            return titleEl.getAttribute('title') || titleEl.innerText.trim();
        }
        return document.title.replace(' - 夸克网盘', '') || "未知标题";
    }

    // ============================================================
    // 3. 日志记录逻辑
    // ============================================================

    function recordLog(user) {
        const fileName = getFileTitle();
        const currentTime = formatTime(new Date());
        const currentUrl = window.location.href;

        const newLog = {
            time: currentTime,
            name: user.name,
            hash: user.hash,
            title: fileName,
            url: currentUrl
        };

        let logs = getLogs();
        logs.unshift(newLog); // 插入到最前面

        if (logs.length > MAX_LOGS) {
            logs = logs.slice(0, MAX_LOGS);
        }

        setLogs(logs);
        console.log(`[夸克懒得点] 日志已记录: ${fileName}`);
    }

    // ============================================================
    // 4. UI 交互 & 菜单
    // ============================================================

    function showBlockedOverlay(user) {
        var overlay = document.createElement('div');
        Object.assign(overlay.style, {
            position: 'fixed', top: '0', left: '0', width: '100%', height: '100%',
            backgroundColor: 'rgba(0, 0, 0, 0.95)', zIndex: '999999',
            display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column'
        });

        var text = document.createElement('h1');
        text.innerText = "⚠️ 已屏蔽该分享者";
        text.style.cssText = "color: red; font-size: 60px; font-weight: bold; text-shadow: 2px 2px 10px black; margin: 0;";

        var subText = document.createElement('div');
        subText.innerHTML = `<p style='font-size:24px; color:white'>昵称:<span style='color:#ff6a00'>${user.name}</span></p>
                             <p style='font-size:16px; color:#888'>Hash:${user.hash}</p>`;
        subText.style.textAlign = 'center';
        subText.style.marginTop = '20px';

        var unlockBtn = document.createElement('button');
        unlockBtn.innerText = "本次临时允许 (点击消失)";
        unlockBtn.style.cssText = "margin-top: 30px; padding: 10px 20px; cursor: pointer; background: #333; color: #fff; border: 1px solid #666;";
        unlockBtn.onclick = function() { overlay.remove(); };

        overlay.appendChild(text);
        overlay.appendChild(subText);
        overlay.appendChild(unlockBtn);
        document.body.appendChild(overlay);
    }

    function showLogViewer() {
        const logs = getLogs();
        if (logs.length === 0) {
            alert("暂无日志记录。");
            return;
        }

        let logText = "时间\t\t\t昵称\t\t文件标题\t\t\t网址\n";
        logText += "--------------------------------------------------------------------------------------\n";
        logs.forEach(log => {
            const u = log.url || "无记录";
            logText += `[${log.time}]  ${log.name} (${log.hash})  >>>  ${log.title}  >>>  ${u}\n`;
        });

        var overlay = document.createElement('div');
        Object.assign(overlay.style, {
            position: 'fixed', top: '0', left: '0', width: '100%', height: '100%',
            backgroundColor: 'rgba(0,0,0,0.8)', zIndex: '999999',
            display: 'flex', justifyContent: 'center', alignItems: 'center'
        });

        var box = document.createElement('div');
        Object.assign(box.style, {
            width: '85%', height: '85%', backgroundColor: '#fff', borderRadius: '8px',
            padding: '20px', display: 'flex', flexDirection: 'column', color: '#333'
        });

        var title = document.createElement('h2');
        title.innerText = `📜 自动保存日志 (最近 ${logs.length} 条)`;
        title.style.margin = '0 0 10px 0';

        var textarea = document.createElement('textarea');
        textarea.value = logText;
        Object.assign(textarea.style, {
            flex: '1', width: '100%', fontSize: '12px', fontFamily: 'monospace',
            whiteSpace: 'pre', overflow: 'auto', border: '1px solid #ccc', padding: '10px'
        });

        var btnContainer = document.createElement('div');
        btnContainer.style.marginTop = '10px';
        btnContainer.style.textAlign = 'right';

        var copyBtn = document.createElement('button');
        copyBtn.innerText = "复制到剪贴板";
        copyBtn.style.marginRight = "10px";
        copyBtn.onclick = function() {
            GM_setClipboard(logText);
            alert("✅ 已复制!");
        };

        var clearBtn = document.createElement('button');
        clearBtn.innerText = "清空日志";
        clearBtn.style.marginRight = "10px";
        clearBtn.style.color = "red";
        clearBtn.onclick = function() {
            if(confirm("确定要清空所有日志吗?")) {
                setLogs([]);
                textarea.value = "";
            }
        };

        var closeBtn = document.createElement('button');
        closeBtn.innerText = "关闭";
        closeBtn.onclick = function() { overlay.remove(); };

        btnContainer.appendChild(clearBtn);
        btnContainer.appendChild(copyBtn);
        btnContainer.appendChild(closeBtn);

        box.appendChild(title);
        box.appendChild(textarea);
        box.appendChild(btnContainer);
        overlay.appendChild(box);
        document.body.appendChild(overlay);
    }

    function registerMenus() {
        GM_registerMenuCommand("🚫 屏蔽当前分享者", function() {
            const currentUser = getTargetSharerInfo();
            if (!currentUser) {
                alert("❌ 无法定位信息,请确保页面加载完成。");
                return;
            }
            const list = getBlockedList();
            const exists = list.some(u => u.name === currentUser.name && u.hash === currentUser.hash);
            if (exists) {
                alert(`用户 [${currentUser.name}] 已存在。`);
            } else {
                list.push(currentUser);
                setBlockedList(list);
                if(confirm(`✅ 已屏蔽: ${currentUser.name}\n是否刷新生效?`)) location.reload();
            }
        });

        GM_registerMenuCommand("⚙️ 管理屏蔽列表", function() {
            const list = getBlockedList();
            if (list.length === 0) {
                alert("屏蔽列表为空。");
                return;
            }
            let msg = "当前屏蔽列表:\n----------------------\n";
            list.forEach((u, index) => {
                msg += `【${index + 1}】 ${u.name} (Hash: ${u.hash})\n`;
            });
            const input = prompt(msg + "\n请输入序号删除:");
            if (input) {
                const index = parseInt(input) - 1;
                if (!isNaN(index) && index >= 0 && index < list.length) {
                    list.splice(index, 1);
                    setBlockedList(list);
                    alert("✅ 已移除,刷新生效。");
                    location.reload();
                }
            }
        });

        GM_registerMenuCommand("📜 查看/导出保存日志", function() {
            showLogViewer();
        });
    }

    registerMenus();

    // ============================================================
    // 5. 主程序执行
    // ============================================================

    // 场景1:分享页面
    if (window.location.href.startsWith("https://pan.quark.cn/s/")) {

        window.onload = function() {
            setTimeout(function() {

                // --- 步骤 A: 获取当前分享者信息 ---
                const currentUser = getTargetSharerInfo();

                // --- 步骤 B: 检查屏蔽列表 ---
                if (currentUser) {
                    const blockedList = getBlockedList();
                    const isBlocked = blockedList.some(u => u.name === currentUser.name && u.hash === currentUser.hash);

                    if (isBlocked) {
                        console.warn(`[夸克懒得点] 触发屏蔽!用户: ${currentUser.name}`);
                        showBlockedOverlay(currentUser);
                        return; // ⛔ 阻断
                    }
                }

                // --- 步骤 C: 自动转存 ---
                console.log("[夸克懒得点] 检查通过,执行自动转存...");

                // 1. 勾选文件
                var checkboxElement = document.querySelector('.ant-checkbox-input');
                try {
                    if (checkboxElement && !checkboxElement.checked) {
                        checkboxElement.click();
                    }
                } catch (error) { console.error(error); }

                // 2. 点击保存 (日志记录移到这里!)
                var saveButtonElement = document.querySelector('.share-save');
                if (saveButtonElement) {
                    if (currentUser) recordLog(currentUser); // ✅ 只有这里才记录
                    saveButtonElement.click();
                } else {
                    var saveButtonElement2 = document.querySelector('.file-info_r');
                    if (saveButtonElement2) {
                        if (currentUser) recordLog(currentUser); // ✅ 备用按钮也记录
                        saveButtonElement2.click();
                    }
                }

                // 3. 确认与跳转
                setTimeout(function() {
                    var confirmButtonElement = document.querySelector('.confirm-btn');
                    if (confirmButtonElement) {
                        confirmButtonElement.click();
                    }

                    var intervalId = setInterval(function() {
                        var viewButtonElement = document.querySelector('.path');
                        if (viewButtonElement) {
                            viewButtonElement.click();
                            clearInterval(intervalId);
                        }
                    }, 1000);
                }, 1000);

            }, 1500);
        };
    }

    // 场景2:列表页面
    if (window.location.href.startsWith("https://pan.quark.cn/list")) {
        window.onload = function() {
            setTimeout(function() {
                var checkboxElement = document.querySelector('.ant-checkbox-wrapper');
                try {
                    if(checkboxElement) checkboxElement.click();
                } catch (error) {}
            }, 1000);
        };
    }

})();