// ==UserScript==
// @name TMGeneralTranslation
// @namespace https://trophymanager.com/
// @version 1.0.9
// @author 提瓦特元素反应(https://trophymanager.com/club/4731723/)
// @description 通过翻译服务器对游戏内球员名字进行汉化
// @license MIT
// @match https://trophymanager.com/*
// @grant GM_xmlhttpRequest
// @run-at document-end
// ==/UserScript==
var VERSION = "1.0.9"
var DEBUG_MODE = true;
var BACK_END = "http://trans.tm.kit.ga";
var LOCAL = [
"/national-teams/cn/",
"flag-img-cn",
"/pics/flags/gradient/cn.png",
"/national-teams/hk/",
"flag-img-hk",
"/pics/flags/gradient/hk.png",
"/national-teams/jp/",
"flag-img-jp",
"/pics/flags/gradient/jp.png",
"/national-teams/tw/",
"flag-img-tw",
"/pics/flags/gradient/tw.png",
]
function isLocal(str){
for(let i = 0; i < LOCAL.length; i++){
if(str.includes(LOCAL[i])){
return true;
}
}
return false;
}
// 函数用于发送请求并处理响应
function translateNumbers(players, callback, update) {
players = players.filter(item => item.ID !== null && item.English !== null && item.English !== undefined && !item.English.includes('@'));
let copyPlayers = [];
for(let i = 0; i < players.length; i++){
let player = {}
if(filterCosName(players[i].English) !== ''){
player.English = filterName(players[i].English);
} else {
player.English = players[i].English;
}
player.ID = players[i].ID
copyPlayers.push(player);
}
// 将输入的整数数组转换为JSON字符串
const jsonData = JSON.stringify({"version": VERSION, "data": copyPlayers, "update":update});
console.log(jsonData);
// 发送 POST 请求
GM_xmlhttpRequest({
method: "POST",
url: BACK_END + "/translate",
data: jsonData,
headers: {
"Content-Type": "application/json"
},
onload: function(response) {
// 解析返回的 JSON 数据
const responseData = JSON.parse(response.responseText);
// 获取翻译结果数组
callback(responseData);
}
});
}
function filterName(name){
if(name.split('\'').length === 3){
return name.split('\'')[0] + name.split('\'')[2];
}
return name;
}
function filterCosName(name){
if(name.split('\'').length === 3){
return name.split('\'')[1];
}
return '';
}
// 球员详情
(function() {
'use strict';
if (window.location.pathname === '/players' || window.location.pathname === '/players/' || !window.location.pathname.includes('/players/')) {
return;
}
// 检查国籍
if(!isLocal(document.querySelector('.box_sub_header .country_link').getAttribute('href'))){
return;
}
// 查找包含 id 的元素
const element = document.querySelector('#change_player_link');
// 遍历每个元素并提取 id
var player = {};
if(element.getAttribute('onclick').split(',').length === 3 && element.getAttribute('onclick').split(',')[0].split('(').length === 2){
player.ID = parseInt(element.getAttribute('onclick').split(',')[0].split('(')[1]);
player.English = document.querySelector("div.large").querySelector("strong").textContent.split(". ")[1];
} else {
return;
}
// 找到具有 'large' 类的 <div>,然后选择第一个 <strong> 元素
var largeDiv = document.querySelector("div.large");
if (largeDiv) {
var strongElement = largeDiv.querySelector("strong");
if (strongElement) {
// 修改 <strong> 的文本内容
// 调用函数并传入整数数组作为参数
translateNumbers([player], function(translations) {
if(filterCosName(player.English) !== ''){
strongElement.textContent = '\'' + filterCosName(player.English) + '\' '+ translations[0].Chinese;
} else {
strongElement.textContent = translations[0].Chinese;
}
}, true);
}
}
})();
// 战术-列表
(function() {
'use strict';
if (!(window.location.pathname === '/tactics' || window.location.pathname === '/tactics/' || window.location.pathname === '/tactics/#')) {
return;
}
let translationsResult;
function modifyNamesAndExtractIdsForNames() {
console.log(document.querySelectorAll('.cond_order div[player_link]'));
var players = [];
document.querySelectorAll("span.player_name").forEach(element => {
var player = {};
// 检查国籍
let parent = element.parentElement;
if(parent.querySelectorAll('ib').length !== 0 && !isLocal(parent.querySelector('ib').getAttribute('class'))){
return;
}
player.English = element.textContent;
player.ID = parseInt(element.getAttribute("player_id"));
players.push(player);
});
document.querySelectorAll('.field_player_name').forEach(element => {
var player = {};
if (element.firstChild && element.firstChild.nodeType === Node.TEXT_NODE) {
player.English = element.firstChild.nodeValue;
}
// 检查国籍
if(element.querySelectorAll('ib').length !== 0 && !isLocal(element.querySelector('ib').getAttribute('class'))){
return;
}
const parentDiv = element.closest('.field_player');
if (parentDiv) {
player.ID = parseInt(parentDiv.getAttribute('player_id'));
}
players.push(player);
});
document.querySelectorAll('.bench_player_name').forEach(element => {
var player = {};
if (element.firstChild && element.firstChild.nodeType === Node.TEXT_NODE) {
player.English = element.firstChild.nodeValue;
}
// 检查国籍
if(element.querySelectorAll('ib').length !== 0 && !isLocal(element.querySelector('ib').getAttribute('class'))){
return;
}
const parentLi = element.closest('li.bench_player');
if (parentLi) {
player.ID = parseInt(parentLi.getAttribute('player_id'));
}
players.push(player);
});
translateNumbers(players, function(translations) {
translationsResult = translations;
document.querySelectorAll("span.player_name").forEach(element => {
translations.forEach(function(translation) {
if (translation.ID === parseInt(element.getAttribute("player_id"))) {
element.textContent = translation.Chinese;
}
})
});
document.querySelectorAll('.field_player_name').forEach(element => {
const parentDiv = element.closest('.field_player');
if (parentDiv) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(parentDiv.getAttribute('player_id'))) {
if (element.firstChild && element.firstChild.nodeType === Node.TEXT_NODE) {
element.firstChild.nodeValue = translation.Chinese;
}
}
})
}
});
document.querySelectorAll('.bench_player_name').forEach(element => {
const parentLi = element.closest('li.bench_player');
if (parentLi) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(parentLi.getAttribute('player_id'))) {
if (element.firstChild && element.firstChild.nodeType === Node.TEXT_NODE) {
element.firstChild.nodeValue = translation.Chinese;
}
}
})
}
});
document.querySelectorAll('.cond_order div[player_link]').forEach(element => {
translations.forEach(function(translation) {
if (translation.ID === parseInt(element.getAttribute('player_link'))) {
element.textContent = translation.Chinese;
}
})
});
}, true);
}
function modifyNamesForSubstitute() {
let translations = translationsResult;
document.querySelectorAll('.parm_select.player_select').forEach(element => {
translations.forEach(function(translation) {
if (translation.ID === parseInt(element.getAttribute('player_link'))) {
element.firstChild.nodeValue = translation.Chinese; // 修改第一个文本节点内容
}
})
});
}
// 监控特定元素并应用回调函数
function bindObserver(selector, callback) {
const elements = document.querySelectorAll(selector);
elements.forEach(element => {
// 创建一个 MutationObserver 实例并应用给定的回调
const observer = new MutationObserver(callback);
observer.observe(element, {
childList: true
});
});
}
// 处理 DOM 变化的函数
const handleMutations = mutations => {
mutations.forEach(mutation => {
// 检查新增的节点
mutation.addedNodes.forEach(node => {
if (node.id === 'popup_action' || node.matches && node.matches('#popup_action')) {
modifyNamesForSubstitute();
}
});
});
};
bindObserver('#tactics_list_list', modifyNamesAndExtractIdsForNames);
bindObserver('#cond_orders_list', modifyNamesAndExtractIdsForNames);
// 创建全局观察者来监控元素的删除和重建
const globalObserver = new MutationObserver(handleMutations);
globalObserver.observe(document.body, {
childList: true,
subtree: true
});
})();
// 球队 && 工资 && 联赛最佳/统计
(function() {
'use strict';
if (!(
window.location.pathname === '/players' || window.location.pathname === '/players/' ||
window.location.pathname === '/finances/wages' || window.location.pathname === '/finances/wages/' ||
window.location.pathname.includes('/league/team-of-the-round') ||
window.location.pathname.includes('/statistics/league') ||
window.location.pathname.includes('/club/')
)) {
return;
}
var players = [];
var links = [];
let checkDefault = window.location.pathname.includes('/club/') ? isLocal(document.querySelector(".box_sub_header a.country_link").getAttribute("href")) : true;
checkDefault = window.location.pathname.includes('/club/') ? document.querySelectorAll("a[league_link]").length == 0 : checkDefault;
console.log(checkDefault);
document.querySelectorAll("a[player_link]").forEach(function(element) {
var link = element;
// 检查国籍
if(true){
let checkFlag = false
let parent = element.parentElement;
parent.querySelectorAll(`img[src]`).forEach(function(img){
if(img.getAttribute("src").includes('/pics/flags/gradient/') && !isLocal(img.getAttribute("src"))){
checkFlag = true;
}
if(!checkDefault && !img.getAttribute("src").includes('/pics/flags/gradient/')){
checkFlag = true;
}
})
parent.querySelectorAll(`a[href]`).forEach(function(a){
if(a.getAttribute("href").includes('/national-teams/') && !isLocal(a.getAttribute("href"))){
checkFlag = true;
}
if(!checkDefault && !a.getAttribute("href").includes('/national-teams/')){
checkFlag = true;
}
})
if(checkFlag) return;
}
if (link) {
var player = {};
player.English = link.textContent;
player.ID = parseInt(link.getAttribute("player_link"));
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("player_link"))) {
link.textContent = translation.Chinese;
}
})
});
}, true);
})();
// 转会
(function() {
'use strict';
if (!(
window.location.pathname.includes('/transfer')
)) {
return;
}
var players = [];
var links = [];
console.log(document.querySelector('#transfer_list'));
// Mutation Observer 实例化
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.matches && node.matches('table')) {
document.querySelectorAll("#transfer_list a[player_link]").forEach(function(element) {
var link = element;
// 检查国籍
if(true){
let parent = element.parentElement.parentElement.parentElement;
if(parent.querySelectorAll('ib').length !== 0 && !isLocal(parent.querySelector('ib').getAttribute("class"))) return;
}
if (link) {
var player = {};
player.English = link.textContent;
player.ID = parseInt(link.getAttribute("player_link"));
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("player_link"))) {
link.textContent = translation.Chinese;
}
})
});
}, true);
}
});
});
});
// 监视整个文档的变化
mutationObserver.observe(document.querySelector('#transfer_list'), {
childList: true,
subtree: true,
});
})();
// 训练
(function() {
'use strict';
if (!(
window.location.pathname === '/training/' || window.location.pathname === '/training'
)) {
return;
}
function transTrain(){
let players = [];
let links = [];
document.querySelectorAll(".team .player").forEach(function(element) {
var link = element;
if (link) {
var player = {};
player.English = link.querySelector(".player_name").textContent;
player.ID = parseInt(link.getAttribute("player_link"));
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("player_link"))) {
link.querySelector(".player_name").textContent = translation.Chinese;
}
})
});
}, false);
}
// 监控特定元素并应用回调函数
function bindObserver(selector, callback) {
const elements = document.querySelectorAll(selector);
elements.forEach(element => {
// 创建一个 MutationObserver 实例并应用给定的回调
const observer = new MutationObserver(callback);
observer.observe(element, {
childList: true
});
});
}
// Mutation Observer 实例化
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.matches && node.matches('#team1, #team2, #team3, #team4, #team5, #team6, #team7')) {
if(document.querySelectorAll("#team1, #team2, #team3, #team4, #team5, #team6, #team7").length === 7){
bindObserver("#team1, #team2, #team3, #team4, #team5, #team6, #team7", transTrain);
transTrain();
}
}
});
});
});
// 监视整个文档的变化
mutationObserver.observe(document.querySelector(".training"), {
childList: true,
subtree: true,
});
})();
// 主页 && 俱乐部 && 联赛
(function() {
'use strict';
if (!(window.location.pathname === '/home/'||
window.location.pathname === '/home'||
window.location.pathname.includes('/club')||
window.location.pathname === '/league' ||
window.location.pathname === '/league/'
)) {
return;
}
function transBox(){
var players = [];
var links = [];
document.querySelectorAll(".box_body span[onclick]").forEach(function(element) {
var link = element;
if (link && link.getAttribute("onclick").split('/').length === 5) {
var player = {};
player.English = link.textContent;
player.ID = parseInt(link.getAttribute("onclick").split('/')[4]);
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("onclick").split('/')[4])) {
link.textContent = translation.Chinese;
}
})
});
}, false);
}
// Mutation Observer 实例化
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.matches && node.matches('#feed .feed_content')) {
setTimeout(function(){
let players = [];
let links = [];
document.querySelectorAll("a[player_link]").forEach(function(element) {
let link = element;
if (link) {
let player = {};
player.English = link.textContent;
player.ID = parseInt(link.getAttribute("player_link"));
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("player_link"))) {
link.textContent = translation.Chinese;
}
})
});
}, false);
}, 800);
}
if (node.matches && node.matches('.column3_a .box:nth-of-type(2)')) {
setTimeout(function(){
transBox();
}, 800);
}
});
});
});
// 监视整个文档的变化
mutationObserver.observe(document.body, {
childList: true,
subtree: true,
});
})();
// 关注名单
(function() {
'use strict';
if (!(
window.location.pathname.includes('/shortlist')
)) {
return;
}
let players = [];
let links = [];
document.querySelectorAll("a[player_link]").forEach(function(link) {
let parent = link.parentElement.parentElement.parentElement;
// 检查国籍
let checkFlag = false;
parent.querySelectorAll("img[src]").forEach(function(img) {
if(isLocal(img.getAttribute('src'))){
checkFlag = true;
}
})
if(checkFlag){
let player = {};
player.English = link.textContent;
player.ID = parseInt(link.getAttribute("player_link"));
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("player_link"))) {
link.textContent = translation.Chinese;
}
})
});
}, true);
})();
// 当前竞价
(function() {
'use strict';
if (!(
window.location.pathname.includes('/bids')
)) {
return;
}
// Mutation Observer 实例化
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.matches && node.matches('div')) {
let players = [];
let links = [];
document.querySelectorAll("a[player_link]").forEach(function(link) {
let parent = link.parentElement;
// 检查国籍
let checkFlag = false;
parent.querySelectorAll("a[href]").forEach(function(a) {
if(isLocal(a.getAttribute('href'))){
checkFlag = true;
}
})
if(checkFlag){
let player = {};
player.English = link.textContent;
player.ID = parseInt(link.getAttribute("player_link"));
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("player_link"))) {
link.textContent = translation.Chinese;
}
})
});
}, true);
}
});
});
});
// 监视整个文档的变化
mutationObserver.observe(document.querySelector('.column2_c .box_body .transfer-box'), {
childList: true,
subtree: true,
});
})();
// 比赛
(function() {
'use strict';
if (!(window.location.pathname.includes('/matches/')
)) {
return;
}
function translateBoard(){
let players = [];
let links = [];
document.querySelectorAll("a.normal.no_hover").forEach(function(element) {
var link = element;
if (link) {
var player = {};
player.English = link.querySelector('.name').textContent;
player.ID = parseInt(link.getAttribute("href").split('/')[2]);
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("href").split('/')[2])) {
link.querySelector('.name').textContent = translation.Chinese;
}
})
});
}, false);
}
function translateQuestionable(){
let players = [];
let links = [];
document.querySelectorAll("a.white.normal").forEach(function(element) {
var link = element;
if (link) {
var player = {};
player.English = link.textContent;
player.ID = parseInt(link.getAttribute("href").split('/')[2]);
players.push(player)
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("href").split('/')[2])) {
link.textContent = translation.Chinese;
}
})
});
}, false);
}
function translateReport(){
let players = [];
let ids = new Set();
let links = [];
document.querySelectorAll(".report_list a[href], .event_list a[href]").forEach(function(element) {
var link = element;
if (link.getAttribute("href").split('/').length === 3) {
var player = {};
player.ID = parseInt(link.getAttribute("href").split('/')[2]);
player.English = link.textContent;
if(!ids.has(parseInt(link.getAttribute("href").split('/')[2]))){
ids.add(player.ID);
players.push(player)
}
links.push(link);
}
});
translateNumbers(players, function(translations) {
links.forEach(function(link) {
translations.forEach(function(translation) {
if (translation.ID === parseInt(link.getAttribute("href").split('/')[2])) {
link.textContent = translation.Chinese;
}
})
});
}, false);
}
// Mutation Observer 实例化
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
// Mutation Observer 实例化
if (node.matches && (node.matches('div[tab="field"]'))) {
translateBoard();
translateQuestionable();
}
if (node.matches && node.matches('.post_report')) {
setTimeout(function(){
translateBoard();
translateQuestionable();
translateReport();
}, 800);
}
});
});
});
// 监视整个文档的变化
mutationObserver.observe(document.body, {
childList: true,
subtree: true,
});
})();