// ==UserScript== // @name s.to autoplay // @namespace https://github.com/zaheer-exe // @version 8.6 // @description Autoplay für SerienStream.to // @author zaheer-exe // @match https://s.to/* // @match https://serienstream.to/* // @match https://aniworld.to/* // @match https://voe.sx/* // @match *://*/* // @grant GM_xmlhttpRequest // @grant none // @run-at document-start // @icon https://www.google.com/s2/favicons?sz=64&domain=s.to // @license Apache License // @downloadURL none // ==/UserScript== function adblock() { function hasKey(url) { // Check for 'key' parameter const keyPattern = /[?&]key=[^&]+/i; return keyPattern.test(url); } // Override window.open const originalWindowOpen = window.open; window.open = function(url, ...args) { if (typeof url === 'string' && hasKey(url)) { console.log('Blocked popup with key:', url, window.location.href); return null; } return originalWindowOpen.call(this, url, ...args); }; // Override createElement to prevent script injection const originalCreateElement = document.createElement; document.createElement = function(tagName) { const element = originalCreateElement.call(document, tagName); if (tagName.toLowerCase() === 'script') { const originalSetAttribute = element.setAttribute; element.setAttribute = function(name, value) { if (name === 'src' && hasKey(value)) { console.log('Blocked script src with key:', value); return; } return originalSetAttribute.call(this, name, value); }; } return element; }; // Intercept and block certain XMLHttpRequests const originalXHROpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url, ...args) { if (hasKey(url)) { console.log('Blocked XHR with key:', url); throw new Error('Blocked XHR'); } return originalXHROpen.call(this, method, url, ...args); }; // Block fetch requests with keys const originalFetch = window.fetch; window.fetch = function(input, init) { if (typeof input === 'string' && hasKey(input)) { console.log('Blocked fetch with key:', input); return Promise.reject(new Error('Blocked fetch')); } return originalFetch.call(this, input, init); }; // Remove suspicious hidden inputs periodically const removeHiddenInputs = () => { const hiddenInputs = document.querySelectorAll('input[type="hidden"]'); hiddenInputs.forEach(input => { if (input.name && input.name.length > 30 && /^[a-f0-9]{32}$/.test(input.name)) { console.log('Removed suspicious hidden input:', input.name); input.remove(); } }); }; // Prevent timer-based function execution const originalSetTimeout = window.setTimeout; const originalSetInterval = window.setInterval; const wrapTimerFunction = (originalFunc) => { return function(callback, delay, ...args) { if (typeof callback === 'function') { const callbackString = callback.toString(); if (callbackString.includes('append') && callbackString.includes('input')) { console.log('Blocked suspicious timer function'); return; } // Wrap the callback to remove hidden inputs after execution const wrappedCallback = function() { callback.apply(this, arguments); removeHiddenInputs(); }; return originalFunc.call(this, wrappedCallback, delay, ...args); } return originalFunc.call(this, callback, delay, ...args); }; }; window.setTimeout = wrapTimerFunction(originalSetTimeout); window.setInterval = wrapTimerFunction(originalSetInterval); // Initial cleanup removeHiddenInputs(); // Periodically check and remove suspicious elements setInterval(removeHiddenInputs, 1000); }; ////////// LISTER //////////////////////////////////////////////////////////////// const sToHosts = ['s.to', 'aniworld.to', 'serienstream.to']; if (sToHosts.includes(new URL(window.location.href).hostname)) { let isAutoPlayed = false; function nextEpisode() { const currentLang = document.querySelector("img.selectedLanguage").dataset.langKey; console.log("S: current lang ", currentLang); const episodeMenuCurrentElem = document.querySelector('li a.active[href*="episode"]'); const nextEpisodeUrl = episodeMenuCurrentElem.parentElement.nextElementSibling.querySelector('a'); var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", nextEpisodeUrl, false); xmlHttp.send(null); let temp = document.createElement('div'); temp.innerHTML = xmlHttp.responseText; let url = temp.querySelector('li[data-lang-key="' + currentLang + '"] .watchEpisode .icon.VOE').parentElement.href; let title = temp.querySelector(".hosterSiteTitle").innerHTML; let streamIframe = document.querySelector(".inSiteWebStream iframe"); streamIframe.src = url; document.querySelector(".hosterSiteTitle").innerHTML = title; document.querySelector(".breadCrumbMenu").innerHTML = temp.querySelector(".breadCrumbMenu").innerHTML; episodeMenuCurrentElem.classList.remove('active'); nextEpisodeUrl.classList.add('active'); window.history.pushState("", "", nextEpisodeUrl.href); if (!isAutoPlayed) { disableElements(); isAutoPlayed = true; } } function disableElements() { const style = document.createElement('style'); style.textContent = ` .changeLanguage, li[data-link-target] { opacity: 0.3; cursor: none; } .changeLanguageBox, li[data-link-target] > .generateInlinePlayer { pointer-events: none; } .tooltip { position: absolute; background-color: #333; /* Dark background for contrast */ color: #fff; /* White text for contrast */ padding: 10px; /* Padding for better appearance */ border-radius: 5px; /* Rounded corners */ font-size: 14px; /* Font size for readability */ line-height: 1.4; /* Line height for better text readability */ white-space: nowrap; /* Prevent text wrapping */ display: none; /* Hidden by default */ z-index: 9999; /* Ensure it appears above other content */ pointer-events: none; /* Ensure it doesn't interfere with interactions */ transform: translate(-50%, -50%); /* Center tooltip on the cursor */ } `; document.head.appendChild(style); const tooltip = document.createElement('div'); tooltip.className = 'tooltip'; tooltip.textContent = 'Autoplay enabled. Refresh/Reload Page to change settings.'; document.body.appendChild(tooltip); function updateTooltipPosition(event) { tooltip.style.left = `${event.pageX}px`; tooltip.style.top = `${event.pageY}px`; } function showTooltip(event) { tooltip.style.display = 'block'; updateTooltipPosition(event); } function hideTooltip() { tooltip.style.display = 'none'; } const elements = document.querySelectorAll('.changeLanguage, li[data-link-target]'); elements.forEach(element => { element.addEventListener('mouseenter', showTooltip); element.addEventListener('mousemove', updateTooltipPosition); element.addEventListener('mouseleave', hideTooltip); }); } function autoPlaySettings() { const style = document.createElement('style'); style.textContent = ` .autoplay-settings-container { border: 1px solid #3a3a3a; border-radius: 8px; margin-top: 15px; padding: 15px; background-color: #18181b; font-family: Arial, sans-serif; color: #ffffff; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } .autoplay-settings-container h2 { margin: 0 0 15px 0; color: #8257e6; font-size: 16px; font-weight: bold; } .settings-row { display: flex; justify-content: space-between; } .settings-column { width: 48%; } .setting-group { margin-bottom: 10px; } .setting-group label { display: block; margin-bottom: 5px; font-size: 14px; color: #a0a0a0; } .setting-group input { width: 100%; padding: 8px; border: 1px solid #3a3a3a; border-radius: 4px; font-size: 14px; background-color: #27272a; color: #ffffff; transition: border-color 0.3s, box-shadow 0.3s; } .setting-group input:focus { outline: none; border-color: #8257e6; box-shadow: 0 0 5px rgba(130, 87, 230, 0.5); } .setting-group input::placeholder { color: #6b7280; } `; document.head.appendChild(style); const container = document.createElement("div"); container.classList.add("autoplay-settings-container"); container.innerHTML = `