Bypass the new external link warning on SimpCity
// ==UserScript==
// @name SimpCity Re-re-direct
// @namespace https://github.com/chuckmingus
// @version 1.1.2
// @description Bypass the new external link warning on SimpCity
// @author chuckmingus
// @icon https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/cobalt.png
// @license MIT
// @match https://simpcity.cr/*
// @match https://simpcity.su/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
"use strict";
// fallback for when we are already on a redirect page
if (window.location.href.includes('/redirect/')) {
const target = document.querySelector(".simpLinkProxy-targetLink").href;
window.location.replace(target)
}
// otherwise try to modify links as they are added to the page
function decodeTarget(str) {
try {
const normalized = str.replace(/-/g, '+').replace(/_/g, '/');
return atob(normalized);
} catch (e) {
console.error("[SimpCity Re-re-direct] Failed to decode base64:", str, e);
return null;
}
}
function processLinks() {
const links = document.querySelectorAll('a[href*="/redirect/?to="]:not([data-bypassed])');
links.forEach(link => {
link.dataset.bypassed = "true";
try {
const url = new URL(link.href, window.location.origin);
let targetUrl = url.searchParams.get("to");
const mode = url.searchParams.get("m");
if (targetUrl && mode === "b64") {
targetUrl = decodeTarget(targetUrl);
}
if (targetUrl) {
link.href = targetUrl;
link.removeAttribute('data-proxy-handler');
link.removeAttribute('data-blank-handler');
link.removeAttribute('data-proxy-href');
}
} catch (e) {
// Silently fail for invalid URLs
}
});
}
// keep watch for loaded links
const observer = new MutationObserver(() => {
processLinks();
});
observer.observe(document.documentElement, {
childList: true,
subtree: true
});
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', processLinks);
} else {
processLinks();
}
})();