// ==UserScript== // @name 网站访问确认脚本 // @namespace https://github.com/liucong2013/userscript-site-access-check // @version 1.4 // @icon data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAgACADASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAABgcDBQgE/8QAKxAAAQMEAQQBAwQDAAAAAAAAAQIDBAUGBxEIABIhQRQxMlETFiJhJEKh/8QAFwEBAQEBAAAAAAAAAAAAAAAAAwACBf/EACMRAAEDAwMFAQAAAAAAAAAAAAECAxEABBIhMUEFFFGx8GH/2gAMAwEAAhEDEQA/ANgZfy7k6+8nO8duO0qLAq0GOmRdN0vth1qiMrH8Wm0+Qp9QIPsjYA0QpSONjgFjCqI+fkO+L9u+uOjukVKbXXG1KX7UhCPtH4BKtfnoS4tXz+yePN952l0OTW69X7tqUyohr7ysOhtAdVolDSNqUTo9oUfHno4urmdaiMdR6taUZTt01EFhNMeSVfBdGgpbhH3o2R2dvlewPGla248GTgDEVx7nqllaE90uDGUHxtpwT+b0KV+x8v8AFESLvxBkCq5BsuiJTIr1l12UmRNiQyCVPxngO5OgFK12gaSSQsA60/YF9W5kyzaTfdpTDKpNZjJkxnCNKAPgoUPS0qBSoeikjpM8cMKXRR587LOT6hMduS4WVIXCeWdpZcIJMgfRSzoab+1seNb8JqODiRRIWVMfQVE0i1cgVKHTBvYbZVpX6af6BH/T1JUXUZEQabp1w7cNJdcbwymATJjgnxI44qis2vwOJmZrlxhkEJgY3yLU3a3bFYfT/hxJjoAkQn1HwgE60T4ACSfCiUtezeM2Lrav1zI9HZMhpwJkUyCSlcSE4ryXWtb7vqOzZIRs9vrTIvKybTyFb8m1r1t+FWaVLGnYstoLQT6UPaVD0oEEeiOkCOCto0hS49hZhylaVMdJKqZTLhV8dIP+qApJKRr8k9Sgh2CrcUj9k08pKnUBWJkTuD99oKNeSPJSy+P1oSZk+fGlXLJZUKRRkuAvSHiP4rWkHaGgfKlHW9aG1EDqs4WWXFtXBVLq5r8Ot1O75D1yVWfEdDjbkuQrakBQ9oCQhQ9LSvqexOGuB7IZqS37XdueoVeO5FnVO45BnynmljS0hSvCNj2gBX99IJii5N4G5Oaatyn1e78O3dPS38NlCn5NPkrOgAB9HgNaPhLyU6VpaQekASpOCd/dKoqSoLWNPVf/2Q== // @description 限制指定主域名及其所有子域名的访问,显示确认页面,支持30分钟、今日内和本次会话不再提示,受限列表存储在 GM_Value 中,已确认页面显示倒计时,支持通过菜单添加当前域名到限制列表 // @author lc cong // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_addStyle // @grant GM_registerMenuCommand // @run-at document_start // @noframes // @supportURL https://raw.githubusercontent.com/liucong2013/userscript-site-access-check/refs/heads/main/README.md // @downloadURL https://update.greasyfork.icu/scripts/534187/%E7%BD%91%E7%AB%99%E8%AE%BF%E9%97%AE%E7%A1%AE%E8%AE%A4%E8%84%9A%E6%9C%AC.user.js // @updateURL https://update.greasyfork.icu/scripts/534187/%E7%BD%91%E7%AB%99%E8%AE%BF%E9%97%AE%E7%A1%AE%E8%AE%A4%E8%84%9A%E6%9C%AC.meta.js // ==/UserScript== (function() { 'use strict'; if (window.top !== window.self) { console.log("脚本在 iframe 中运行,退出或执行 iframe 特定逻辑"); return; console.log("======="); } // --- 配置区 --- // GM_Value Key for the restricted domains list const RESTRICTED_DOMAINS_KEY = 'my_restricted_domains'; // GM_Value Key Prefix for localStorage (长期和今日有效) const LOCAL_CONFIRM_KEY_PREFIX = 'confirmed_access_'; // SessionStorage Key Prefix (本次会话有效) - 不再用于主要确认逻辑 // const SESSION_CONFIRM_KEY_PREFIX = 'session_confirmed_access_'; // --- 函数区 --- // 从 GM_Value 中读取受限域名列表 function getRestrictedBaseDomains() { const domainsJson = GM_getValue(RESTRICTED_DOMAINS_KEY, '[]'); // 默认返回一个空数组的JSON字符串 try { const domains = JSON.parse(domainsJson); // 确保读取的是数组 if (!Array.isArray(domains)) { console.error("从 GM_Value 读取的受限域名列表不是数组,已重置。"); GM_deleteValue(RESTRICTED_DOMAINS_KEY); return []; } return domains; } catch (e) { console.error("解析受限域名列表失败:", e); // 如果解析失败,返回一个空数组并清除可能损坏的存储值 GM_deleteValue(RESTRICTED_DOMAINS_KEY); return []; } } // 将受限域名列表保存到 GM_Value 中 function setRestrictedBaseDomains(domainsArray) { try { GM_setValue(RESTRICTED_DOMAINS_KEY, JSON.stringify(domainsArray)); } catch (e) { console.error("保存受限域名列表失败:", e); } } // 检查当前域名是否在限制列表中的某个主域名或其子域名下 function isRestricted(hostname) { const restrictedBaseDomains = getRestrictedBaseDomains(); // 从 GM_Value 读取列表 return restrictedBaseDomains.some(baseDomain => { if (hostname === baseDomain) { return true; } // 检查是否以 '.' + 主域名 结尾,即是子域名 // 同时确保 hostname 比 baseDomain 长,避免意外匹配 (例如 'com' 匹配 'example.com') if (hostname.endsWith('.' + baseDomain) && hostname.length > baseDomain.length + 1) { return true; } return false; }); } // 获取今天结束时的 Unix 时间戳 (毫秒) function getEndOfTodayTimestamp() { const now = new Date(); const endOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999); return endOfToday.getTime(); } // 检查当前网站是否已被用户通过 localStorage 确认且未过期 function isLocalConfirmedAndNotExpired(hostname) { const storedData = GM_getValue(LOCAL_CONFIRM_KEY_PREFIX + hostname, null); if (!storedData) { return false; } try { const confirmInfo = JSON.parse(storedData); const now = Date.now(); if (confirmInfo.expiryType === '30min') { const expiryTime = confirmInfo.timestamp + 30 * 60 * 1000; return now < expiryTime; } else if (confirmInfo.expiryType === '5min') { const expiryTime = confirmInfo.timestamp + 5 * 60 * 1000; return now < expiryTime; } else if (confirmInfo.expiryType === 'today') { const endOfToday = getEndOfTodayTimestamp(); // 检查确认时间戳是否是今天(防止跨天后 today 确认仍然有效) const confirmDate = new Date(confirmInfo.timestamp); const nowDate = new Date(now); // 从时间戳创建 Date 对象 const todayStart = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate()); // 获取今天开始的时间 if (confirmDate < todayStart) { // 确认时间是昨天或更早,已过期 return false; } return now < endOfToday; } return false; } catch (e) { console.error("解析 localStorage 确认状态失败:", e); GM_deleteValue(LOCAL_CONFIRM_KEY_PREFIX + hostname); return false; } } // 检查当前网站是否已被用户通过 sessionStorage 确认 (不再用于主要确认逻辑) /* function isSessionConfirmed(hostname) { try { return sessionStorage.getItem(SESSION_CONFIRM_KEY_PREFIX + hostname) === 'true'; } catch (e) { console.error("访问 sessionStorage 失败:", e); return false; } } */ // 标记当前网站已被用户通过 localStorage 确认,并设置过期时间 function setLocalConfirmed(hostname, expiryType) { const confirmInfo = { timestamp: Date.now(), expiryType: expiryType }; GM_setValue(LOCAL_CONFIRM_KEY_PREFIX + hostname, JSON.stringify(confirmInfo)); } // 标记当前网站已被用户通过 sessionStorage 确认 (不再用于主要确认逻辑) /* function setSessionConfirmed(hostname) { try { sessionStorage.setItem(SESSION_CONFIRM_KEY_PREFIX + hostname, 'true'); } catch (e) { console.error("写入 sessionStorage 失败:", e); } } */ // 显示限制页面 function showRestrictionPage(hostname) { // 确保在页面加载早期清空内容 if (document.documentElement) document.documentElement.innerHTML = ''; if (document.head) document.head.innerHTML = ''; GM_addStyle(` body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f0f0f0; margin: 0; } .restriction-container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); text-align: center; max-width: 500px; } h1 { color: #d9534f; margin-bottom: 20px; } p { color: #555; margin-bottom: 30px; line-height: 1.6; } .button-container button { background-color: #5cb85c; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-size: 15px; margin: 5px 5px; transition: background-color 0.3s ease; } .button-container button:hover { background-color: #4cae4c; } .button-container { margin-top: 20px; } `); const restrictionHTML = `
您正尝试访问的网站 ${hostname} 已被标记为受限。请确认您希望继续访问,并选择本次确认的有效时长。