// ==UserScript== // @name 夸克懒得点(屏蔽狗屎广告版) // @namespace https://greasyfork.org/users/158417 // @version 0.18 // @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 // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 默认屏蔽列表 (示例) const DEFAULT_BLOCKED = []; // ============================================================ // 1. 基础工具:存储与 Hash 计算 // ============================================================ function getBlockedList() { return GM_getValue("blocked_users_hash", DEFAULT_BLOCKED); } function setBlockedList(list) { GM_setValue("blocked_users_hash", list); } // 字符串转 Hash 算法 (类似 Java hashCode,生成唯一短 ID) 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; // Convert to 32bit integer } // 返回绝对值并加前缀,确保是正数字符串 return "u" + Math.abs(hash); } // ============================================================ // 2. 核心逻辑:精准定位与提取 // ============================================================ // 获取【分享信息区域】内的头像 Hash // 逻辑:找到 .share-info-wrap -> 找里面的第一个 img -> 获取 src -> 计算 Hash function getTargetSharerHash() { // 1. 定位分享信息容器 const shareContainer = document.querySelector('.share-info-wrap'); if (!shareContainer) { return null; // 没加载出来,或者不是分享页 } // 2. 找容器内的第一个图片 const imgElement = shareContainer.querySelector('img'); if (!imgElement || !imgElement.src) { return null; } // 3. 计算 Hash const hashID = computeStringHash(imgElement.src); // 在控制台打印,方便调试 console.log(`[夸克懒得点] 捕获分享者头像Src: ${imgElement.src}`); console.log(`[夸克懒得点] 计算HashID: %c${hashID}`, "color:red;font-weight:bold;"); return hashID; } // ============================================================ // 3. UI 交互:遮罩与菜单 // ============================================================ function showBlockedOverlay(hash) { 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('p'); subText.innerText = `HashID: ${hash}\n脚本已自动拦截转存`; subText.style.cssText = "color: #ccc; font-size: 20px; margin-top: 20px; text-align: center; white-space: pre-wrap;"; 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 registerMenus() { // 菜单:屏蔽当前 GM_registerMenuCommand("🚫 屏蔽当前分享者 (精准)", function() { const currentHash = getTargetSharerHash(); if (!currentHash) { alert("❌ 无法定位 .share-info-wrap 区域或头像。\n请确保页面已加载完毕,且当前是分享详情页。"); return; } const list = getBlockedList(); if (list.includes(currentHash)) { alert(`ID: ${currentHash} 已经在屏蔽列表中了。`); } else { list.push(currentHash); setBlockedList(list); if(confirm(`✅ 已添加屏蔽!\nHashID: ${currentHash}\n\n是否立即刷新生效?`)) { location.reload(); } } }); // 菜单:管理 GM_registerMenuCommand("📋 管理屏蔽列表", function() { const list = getBlockedList(); if (list.length === 0) { alert("屏蔽列表为空。"); return; } let msg = "当前屏蔽的 HashID 列表:\n(复制 ID 到下方框中可删除)\n\n"; list.forEach((hash, index) => { msg += `[${index + 1}] ${hash}\n`; }); const deleteInput = prompt(msg + "\n----------\n请输入要删除的 ID:"); if (deleteInput) { const trimInput = deleteInput.trim(); const newList = list.filter(item => item !== trimInput); if (newList.length < list.length) { setBlockedList(newList); alert(`✅ 已删除: ${trimInput}\n刷新生效。`); location.reload(); } else { alert("❌ 未找到该 ID。"); } } }); } registerMenus(); // ============================================================ // 4. 主程序执行 // ============================================================ // 场景1:分享页面 if (window.location.href.startsWith("https://pan.quark.cn/s/")) { window.onload = function() { // 稍微增加延迟,确保 React 渲染出 share-info-wrap setTimeout(function() { // --- 步骤 A: 获取当前分享者 Hash --- const currentHash = getTargetSharerHash(); // --- 步骤 B: 检查是否在屏蔽列表 --- if (currentHash) { const blockedList = getBlockedList(); if (blockedList.includes(currentHash)) { console.warn(`[夸克懒得点] 触发屏蔽!ID: ${currentHash}`); showBlockedOverlay(currentHash); return; // ⛔ 直接终止,不执行后续点击 } } else { console.log("[夸克懒得点] 未检测到分享者信息区域,跳过屏蔽检查。"); } // --- 步骤 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) { saveButtonElement.click(); } else { var saveButtonElement2 = document.querySelector('.file-info_r'); if (saveButtonElement2) { 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); // 1.5秒延迟确保DOM加载 }; } // 场景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); }; } })();