您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds chat translation buttons
- // ==UserScript==
- // @name Torn Translator (Chat Fix)
- // @namespace http://tampermonkey.net/
- // @version 0.1
- // @description Adds chat translation buttons
- // @author JeffBezas
- // @match https://www.torn.com/*
- // @grant GM_xmlhttpRequest
- // @grant GM_addStyle
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_setClipboard
- // @connect translate.googleapis.com
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- // Load saved position or set default
- let posX = GM_getValue("translatorPosX", 50);
- let posY = GM_getValue("translatorPosY", 50);
- // Add custom styles
- GM_addStyle(`
- #translator-container {
- position: fixed;
- left: ${posX}px;
- top: ${posY}px;
- width: 300px;
- background: rgba(0, 0, 0, 0.8);
- padding: 10px;
- border-radius: 5px;
- color: white;
- font-size: 14px;
- z-index: 9999;
- cursor: grab;
- }
- #translator-header {
- background: rgba(255, 255, 255, 0.2);
- padding: 5px;
- text-align: center;
- font-weight: bold;
- cursor: grab;
- user-select: none;
- }
- #translator-container select, #translator-container textarea, #translator-container button {
- width: 100%;
- margin-top: 5px;
- }
- #translator-container textarea {
- height: 50px;
- }
- #translated-text {
- margin-top: 10px;
- background: white;
- color: black;
- padding: 5px;
- border-radius: 3px;
- }
- .translate-btn {
- margin-left: 5px;
- background: #4CAF50;
- color: white;
- border: none;
- padding: 2px 5px;
- font-size: 12px;
- cursor: pointer;
- border-radius: 3px;
- }
- .translate-btn:hover {
- background: #45a049;
- }
- `);
- // Create the translation UI
- const translatorDiv = document.createElement('div');
- translatorDiv.id = 'translator-container';
- translatorDiv.innerHTML = `
- <div id="translator-header">Drag Me</div>
- <label>Translate from:</label>
- <select id="sourceLang">
- <option value="auto">Auto</option>
- <option value="en">English</option>
- <option value="es">Spanish</option>
- <option value="fr">French</option>
- <option value="de">German</option>
- </select>
- <label>To:</label>
- <select id="targetLang">
- <option value="en">English</option>
- <option value="es">Spanish</option>
- <option value="fr">French</option>
- <option value="de">German</option>
- </select>
- <textarea id="textToTranslate" placeholder="Enter text here..."></textarea>
- <div style="display: flex; justify-content: space-between;">
- <button id="copyText">📋 Copy</button>
- <button id="pasteText">📥 Paste</button>
- </div>
- <div id="translated-text">Translation will appear here...</div>
- `;
- document.body.appendChild(translatorDiv);
- // Enable dragging
- let isDragging = false, startX, startY;
- document.getElementById('translator-header').addEventListener('mousedown', function(e) {
- isDragging = true;
- startX = e.clientX - translatorDiv.offsetLeft;
- startY = e.clientY - translatorDiv.offsetTop;
- translatorDiv.style.cursor = "grabbing";
- });
- document.addEventListener('mousemove', function(e) {
- if (isDragging) {
- let newX = e.clientX - startX;
- let newY = e.clientY - startY;
- translatorDiv.style.left = newX + "px";
- translatorDiv.style.top = newY + "px";
- }
- });
- document.addEventListener('mouseup', function() {
- if (isDragging) {
- GM_setValue("translatorPosX", translatorDiv.offsetLeft);
- GM_setValue("translatorPosY", translatorDiv.offsetTop);
- isDragging = false;
- translatorDiv.style.cursor = "grab";
- }
- });
- // Copy to clipboard
- document.getElementById('copyText').addEventListener('click', function() {
- const translatedText = document.getElementById('translated-text').innerText;
- GM_setClipboard(translatedText);
- });
- // Paste from clipboard
- document.getElementById('pasteText').addEventListener('click', function() {
- navigator.clipboard.readText().then(text => {
- document.getElementById('textToTranslate').value = text;
- translateText(text);
- }).catch(err => {
- console.error("Failed to read clipboard: ", err);
- });
- });
- // Auto-translate on input
- let timeout;
- document.getElementById('textToTranslate').addEventListener('input', function() {
- clearTimeout(timeout);
- timeout = setTimeout(() => {
- const text = document.getElementById('textToTranslate').value;
- translateText(text);
- }, 500);
- });
- // Function to fetch translation
- function translateText(text) {
- const sourceLang = document.getElementById('sourceLang').value;
- const targetLang = document.getElementById('targetLang').value;
- if (text.trim() === "") {
- document.getElementById('translated-text').innerText = "Translation will appear here...";
- return;
- }
- const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sourceLang}&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}`;
- GM_xmlhttpRequest({
- method: "GET",
- url: url,
- onload: function(response) {
- try {
- const result = JSON.parse(response.responseText);
- const translatedText = result[0].map(item => item[0]).join("");
- document.getElementById('translated-text').innerText = translatedText;
- } catch (e) {
- document.getElementById('translated-text').innerText = "Translation error.";
- }
- }
- });
- }
- // Add translation buttons to chat messages
- function addTranslationButtons() {
- document.querySelectorAll('.chat-box-message__message___SldE8').forEach(message => {
- if (!message.querySelector('.translate-btn')) {
- const translateBtn = document.createElement('button');
- translateBtn.innerText = "Translate";
- translateBtn.classList.add('translate-btn');
- // Get clean message text (remove button and emoji)
- translateBtn.addEventListener('click', function() {
- const text = message.querySelector('.text-message___gcG6e')?.innerText.trim() || ""; // Extract only message text
- document.getElementById('textToTranslate').value = text;
- translateText(text);
- });
- message.appendChild(translateBtn);
- }
- });
- }
- // Observe chat for new messages
- const chatObserver = new MutationObserver(addTranslationButtons);
- chatObserver.observe(document.body, { childList: true, subtree: true });
- })();