您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Redirect social media to privacy frontends, remember mirror, switch instances with button and Ctrl+Shift+R hotkey. SponsorBlock removed. Sticky redirects enabled.
// ==UserScript== // @name Ultimate Instance Redirect // @namespace violentmonkey.ultimate.redirect // @version 2.6 // @description Redirect social media to privacy frontends, remember mirror, switch instances with button and Ctrl+Shift+R hotkey. SponsorBlock removed. Sticky redirects enabled. // @author Amil John // @match *://*reddit.com/* // @match *://*.reddit.com/* // @match *://*twitter.com/* // @match *://*.twitter.com/* // @match *://*x.com/* // @match *://*.x.com/* // @match *://*/* // @grant none // @license CC-BY-NC-4.0 // @run-at document-start // ==/UserScript== (function () { 'use strict'; const STORAGE_KEY_PREFIX = "preferredFrontend:"; const serviceRedirects = [ { name: "Reddit", match: /(?:^|\.)reddit\.com$/, storageKey: STORAGE_KEY_PREFIX + "reddit", frontends: [ "https://redlib.catsarch.com", "https://redlib.perennialte.ch", "https://redlib.r4fo.com", "https://redlib.privacyredirect.com", "https://libreddit.diffraction.dev", "https://redlib.privadency.com", "https://redlib.scanash.xyz" ] }, { name: "YouTube", match: /(?:^|\.)youtube\.com$/, storageKey: STORAGE_KEY_PREFIX + "youtube", frontends: [ "https://yewtu.be", "https://inv.nadeko.net", ] }, { name: "Twitter", match: /(?:^|\.)twitter\.com$|(?:^|\.)x\.com$/, storageKey: STORAGE_KEY_PREFIX + "twitter", frontends: [ "https://nitter.net", "https://nitter.poast.org", ] } ]; const currentHost = window.location.hostname; function getCurrentService() { return serviceRedirects.find(service => service.match.test(currentHost)); } function getFrontendByHost(hostname) { return serviceRedirects.find(service => service.frontends.some(url => new URL(url).hostname === hostname) ); } function getStoredFrontend(service) { const url = localStorage.getItem(service.storageKey); return url && service.frontends.includes(url) ? new URL(url) : null; } function setStoredFrontend(service, frontendURL) { localStorage.setItem(service.storageKey, frontendURL.toString()); } function getRandomFrontend(service, excludeHostname = null) { const filtered = excludeHostname ? service.frontends.filter(u => new URL(u).hostname !== excludeHostname) : [...service.frontends]; return new URL(filtered[Math.floor(Math.random() * filtered.length)]); } function switchFrontend() { const service = getFrontendByHost(currentHost); if (!service) return; const newFrontend = getRandomFrontend(service, currentHost); setStoredFrontend(service, newFrontend.toString()); const newUrl = newFrontend + window.location.pathname + window.location.search + window.location.hash; window.location.href = newUrl; } function createSwitcherButton() { const service = getFrontendByHost(currentHost); if (!service) return; const btn = document.createElement("button"); btn.innerText = `🔄 Switch Instance (Ctrl + Shift + R)`; Object.assign(btn.style, { position: "fixed", bottom: "12px", right: "12px", zIndex: "99999", padding: "10px 14px", backgroundColor: "#222", color: "#fff", border: "none", borderRadius: "6px", cursor: "pointer", fontWeight: "bold", fontSize: "14px", boxShadow: "0 2px 8px rgba(0,0,0,0.3)" }); btn.addEventListener("click", switchFrontend); const tryInsert = () => (document.body || document.documentElement).appendChild(btn); if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", tryInsert); } else { tryInsert(); } } function addHotkey() { document.addEventListener("keydown", function (e) { const service = getFrontendByHost(currentHost); if (e.ctrlKey && e.shiftKey && e.code === "KeyR" && service) { e.preventDefault(); switchFrontend(); } }); } function rewriteLinks() { document.querySelectorAll("a[href]").forEach(link => { try { const url = new URL(link.href); const service = serviceRedirects.find(svc => svc.match.test(url.hostname)); if (service) { const saved = getStoredFrontend(service); if (saved) { url.hostname = new URL(saved).hostname; url.protocol = "https:"; link.href = url.toString(); } } } catch (_) {} }); } function redirectIfOnService() { const service = getCurrentService(); if (!service) return; const saved = getStoredFrontend(service); const redirectTarget = saved || getRandomFrontend(service); if (!saved) { setStoredFrontend(service, redirectTarget.toString()); } const fullURL = redirectTarget + window.location.pathname + window.location.search + window.location.hash; window.location.replace(fullURL); } function initSponsorBlock() { const categories = ["sponsor", "selfpromo", "interaction", "intro", "outro", "preview", "music_offtopic", "exclusive_access"]; const skipSegments = new Map(); const muteSegments = new Map(); const params = new URLSearchParams(window.location.search); const videoID = params.get("v"); if (!videoID) return; function tryInject() { const video = document.querySelector("video"); if (!video) return; fetch(`https://sponsor.ajay.app/api/skipSegments?videoID=${videoID}&categories=${JSON.stringify(categories)}`) .then(res => res.json()) .then(data => { data.forEach(item => { const [start, end] = item.segment; if (item.actionType === "skip") skipSegments.set(start, end); else if (item.actionType === "mute") muteSegments.set(start, end); }); video.addEventListener("timeupdate", () => { const t = video.currentTime; for (const [start, end] of skipSegments) { if (t >= start && t < end) { video.currentTime = end; skipSegments.delete(start); } } for (const [start, end] of muteSegments) { video.muted = (t >= start && t < end); } }); }); } const observer = new MutationObserver(() => { if (document.querySelector("video")) { tryInject(); observer.disconnect(); } }); observer.observe(document, { childList: true, subtree: true }); let retryCount = 0; const fallback = setInterval(() => { if (++retryCount > 30) return clearInterval(fallback); if (document.querySelector("video")) { tryInject(); clearInterval(fallback); } }, 500); } // === INIT === const matchService = getCurrentService(); if (matchService) { redirectIfOnService(); return; } createSwitcherButton(); addHotkey(); rewriteLinks(); new MutationObserver(rewriteLinks).observe(document, { childList: true, subtree: true }); window.addEventListener("load", initSponsorBlock); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址