您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Floating UI enhancements: draggable gear icon, saved position, toggling panel, hover tooltip, and adaptive placement. Improved usability in Safari and Chrome.
当前为
// ==UserScript== // @name Anti-Fingerprinting Shield Plus // @namespace https://365devnet.eu/userscripts // @version 4.9 // @description Floating UI enhancements: draggable gear icon, saved position, toggling panel, hover tooltip, and adaptive placement. Improved usability in Safari and Chrome. // @author Richard B // @match *://*/* // @run-at document-start // @grant none // @license MIT // ==/UserScript== (() => { const DEBUG = true; const settingsKey = '__afs_user_settings'; const positionKey = '__afs_ui_position'; const sessionExpiryKey = '__afs_last_seen'; const spoofDefaults = { userAgent: true, platform: true, language: true, screen: true, hardwareConcurrency: true, timezone: true, canvas: true, webgl: true, audio: true, plugins: true, mediaDevices: true, storageEstimate: true, matchMedia: true, sharedArrayBuffer: true }; const spoofSettings = loadSettings(); const now = Date.now(); const SESSION_TIMEOUT_MINUTES = 30; const browser = detectBrowser(); if (isExpired()) { clearStoredValues(); log(`Session expired. Values cleared.`); } localStorage.setItem(sessionExpiryKey, now.toString()); const sessionId = getOrCreatePersistent('__afs_session_id', () => Math.random().toString(36).substring(2, 10)); function log(...args) { if (DEBUG) console.log('[AFS+]', ...args); } function loadSettings() { const saved = localStorage.getItem(settingsKey); return saved ? JSON.parse(saved) : { ...spoofDefaults }; } function saveSettings(settings) { localStorage.setItem(settingsKey, JSON.stringify(settings)); } function clearStoredValues() { Object.keys(localStorage).forEach(key => { if (key.startsWith('__afs_')) localStorage.removeItem(key); }); } function isExpired() { const lastSeen = parseInt(localStorage.getItem(sessionExpiryKey), 10); return isNaN(lastSeen) || now - lastSeen > SESSION_TIMEOUT_MINUTES * 60 * 1000; } function getOrCreatePersistent(key, generator) { const fullKey = '__afs_' + key; let value = localStorage.getItem(fullKey); if (!value) { value = generator(); localStorage.setItem(fullKey, value); } return value; } function detectBrowser() { const ua = navigator.userAgent; if (/Safari/.test(ua) && !/Chrome/.test(ua)) return 'Safari'; if (/Edg\//.test(ua)) return 'Edge'; if (/Chrome/.test(ua)) return 'Chrome'; return 'Other'; } function pick(arr) { return arr[Math.floor(Math.random() * arr.length)]; } function spoof(obj, prop, valueFn) { try { Object.defineProperty(obj, prop, { get: valueFn, configurable: true }); } catch (e) { log('Spoof failed:', prop, e); } } const spoofed = { userAgent: getOrCreatePersistent('ua', () => pick([ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' ])), platform: getOrCreatePersistent('platform', () => pick(['MacIntel', 'Win32', 'Linux x86_64'])), language: getOrCreatePersistent('lang', () => pick(['en-US', 'nl-NL', 'de-DE'])), screenWidth: parseInt(getOrCreatePersistent('sw', () => pick([1920, 1366, 1440]))), screenHeight: parseInt(getOrCreatePersistent('sh', () => pick([1080, 900, 768]))), cores: parseInt(getOrCreatePersistent('cores', () => pick([2, 4, 8]))), memory: parseInt(getOrCreatePersistent('mem', () => pick([2, 4, 8]))), timezone: getOrCreatePersistent('tz', () => pick(['UTC', 'Europe/Amsterdam', 'America/New_York'])) }; if (spoofSettings.userAgent) spoof(navigator, 'userAgent', () => spoofed.userAgent); if (spoofSettings.platform) spoof(navigator, 'platform', () => spoofed.platform); if (spoofSettings.language) { spoof(navigator, 'language', () => spoofed.language); spoof(navigator, 'languages', () => [spoofed.language, 'en']); } if (spoofSettings.screen) { spoof(window.screen, 'width', () => spoofed.screenWidth); spoof(window.screen, 'height', () => spoofed.screenHeight); spoof(window, 'innerWidth', () => spoofed.screenWidth); spoof(window, 'innerHeight', () => spoofed.screenHeight - 40); } if (spoofSettings.hardwareConcurrency) { spoof(navigator, 'hardwareConcurrency', () => spoofed.cores); spoof(navigator, 'deviceMemory', () => spoofed.memory); } if (spoofSettings.timezone && typeof Intl !== 'undefined') { const orig = Intl.DateTimeFormat.prototype.resolvedOptions; Intl.DateTimeFormat.prototype.resolvedOptions = function () { const options = orig.call(this); options.timeZone = spoofed.timezone; return options; }; } if (spoofSettings.canvas && CanvasRenderingContext2D) { const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData; CanvasRenderingContext2D.prototype.getImageData = function (x, y, w, h) { const data = originalGetImageData.call(this, x, y, w, h); for (let i = 0; i < data.data.length; i += 4) { data.data[i] += Math.floor(Math.random() * 3); data.data[i + 1] += Math.floor(Math.random() * 3); data.data[i + 2] += Math.floor(Math.random() * 3); } return data; }; } if (spoofSettings.webgl && WebGLRenderingContext) { const originalGL = WebGLRenderingContext.prototype.getParameter; WebGLRenderingContext.prototype.getParameter = function (param) { const spoofMap = { 37445: 'FakeVendor Inc.', 37446: 'Virtual GPU Renderer', 3379: 4096, 35661: 8 }; return spoofMap[param] || originalGL.call(this, param); }; } if (spoofSettings.audio && window.AudioContext) { const ctx = window.AudioContext.prototype; spoof(ctx, 'sampleRate', () => 44100); if (AnalyserNode.prototype.getFloatFrequencyData) { const original = AnalyserNode.prototype.getFloatFrequencyData; AnalyserNode.prototype.getFloatFrequencyData = function (arr) { original.call(this, arr); for (let i = 0; i < arr.length; i++) { arr[i] += Math.random() * 0.1; } }; } } if (spoofSettings.mediaDevices) { spoof(navigator, 'mediaDevices', () => ({ enumerateDevices: () => Promise.resolve([]) })); } if (spoofSettings.plugins) { spoof(navigator, 'plugins', () => []); spoof(navigator, 'mimeTypes', () => ({ length: 0 })); } if (spoofSettings.storageEstimate) { navigator.storage.estimate = () => Promise.resolve({ usage: 5242880, quota: 1073741824 }); } if (spoofSettings.matchMedia) { const originalMatchMedia = window.matchMedia; window.matchMedia = function (query) { if (query.includes('color-scheme') || query.includes('forced-colors')) { return { matches: Math.random() > 0.5, media: query }; } return originalMatchMedia.call(this, query); }; } if (spoofSettings.sharedArrayBuffer) { spoof(window, 'SharedArrayBuffer', () => undefined); } function createUI() { if (!DEBUG) return; const savedPos = JSON.parse(localStorage.getItem(positionKey) || '{"top":10,"left":10}'); const panel = document.createElement('div'); panel.style.cssText = 'position:absolute;background:#1b1b1b;color:#fff;padding:10px;border-radius:8px;z-index:99999;font-family:sans-serif;font-size:13px;'; panel.style.display = 'none'; panel.innerHTML = '<strong>Anti-Fingerprinting Shield Settings</strong><br>'; Object.keys(spoofDefaults).forEach(key => { const line = document.createElement('div'); line.innerHTML = `<label><input type="checkbox" ${spoofSettings[key] ? 'checked' : ''} /> ${key}</label>`; line.querySelector('input').addEventListener('change', () => { spoofSettings[key] = !spoofSettings[key]; saveSettings(spoofSettings); location.reload(); }); panel.appendChild(line); }); const icon = document.createElement('div'); icon.textContent = '⚙️'; icon.title = 'Anti-Fingerprinting Shield Plus'; icon.style.cssText = ` position:fixed; top:${savedPos.top}px; left:${savedPos.left}px; cursor:move; z-index:99999; font-size:20px; user-select:none; `; icon.addEventListener('click', () => { panel.style.display = (panel.style.display === 'none') ? 'block' : 'none'; const iconBox = icon.getBoundingClientRect(); panel.style.top = `${iconBox.top + 25}px`; panel.style.left = `${iconBox.left}px`; }); let isDragging = false; let offsetX = 0; let offsetY = 0; icon.addEventListener('mousedown', e => { isDragging = true; offsetX = e.clientX - icon.offsetLeft; offsetY = e.clientY - icon.offsetTop; }); document.addEventListener('mousemove', e => { if (isDragging) { icon.style.left = `${e.clientX - offsetX}px`; icon.style.top = `${e.clientY - offsetY}px`; } }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; localStorage.setItem(positionKey, JSON.stringify({ top: icon.offsetTop, left: icon.offsetLeft })); } }); document.addEventListener('fullscreenchange', () => { const isFullscreen = !!document.fullscreenElement; icon.style.display = isFullscreen ? 'none' : 'block'; }); document.addEventListener('keydown', e => { if (e.ctrlKey && e.shiftKey && e.key === 'F') { if (!document.body.contains(panel)) document.body.appendChild(panel); panel.style.display = 'block'; } }); document.addEventListener('DOMContentLoaded', () => { document.body.appendChild(icon); document.body.appendChild(panel); }); } createUI(); })();