您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
redirects imgur <img> tags to a randomly selected rimgo instance
当前为
// ==UserScript== // @name imgur to rimgo image redirector // @namespace http://tampermonkey.net/ // @version 2025-10-01-v2 // @description redirects imgur <img> tags to a randomly selected rimgo instance // @author infinitysnapz // @match *://*/* // @icon https://www.google.com/s2/favicons?sz=64&domain=imgur.com // @license MIT; http://opensource.org/licenses/MIT // @grant GM_xmlhttpRequest // ==/UserScript== // based on: //Imgur to Rimgo redirect v0.1.4 by 0b9 //https://gist.github.com/wont-work/e1f00fcc6c44b05a312573379b649afa#file-free-overjoyed-anywhere-you-go-user-js by kopper (function() { 'use strict'; const apiUrl = 'https://rimgo.codeberg.page/api.json'; const instancediscovery = 'https://rimgo.codeberg.page'; var eligible = {}; var broken = [ "rimgo.proxik.cloud", "imgur.010032.xyz", "rimgo.aketawi.space", "projectsegfau.lt", "rimgo.darkness.services", "rimgo.totaldarkness.net", "rmgur.com", "rimgo.quantenzitrone.eu", "rimgo.frylo.net", "r.opnxng.com", //has anubis check "imgur.artemislena.eu", //has anubis check "rimgo.fascinated.cc", "rimgo.reallyaweso.me", "rimgo.thebunny.zone", "rimgo.bloat.cat", //has anubis check "imgur.nerdvpn.de" ];// soo many broken instances wtf const generateHash = (string) => { // hash, to allow us to cache images easier and reduce load on let hash = 0; for (const char of string) { hash = (hash << 5) - hash + char.charCodeAt(0); hash |= 0; // Constrain to 32bit integer } return hash; }; const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { walk(node); } } }); /** * @param {Node} root */ function walk(root) { if (!root.ownerDocument) throw "assertion falied: no owner document"; const walker = root.ownerDocument.createNodeIterator( root, NodeFilter.SHOW_ELEMENT, (node) => { if (node.nodeType == Node.ELEMENT_NODE && node.shadowRoot) {return NodeFilter.FILTER_ACCEPT}; if (node.nodeName == "STYLE" || node.nodeName == "SCRIPT") {return NodeFilter.FILTER_REJECT}; if (node.nodeName == "IMG"){return NodeFilter.FILTER_ACCEPT}; return NodeFilter.FILTER_SKIP; }); /** @type {Node|null} */let node; node = walker.nextNode(); while ((node = walker.nextNode())) { if (node.shadowRoot) { for (const child of node.shadowRoot.children) { if (child.nodeName == "STYLE" || child.nodeName == "SCRIPT") continue; walk(child); } observer.observe(node.shadowRoot, observerConfig); continue; }; if (!node.nodeName == "IMG") continue; redirectImg(node); } } const observerConfig = { childList: true, subtree: true, }; const redirectImg = (elem) => { const imgsrc = elem.src if (/https?:\/\/(\w+\.)?imgur.com\/(\w*)+(\.[a-zA-Z]{3,4})/.test(imgsrc)){ const path = imgsrc.substring(imgsrc.indexOf("/", 8)); const instanceUrl = eligible[Math.abs(generateHash(path) % eligible.length)].url const newUrl = `${instanceUrl}/${path.startsWith("/") ? path.slice(1) : path}`; elem.src = newUrl; }; }; GM_xmlhttpRequest({ method: "GET", url: apiUrl, onload: function (response) { try { const data = JSON.parse(response.responseText); eligible = data.clearnet.filter(inst => inst.note.includes("✅ Data not collected")); eligible = eligible.filter(inst => !(new RegExp( '\\b' + broken.join('\\b|\\b') + '\\b') ).test(inst.url) ); console.log(eligible) walk(document.body) observer.observe(document.body, observerConfig); } catch (e) { console.error("JSON parsing failed, no image redirecting will occur.", e); } }, onerror: function (err) { console.error("Request failed, no image redirecting will occur.", err); } }); })();