Greasy Fork is available in English.
Forces English on esologs.com, redirects locale subdomains (e.g., ru.esologs.com) to esologs.com, auto-presses "Translate" button, and replaces character names with account names
当前为
// ==UserScript==
// @name Show account names (all locales) + Force English + Auto-press Translate + De-locale redirect
// @namespace io.inp
// @match https://*.esologs.com/*
// @grant none
// @version 1.6
// @author Xandaros (tweaked by Kwiebe-Kwibus)
// @license BSD-2-Clause
// @run-at document-start
// @description Forces English on esologs.com, redirects locale subdomains (e.g., ru.esologs.com) to esologs.com, auto-presses "Translate" button, and replaces character names with account names
// ==/UserScript==
(function () {
"use strict";
// --- 0) If on a locale subdomain (e.g., ru.esologs.com), redirect to the root domain (esologs.com) ---
(function redirectLocaleSubdomain() {
try {
const host = location.hostname; // e.g., ru.esologs.com
const m = host.match(/^([a-z]{2})\.esologs\.com$/i);
// Redirect any 2-letter locale (ru, de, fr, etc.) EXCEPT "en" (just in case)
if (m && m[1].toLowerCase() !== "en") {
const targetHost = "esologs.com"; // user explicitly asked for root, not www
const newUrl = location.protocol + "//" + targetHost + location.pathname + location.search + location.hash;
// Use replace() to avoid back button ping-pong
location.replace(newUrl);
return; // stop running rest on this page; the new page will run the script again
}
} catch (_) {}
})();
// --- 1) Force site language to English (works on esologs.com & subdomains) ---
(function ensureEnglish() {
try {
const desired = "en";
const hasEnCookie = (name) =>
document.cookie.split(";").some((c) => c.trim().startsWith(name + "=en"));
const setCookie = (name, value, domain) => {
const maxAge = 60 * 60 * 24 * 365; // 1 year
const parts = [
`${name}=${value}`,
"path=/",
`max-age=${maxAge}`,
"samesite=lax",
"secure",
];
if (domain) parts.push(`domain=${domain}`);
document.cookie = parts.join("; ");
};
const needSet =
!hasEnCookie("NEXT_LOCALE") ||
(typeof localStorage !== "undefined" &&
(localStorage.getItem("NEXT_LOCALE") !== desired ||
localStorage.getItem("locale") !== desired ||
localStorage.getItem("language") !== desired));
if (needSet) {
const host = location.hostname;
// Root cookie so it applies on all subdomains too
setCookie("NEXT_LOCALE", desired, ".esologs.com");
// Also set on current host in case root is blocked for any reason
setCookie("NEXT_LOCALE", desired, undefined);
try {
localStorage.setItem("NEXT_LOCALE", desired);
localStorage.setItem("locale", desired);
localStorage.setItem("language", desired);
} catch (_) {}
try {
sessionStorage.setItem("NEXT_LOCALE", desired);
} catch (_) {}
if (!sessionStorage.getItem("esologs_forced_en_reloaded")) {
sessionStorage.setItem("esologs_forced_en_reloaded", "1");
location.reload();
}
}
} catch (_) {}
})();
// --- 2) Auto-press the "Translate"/"Show Original" button ---
function autoPressTranslate() {
function clickButton() {
const btn = document.querySelector("input.translator-button");
if (btn && btn.value && /Show Original|Translate/i.test(btn.value)) {
btn.click();
return true;
}
return false;
}
// Try a few times (button appears late)
let tries = 0;
const maxTries = 20;
const timer = setInterval(() => {
tries++;
if (clickButton() || tries >= maxTries) clearInterval(timer);
}, 500);
// Watch for future appearances
const mo = new MutationObserver(() => clickButton());
const startObs = () => {
if (document.body) {
mo.observe(document.body, { childList: true, subtree: true });
} else {
requestAnimationFrame(startObs);
}
};
startObs();
}
// --- 3) Replace character names with account display names ---
function replaceNames(nodeOr$) {
const $root = window.jQuery ? window.jQuery(nodeOr$) : null;
const nodeList = $root
? $root.contents().toArray()
: nodeOr$?.childNodes
? Array.from(nodeOr$.childNodes)
: [];
for (const inner of nodeList) {
if (!inner) continue;
if (inner.nodeType === Node.TEXT_NODE && inner.parentElement) {
const tag = inner.parentElement.tagName;
if (["SCRIPT", "STYLE", "TEXTAREA", "INPUT"].includes(tag)) continue;
const txt = inner.textContent;
if (!txt || !Array.isArray(window.players)) continue;
let out = txt;
for (const player of window.players) {
if (!player) continue;
if (player.type === "NPC" || player.anonymous) continue;
if (!player.name || !player.displayName) continue;
if (out.includes(player.displayName)) continue;
out = out.replaceAll(player.name, player.displayName);
}
if (out !== txt) inner.textContent = out;
}
if (inner.childNodes && inner.childNodes.length) replaceNames(inner);
}
}
function initWhenReady() {
if (Array.isArray(window.players) && window.players.length > 0) {
replaceNames(document.documentElement);
const obs = new MutationObserver((mutations) => {
for (const m of mutations) {
if (m.type === "childList") {
m.addedNodes.forEach((n) => replaceNames(n));
} else if (m.type === "characterData" && m.target?.parentElement) {
replaceNames(m.target.parentElement);
}
}
});
obs.observe(document.documentElement, {
childList: true,
characterData: true,
subtree: true,
});
return true;
}
return false;
}
function startNameReplacement() {
if (!initWhenReady()) {
const maxTries = 30;
let tries = 0;
const timer = setInterval(() => {
tries++;
if (initWhenReady() || tries >= maxTries) clearInterval(timer);
}, 500);
}
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
autoPressTranslate();
startNameReplacement();
}, { once: true });
} else {
autoPressTranslate();
startNameReplacement();
}
})();