// ==UserScript== // @name 我真的没有切屏! // @namespace https://github.com/lanzeweie // @version 0.82 // @description 我真的没有切屏!!!采用多重策略,从内核层面阻止浏览器将失焦或隐藏状态暴露给网站。尽最大可能伪造一直在窗口的假象 // @author lanzeweie@foxmail.com // @match *://*/* // @grant none // @run-at document-start // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/555806/%E6%88%91%E7%9C%9F%E7%9A%84%E6%B2%A1%E6%9C%89%E5%88%87%E5%B1%8F%EF%BC%81.user.js // @updateURL https://update.greasyfork.icu/scripts/555806/%E6%88%91%E7%9C%9F%E7%9A%84%E6%B2%A1%E6%9C%89%E5%88%87%E5%B1%8F%EF%BC%81.meta.js // ==/UserScript== (function() { 'use strict'; const blockEvents = ['visibilitychange', 'blur', 'focus', 'focusin', 'focusout', 'pagehide', 'pageshow']; const originalAddEventListener = EventTarget.prototype.addEventListener; EventTarget.prototype.addEventListener = function(type, listener, options) { if (blockEvents.includes(type)) { addLog('proxy', `🚫 已代理并阻止 ${type} 监听器附加`, '#6f42c1'); return; } return originalAddEventListener.call(this, type, listener, options); }; ["visibilitychange", "blur", "focus", "focusin", "focusout"].forEach((e) => { originalAddEventListener.call( window, e, (event) => { event.stopImmediatePropagation(); event.stopPropagation(); event.preventDefault(); return false; }, true ); }); let isEnabled = true; let isUIVisible = false; let uiContainer = null; let uiMinimizedTag = null; let uiUpdateFunction = () => {}; const stats = { visibilitychange: 0, blur: 0, focusout: 0, focusin: 0, pagehide: 0, pageshow: 0, proxy: 0, get total() { return this.visibilitychange + this.blur + this.focusout + this.focusin + this.pagehide + this.pageshow + this.proxy; } }; const interceptLog = []; const MAX_LOG_ITEMS = 15; function addLog(type, message, color = '#dc3545') { const timestamp = new Date().toLocaleTimeString(); interceptLog.unshift({ time: timestamp, type: type, message: message, color: color }); if (interceptLog.length > MAX_LOG_ITEMS) { interceptLog.pop(); } if (type === 'proxy') { stats.proxy++; } if (uiUpdateFunction) { uiUpdateFunction(); } } try { document.hasFocus = () => true; Object.defineProperty(document, 'hidden', { get() { return false; }, configurable: true }); Object.defineProperty(document, 'visibilityState', { get: () => 'visible', configurable: true }); if (!document.__hasFocusPatched) { document.hasFocus = function() { return true; }; document.__hasFocusPatched = true; } addLog('system', '✓ 属性覆盖成功 (hasFocus/hidden/visibilityState)', '#28a745'); } catch (e) { addLog('system', '❌ 属性覆盖失败: ' + e.message, '#dc3545'); } const interceptOtherEvents = (e) => { if (!isEnabled) return; e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); const eventType = e.type; if (stats.hasOwnProperty(eventType)) { stats[eventType]++; let logMessage = ''; switch (eventType) { case 'visibilitychange': logMessage = `📱 强力阻止 页面可见性检测`; break; case 'pagehide': logMessage = `📄 强力阻止 页面隐藏 (pagehide)`; break; case 'pageshow': logMessage = `📄 强力阻止 页面显示 (pageshow)`; break; case 'focusin': logMessage = `⚡ 强力阻止 焦点获得 (focusin)`; break; } addLog(eventType, logMessage, '#28a745'); } }; try { ['visibilitychange', 'pagehide', 'pageshow', 'focusin'].forEach(eventType => { originalAddEventListener.call(window, eventType, interceptOtherEvents, true); originalAddEventListener.call(document, eventType, interceptOtherEvents, true); }); } catch (e) { addLog('system', '❌ 监听器附加失败: ' + e.message, '#dc3545'); } (function() { try { const originalObserve = MutationObserver.prototype.observe; MutationObserver.prototype.observe = function(target, options) { if (target === document || target === document.documentElement) { addLog('system', '🛡️ 拦截 DOM 观察器', '#007bff'); return { disconnect: () => {}, observe: () => {}, unobserve: () => {} }; } return originalObserve.apply(this, arguments); }; const originalMutationObserver = window.MutationObserver; window.MutationObserver = function(callback) { const observer = new originalMutationObserver((mutations) => { const filteredMutations = mutations.filter(mutation => { return mutation.target !== document && mutation.target !== document.documentElement; }); if (filteredMutations.length > 0) { callback(filteredMutations); } }); return observer; }; window.MutationObserver.prototype = originalMutationObserver.prototype; } catch (e) { } })(); addLog('system', '✅ 切屏防护系统已启动', '#007bff'); addLog('system', '📌 UI优化: 最小化标签尺寸缩小 + 模式颜色区分', '#17a2b8'); const createUI = () => { if (window.top !== window.self) { return; } const completelyHideUI = () => { if (uiContainer && uiContainer.parentNode) { uiContainer.parentNode.removeChild(uiContainer); uiContainer = null; } if (uiMinimizedTag && uiMinimizedTag.parentNode) { uiMinimizedTag.parentNode.removeChild(uiMinimizedTag); uiMinimizedTag = null; } addLog('system', '👻 UI 已完全隐藏 (需刷新页面恢复)', '#6c757d'); }; // === 最小化标签 === uiMinimizedTag = document.createElement('div'); const uiTagTitle = document.createElement('span'); const uiTagHideButton = document.createElement('span'); uiTagTitle.textContent = '🛡️ 防护'; uiTagHideButton.textContent = '❌'; uiTagHideButton.title = '从页面中移除所有UI元素 (需刷新恢复)'; uiMinimizedTag.appendChild(uiTagTitle); uiMinimizedTag.appendChild(uiTagHideButton); // 最小化标签样式 Object.assign(uiMinimizedTag.style, { position: 'fixed', bottom: '20px', right: '20px', color: 'white', padding: '4px 8px', borderRadius: '15px', fontSize: '11px', fontFamily: 'sans-serif', cursor: 'pointer', zIndex: '999999', boxShadow: '0 2px 8px rgba(0, 0, 0, 0.2)', transition: 'all 0.3s ease', userSelect: 'none', display: 'flex', gap: '5px', alignItems: 'center', fontWeight: 'bold', }); Object.assign(uiTagHideButton.style, { padding: '2px 4px', backgroundColor: 'rgba(255, 255, 255, 0.2)', borderRadius: '10px', cursor: 'pointer', fontSize: '10px', fontWeight: 'normal', lineHeight: '1' }); const updateUIMinimizedTagBackground = () => { const enabledColor = 'rgba(0, 123, 255, 0.9)'; const disabledColor = 'rgba(108, 117, 125, 0.9)'; if (uiMinimizedTag) { uiMinimizedTag.style.backgroundColor = isEnabled ? enabledColor : disabledColor; } }; uiTagTitle.addEventListener('click', (e) => { e.stopPropagation(); isUIVisible = !isUIVisible; uiContainer.style.display = isUIVisible ? 'block' : 'none'; uiMinimizedTag.style.display = isUIVisible ? 'none' : 'flex'; }); uiTagHideButton.addEventListener('click', (e) => { e.stopPropagation(); completelyHideUI(); }); // === 主面板 === uiContainer = document.createElement('div'); const uiHeader = document.createElement('div'); const uiTitle = document.createElement('span'); const uiControls = document.createElement('div'); const uiToggleButton = document.createElement('span'); const uiMinimizeButton = document.createElement('span'); const uiHideButton = document.createElement('span'); const uiBody = document.createElement('div'); const uiRealTimePanel = document.createElement('div'); const uiRealTimeTitle = document.createElement('div'); const uiFocusStatus = document.createElement('div'); const uiVisibilityStatus = document.createElement('div'); const uiLogPanel = document.createElement('div'); const uiLogTitle = document.createElement('div'); const uiLogContent = document.createElement('div'); const uiStatsPanel = document.createElement('div'); const uiStatsTitle = document.createElement('div'); const uiStatsContent = document.createElement('div'); const uiControlPanel = document.createElement('div'); const uiStatus = document.createElement('div'); const uiHotKey = document.createElement('div'); uiHeader.appendChild(uiTitle); uiControls.appendChild(uiToggleButton); uiControls.appendChild(uiMinimizeButton); uiControls.appendChild(uiHideButton); uiHeader.appendChild(uiControls); uiRealTimePanel.appendChild(uiRealTimeTitle); uiRealTimePanel.appendChild(uiFocusStatus); uiRealTimePanel.appendChild(uiVisibilityStatus); uiLogPanel.appendChild(uiLogTitle); uiLogPanel.appendChild(uiLogContent); uiStatsPanel.appendChild(uiStatsTitle); uiStatsPanel.appendChild(uiStatsContent); uiControlPanel.appendChild(uiStatus); uiControlPanel.appendChild(uiHotKey); uiBody.appendChild(uiRealTimePanel); uiBody.appendChild(uiLogPanel); uiBody.appendChild(uiStatsPanel); uiBody.appendChild(uiControlPanel); uiContainer.appendChild(uiHeader); uiContainer.appendChild(uiBody); const appendUI = () => { if (document.body) { document.body.appendChild(uiContainer); document.body.appendChild(uiMinimizedTag); uiContainer.style.display = 'none'; updateUIMinimizedTagBackground(); } }; if (document.body) { appendUI(); } else { originalAddEventListener.call(document, 'DOMContentLoaded', appendUI); } uiTitle.textContent = "🛡️ 切屏防护"; uiToggleButton.title = '点击切换 启用/禁用'; uiMinimizeButton.textContent = '—'; uiMinimizeButton.title = '点击最小化 (切换到右下角标签)'; uiHideButton.textContent = '✕'; uiHideButton.title = '完全隐藏 UI'; const updateUI = () => { updateUIMinimizedTagBackground(); uiRealTimeTitle.innerHTML = '📊 实时状态'; uiFocusStatus.innerHTML = `🎯 焦点状态: ✓ 强制聚焦`; uiVisibilityStatus.innerHTML = `📱 页面可见: visible | hidden: false`; uiLogTitle.innerHTML = '📝 拦截日志'; if (interceptLog.length === 0) { uiLogContent.innerHTML = '