您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Full pirate conversion: words, money, dates, times, numbers, and context-aware interjections
// ==UserScript== // @name ZedCity Pirate Immersion Mega Ultimate v6 // @namespace http://zed.city/ // @version 6.0 // @description Full pirate conversion: words, money, dates, times, numbers, and context-aware interjections // @match *://*.zed.city/* // @grant none // ==/UserScript== (function() { 'use strict'; // --- Word Translations --- const TRANSLATIONS = [ ["\\bhello\\b", "ahoy"], ["\\bhi\\b", "ahoy"], ["\\bhey\\b", "ahoy"], ["\\bmy\\b", "me"], ["\\byour\\b", "yer"], ["\\byou\\b", "ye"], ["\\bfriend\\b", "matey"], ["\\bfriends\\b", "crew"], ["\\bman\\b", "buccaneer"], ["\\bwoman\\b", "wench"], ["\\bboss\\b", "cap'n"], ["\\bmoney\\b", "booty"], ["\\bgold\\b", "booty"], ["\\btown\\b", "port"], ["\\bthe\\b", "th'"], ["\\bis\\b", "be"], ["\\bare\\b", "be"], ["\\bam\\b", "be"], ["\\bof\\b", "o'"], ["\\bfor\\b", "fer"], ["\\bto\\b", "t'"], ["\\bthis\\b", "this 'ere"], ["\\bthat\\b", "that 'ere"], ["\\bno\\b", "nay"], ["\\byes\\b", "aye"], ["\\bdrink\\b", "grog"], ["\\bdrinks\\b", "grog"], ["\\bsea\\b", "briny deep"], ["\\bfood\\b", "grub"], ["\\border\\b", "summon"], ["\\bkill\\b", "keelhaul"], ["\\bplease\\b", "be so kind, matey"], ["\\bking\\b", "pirate king"], ["\\bqueen\\b", "sea queen"], ["\\bcaptain\\b", "cap'n"], ["\\bfight\\b", "duel"], ["\\btreasure\\b", "booty"], ["\\bwork\\b", "plunder"], ["\\bsailor\\b", "sea dog"], ["\\bship\\b", "galleon"], ["\\bhome\\b", "harbor"] ]; // --- Days & Months --- const PIRATE_DAYS = { "Monday": "Moonday", "Tuesday": "Twosday", "Wednesday": "Wodensday", "Thursday": "Thorsday", "Friday": "Fryday", "Saturday": "Sat’rday", "Sunday": "Sun’s Day" }; const PIRATE_MONTHS = { "January": "JanuARRy", "February": "FebruARRy", "March": "Marrrch", "April": "ApRRil", "May": "May", "June": "June", "July": "July", "August": "AugARRst", "September": "SeptembARR", "October": "OctobARR", "November": "NovembARR", "December": "DecembARR" }; const PIRATE_TIMES = [ [/\bAM\b/g, "bells before noon"], [/\bPM\b/g, "bells after noon"], [/\bmidnight\b/gi, "the witchin’ hour"], [/\bnoon\b/gi, "high sun"], [/\byesterday\b/gi, "yestermorn"], [/\btomorrow\b/gi, "on the morrow"], [/\b(\d+)\s+hours?\b/gi, "$1 bells"], [/\b(\d+)\s+minutes?\b/gi, "$1 minutes"], [/\b(\d+)\s+seconds?\b/gi, "$1 heartbeats"], [/\b(\d+)\s+days?\b/gi, "$1 suns"], [/\bago\b/gi, "aft"] ]; // --- Compile Regex --- const compiled = TRANSLATIONS.map(([pat, repl]) => ({ re: new RegExp(pat, "gi"), repl })); // --- Case Preservation --- function preserveCaseReplace(original, replacement) { if (original === original.toUpperCase()) return replacement.toUpperCase(); if (original[0] === original[0].toUpperCase()) { return replacement.charAt(0).toUpperCase() + replacement.slice(1); } return replacement; } // --- Money, Dates, Times --- function pirateNumbersAndMoney(str) { str = str.replace(/([$£€¥]\s?\d[\d,]*(\.\d+)?)/g, (match) => { return match.replace(/[$£€¥]/, "").trim() + " pieces o’ eight"; }); str = str.replace(/\bUSD\s?(\d[\d,]*)/gi, "$1 pieces o’ eight"); for (let day in PIRATE_DAYS) str = str.replace(new RegExp("\\b" + day + "\\b", "g"), PIRATE_DAYS[day]); for (let month in PIRATE_MONTHS) str = str.replace(new RegExp("\\b" + month + "\\b", "g"), PIRATE_MONTHS[month]); str = str.replace(/\b(\d{4})\b/g, "Year o’ our Lord $1"); PIRATE_TIMES.forEach(([re, repl]) => str = str.replace(re, repl)); return str; } // --- Nautical Conversions --- function pirateMeasurements(str) { // Distances str = str.replace(/(\d+\.?\d*)\s?m\b/g, (_, n) => ((parseFloat(n)/1.8288).toFixed(1) + " fathoms")); str = str.replace(/(\d+\.?\d*)\s?km\b/g, (_, n) => ((parseFloat(n)/1.852).toFixed(1) + " nautical miles")); // Weights str = str.replace(/(\d+\.?\d*)\s?kg\b/g, (_, n) => ((parseFloat(n)/159).toFixed(1) + " barrels")); str = str.replace(/(\d+\.?\d*)\s?t\b/g, (_, n) => (n + " burdens")); // Speeds str = str.replace(/(\d+\.?\d*)\s?m\/s\b/g, (_, n) => ((parseFloat(n)*1.944).toFixed(1) + " knots")); return str; } // --- Context-Aware Pirate Interjections --- function getContextAwareInterjection(str) { const moneyKeywords = /\b(booty|gold|money|treasure|coins|pieces o’ eight)\b/i; const timeKeywords = /\b(hour|time|minute|second|bell|day|morning|noon|midnight|tide)\b/i; const dangerKeywords = /\b(danger|fight|battle|attack|kill|enemy|cannon|keelhaul)\b/i; if (moneyKeywords.test(str)) { return ["Booty ahoy!", "Pieces o’ eight!", "Gold in me eyes!", "Plunder time!", "Riches for all!"][Math.floor(Math.random()*5)]; } else if (timeKeywords.test(str)) { return ["Mark the bell!", "Batten down the hatches!", "High noon approaches!", "The tide waits for no one!", "Heave ho!"][Math.floor(Math.random()*5)]; } else if (dangerKeywords.test(str)) { return ["Fire the cannons!", "To Davy Jones’ locker!", "Scurvy dogs ahead!", "Ready the cutlasses!", "Brace yerselves!"][Math.floor(Math.random()*5)]; } else { return ["Arr!", "Yo-ho-ho!", "Shiver me timbers!", "Avast!", "Blimey!", "By Blackbeard's beard!", "Land ho!", "Splice the mainbrace!"][Math.floor(Math.random()*8)]; } } // --- Full Translation --- function translateString(str) { let result = str; compiled.forEach(({ re, repl }) => result = result.replace(re, (m) => preserveCaseReplace(m, repl))); result = pirateNumbersAndMoney(result); result = pirateMeasurements(result); if (Math.random() < 0.10) result += " " + getContextAwareInterjection(result); return result; } // --- Node Translators --- function translateTextNode(node) { if (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim()) node.nodeValue = translateString(node.nodeValue); } function translateElementAttributes(el) { ["title", "alt", "placeholder", "aria-label"].forEach(attr => { if (el.hasAttribute && el.hasAttribute(attr)) { const val = el.getAttribute(attr); if (val && val.trim()) el.setAttribute(attr, translateString(val)); } }); if ((el.tagName === "INPUT" || el.tagName === "TEXTAREA") && el.type !== "password") { if (el.value && el.value.trim() && !el.matches(":focus")) el.value = translateString(el.value); } } function walkAndTranslate(root) { const walker = document.createTreeWalker( root, NodeFilter.SHOW_TEXT, { acceptNode: (node) => { if (!node.parentNode) return NodeFilter.FILTER_REJECT; const style = window.getComputedStyle(node.parentNode); if (style && style.display !== "none" && style.visibility !== "hidden") return NodeFilter.FILTER_ACCEPT; return NodeFilter.FILTER_REJECT; } }, false ); let node; while ((node = walker.nextNode())) translateTextNode(node); root.querySelectorAll("*").forEach(translateElementAttributes); } // --- Initial Translation --- translateElementAttributes(document.body); walkAndTranslate(document.body); // --- Observe for Dynamic Content --- const observer = new MutationObserver(mutations => { mutations.forEach(m => { if (m.addedNodes) m.addedNodes.forEach(n => { if (n.nodeType === Node.ELEMENT_NODE) { translateElementAttributes(n); walkAndTranslate(n); } else if (n.nodeType === Node.TEXT_NODE) { translateTextNode(n); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })();