// ==UserScript== // @name 夸克懒得点 (屏蔽版+日志记录) // @namespace https://greasyfork.org/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 // @downloadURL none // ==/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 = `

昵称:${user.name}

Hash:${user.hash}

`; 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); }; } })();