TMGeneralTranslation

通过翻译服务器对游戏内球员名字进行汉化

目前為 2024-05-01 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         TMGeneralTranslation
// @namespace    https://trophymanager.com/
// @version      1.0.4
// @author       提瓦特元素反应(https://trophymanager.com/club/4731723/)
// @description  通过翻译服务器对游戏内球员名字进行汉化
// @license      MIT
// @match        https://trophymanager.com/*
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// ==/UserScript==

var DEBUG_MODE = true;
var BACK_END = "http://trans.tm.kit.ga";
var DISPLAY_LOCAL_ONLY = true

// 函数用于发送请求并处理响应
function translateNumbers(players, callback) {
    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(copyPlayers);

    console.log(jsonData);
    // 发送 POST 请求
    GM_xmlhttpRequest({
        method: "POST",
        url: BACK_END + "/translate",
        data: jsonData,
        headers: {
            "Content-Type": "application/json"
        },
        onload: function(response) {
            console.log(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(DISPLAY_LOCAL_ONLY && document.querySelector('.box_sub_header .country_link').getAttribute('href') !== '/national-teams/cn/'){
        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;
                }
            });
        }
    }
})();

// 战术-列表
(function() {
    'use strict';

    if (!(window.location.pathname === '/tactics' || window.location.pathname === '/tactics/' || window.location.pathname === '/tactics/#')) {
        return;
    }

    let translationsResult;

    function modifyNamesAndExtractIdsForNames() {
        var players = [];
        document.querySelectorAll("span.player_name").forEach(element => {
            var player = {};

            // 检查国籍
            let parent = element.parentElement;
            if(DISPLAY_LOCAL_ONLY && parent.querySelectorAll('ib').length !== 0){
                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(DISPLAY_LOCAL_ONLY && element.querySelectorAll('ib').length !== 0){
                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(DISPLAY_LOCAL_ONLY && element.querySelectorAll('ib').length !== 0){
                return;
            }

            const parentLi = element.closest('li.bench_player');
            if (parentLi) {
                player.ID = parseInt(parentLi.getAttribute('player_id'));
            }
            players.push(player);
        });

        document.querySelectorAll('.cond_order div[player_link]').forEach(element => {
            var player = {};
            player.ID = parseInt(element.getAttribute('player_link'));
            player.English = element.textContent.trim();

            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;
                    }
                })
            });
        });
    }

    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);
    // 创建全局观察者来监控元素的删除和重建
    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 = [];

    document.querySelectorAll("a[player_link]").forEach(function(element) {
        var link = element;

        // 检查国籍
        if(DISPLAY_LOCAL_ONLY){
            let checkFlag = false
            let parent = element.parentElement;
            parent.querySelectorAll(`img[src]`).forEach(function(img){
                if(img.getAttribute("src").includes('/pics/flags/gradient/')){
                    checkFlag = true;
                }
            })
            parent.querySelectorAll(`a[href]`).forEach(function(a){
                if(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;
                }
            })
        });
    });
})();

// 转会
(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(DISPLAY_LOCAL_ONLY){
                            let parent = element.parentElement.parentElement.parentElement;
                            if(parent.querySelectorAll('.flag-img-cn').length === 0) 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;
                                }
                            })
                        });
                    });
                }
            });
        });
    });

    // 监视整个文档的变化
    mutationObserver.observe(document.querySelector('#transfer_list'), {
        childList: true,
        subtree: true,
    });

})();

// 训练
(function() {
    'use strict';

    if (!(
        window.location.pathname === '/training/' || window.location.pathname === '/training'
    )) {
        return;
    }

    var players = [];
    var links = [];

    // 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){
                        setTimeout(function(){
                            document.querySelectorAll(".team .player").forEach(function(element) {
                                var link = element;
                                console.log(link);
                                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;
                                        }
                                    })
                                });
                            });
                        }, 1000);
                    }
                }
            });
        });
    });

    // 监视整个文档的变化
    mutationObserver.observe(document.body, {
        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;
                    }
                })
            });
        });
    }

    // 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;
                                    }
                                })
                            });
                        });
                    }, 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('/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;
                    }
                })
            });
        });
    }

    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;
                    }
                })
            });
        });
    }

    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;
                    }
                })
            });
        });
    }

    // 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,
    });
})();