// ==UserScript== // @name KinkWall Background Everywhere // @namespace https://barefoot-boi.itch.io/ // @version 1.0.0 // @description Actually works on all websites. // @author @Barefootboi92 // @match *://*/* // @grant GM_xmlhttpRequest // @connect * // @run-at document-start // ==/UserScript== (function() { 'use strict'; // ===== CONFIG - EDIT THESE ===== // Set this to whichever of your 3 image pool URLs you want to use // https://footfetish.blakesfeet1992.com/random // https://rubber.blakesfeet1992.com/random // https://sneakers.blakesfeet1992.com/random const API_URL = "https://footfetish.blakesfeet1992.com/random"; // Poll every 30 minutes (30 * 60 * 1000 = 1,800,000 milliseconds) const POLL_INTERVAL = 1800000; const IMAGE_OPACITY = 0.6; // 0.0 to 1.0 - how visible the background is const IMAGE_BLUR = 0; // Blur in pixels (0 = no blur) const OVERLAY_DARKNESS = 0.5; // 0.0 to 1.0 - dark overlay for readability // ================================ let currentUrl = ""; let pollTimer = null; // Inject CSS for background function injectStyles() { const style = document.createElement('style'); style.id = 'custom-bg-everywhere-styles'; style.textContent = ` #custom-bg-container { position: fixed !important; top: 0 !important; left: 0 !important; width: 100vw !important; height: 100vh !important; z-index: -999999 !important; pointer-events: none !important; overflow: hidden !important; } #custom-bg-image { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; object-fit: cover !important; opacity: ${IMAGE_OPACITY} !important; filter: blur(${IMAGE_BLUR}px) !important; transition: opacity 0.5s ease !important; } #custom-bg-overlay { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; background: rgba(0, 0, 0, ${OVERLAY_DARKNESS}) !important; pointer-events: none !important; } `; (document.head || document.documentElement).appendChild(style); } // Create background elements function createBackgroundElements() { if (document.getElementById('custom-bg-container')) return; const container = document.createElement('div'); container.id = 'custom-bg-container'; const img = document.createElement('img'); img.id = 'custom-bg-image'; img.alt = ''; img.style.opacity = '0'; // Start invisible const overlay = document.createElement('div'); overlay.id = 'custom-bg-overlay'; container.appendChild(img); container.appendChild(overlay); // Inject as early as possible const targetElement = document.body || document.documentElement; if (targetElement.firstChild) { targetElement.insertBefore(container, targetElement.firstChild); } else { targetElement.appendChild(container); } } // Update background image function updateBackground(newUrl) { if (newUrl === currentUrl) return; // No change currentUrl = newUrl; const img = document.getElementById('custom-bg-image'); if (!img) return; // Fade out, change, fade in img.style.opacity = '0'; setTimeout(() => { img.src = newUrl; img.onload = () => { img.style.opacity = IMAGE_OPACITY; }; }, 500); console.log('[CustomBG] Background updated:', newUrl); } // Poll custom API function pollCustomAPI() { GM_xmlhttpRequest({ method: 'GET', url: API_URL, onload: function(response) { try { const data = JSON.parse(response.responseText); // Updated to target 'data.url' based on your JSON structure if (data.url && data.url !== currentUrl) { updateBackground(data.url); } } catch (e) { console.error('[CustomBG] Parse error:', e); } }, onerror: function(error) { console.error('[CustomBG] Fetch error:', error); } }); } // Start polling function startPolling() { if (pollTimer) clearInterval(pollTimer); pollCustomAPI(); // Immediate first poll pollTimer = setInterval(pollCustomAPI, POLL_INTERVAL); console.log('[CustomBG] Started polling every', POLL_INTERVAL / 60000, 'minutes'); } // Initialize function init() { injectStyles(); // Wait for body to exist if (document.body) { createBackgroundElements(); startPolling(); } else { // If body doesn't exist yet, wait for it const observer = new MutationObserver(() => { if (document.body) { observer.disconnect(); createBackgroundElements(); startPolling(); } }); observer.observe(document.documentElement, { childList: true }); } } // Run on load if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } // Cleanup on unload window.addEventListener('beforeunload', () => { if (pollTimer) clearInterval(pollTimer); }); })();