Sleazy Fork is available in English.
Bypass the new external link warning on SimpCity
// ==UserScript==
// @name SimpCity Re-re-direct
// @namespace https://github.com/chuckmingus
// @version 1.2.0
// @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.cr/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
"use strict";
function isValidUrl(str) {
try {
const parsed = new URL(str);
return parsed.protocol === "http:" || parsed.protocol === "https:";
} catch {
return false;
}
}
function decodeTarget(str) {
try {
let normalized = str.replace(/-/g, "+").replace(/_/g, "/");
while (normalized.length % 4 !== 0) {
normalized += "=";
}
const binary = atob(normalized);
const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
} catch (e) {
console.error("[SimpCity Re-re-direct] Failed to decode base64:", str, e);
return null;
}
}
function extractTargetFromUrl(href) {
try {
const url = new URL(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 && isValidUrl(targetUrl)) {
return targetUrl;
}
} catch (e) {
// Silently fail for invalid URLs
}
return null;
}
// fallback for when we are already on a redirect page
if (window.location.pathname.includes("/redirect/")) {
const immediateTarget = extractTargetFromUrl(window.location.href);
if (immediateTarget) {
window.location.replace(immediateTarget);
return;
}
// wait for DOM if parameters weren't available in search string
document.addEventListener("DOMContentLoaded", () => {
const link = document.querySelector(".simpLinkProxy-targetLink");
if (link && link.href && isValidUrl(link.href)) {
window.location.replace(link.href);
}
});
}
function processSingleLink(link) {
link.dataset.bypassed = "true";
const targetUrl = extractTargetFromUrl(link.href);
if (targetUrl) {
link.href = targetUrl;
link.rel = "noopener noreferrer";
link.removeAttribute("data-proxy-handler");
link.removeAttribute("data-blank-handler");
link.removeAttribute("data-proxy-href");
}
}
function processLinks() {
const links = document.querySelectorAll(
'a[href*="/redirect/?to="]:not([data-bypassed])'
);
links.forEach(processSingleLink);
}
// intercept click events as a fallback
document.addEventListener(
"click",
(e) => {
const link = e.target.closest('a[href*="/redirect/?to="]');
if (link && !link.dataset.bypassed) {
processSingleLink(link);
}
},
true
);
let isScheduled = false;
function scheduleProcessLinks() {
if (isScheduled) return;
isScheduled = true;
requestAnimationFrame(() => {
processLinks();
isScheduled = false;
});
}
const observer = new MutationObserver((mutations) => {
const hasAddedNodes = mutations.some((m) => m.addedNodes.length > 0);
if (hasAddedNodes) {
scheduleProcessLinks();
}
});
observer.observe(document.documentElement, {
childList: true,
subtree: true,
});
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", processLinks);
} else {
processLinks();
}
})();