MZ - Link Enhancements for League and Match Pages

Updates team links on league pages and adds missing league links to youth match pages

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         MZ - Link Enhancements for League and Match Pages
// @namespace    douglaskampl
// @version      2.1
// @description  Updates team links on league pages and adds missing league links to youth match pages
// @author       Douglas
// @match        https://www.managerzone.com/?p=league&type=*
// @match        https://www.managerzone.com/?p=match&sub=result&mid=*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=managerzone.com
// @grant        none
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    const currentUrl = window.location.href;

    if (currentUrl.includes('?p=league&type=')) {
        const observer = new MutationObserver(() => {
            const leagueRows = document.querySelectorAll('.nice_table tbody tr');
            if (leagueRows.length) {
                let updatedCount = 0;
                leagueRows.forEach(row => {
                    const link = row.querySelector('a[href^="/?p=league&type="]');
                    if (link && link.href.includes('&tid=')) {
                         const teamId = link.href.match(/tid=(\d+)/)?.[1];
                         if (teamId) {
                            link.href = `https://www.managerzone.com/?p=team&tid=${teamId}`;
                            updatedCount++;
                         }
                    }
                });
                 if (updatedCount > 0 || leagueRows.length > 0) {
                     observer.disconnect();
                 }
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    else if (currentUrl.includes('?p=match&sub=result&mid=')) {
        function getUniqueTeamLinks(matchInfoWrapper) {
            const allLinks = matchInfoWrapper.querySelectorAll('a[href*="/?p=team"]');
            const teamIds = new Set();
            const uniqueLinks = [];

            allLinks.forEach(link => {
                const tidMatch = link.href.match(/tid=(\d+)/);
                if (tidMatch) {
                    const tid = tidMatch[1];
                    if (!teamIds.has(tid)) {
                        teamIds.add(tid);
                        uniqueLinks.push(link);
                    }
                }
            });

            return uniqueLinks;
        }

        function extractLeagueInfo(dd) {
            const link = dd.querySelector('a');
            if (!link) return null;

            const url = link.getAttribute('href');
            if (!url) return null;

            const sidMatch = url.match(/[?&]sid=(\d+)/);
            if (!sidMatch) return null;

            return {
                name: link.textContent.trim(),
                url: url,
                sid: sidMatch[1]
            };
        }

        function findLeagueEntries(teamHtml, ageGroup) {
            const doc = new DOMParser().parseFromString(teamHtml, 'text/html');
            const teamInfo = doc.querySelector('#infoAboutTeam');
            if (!teamInfo) return [];

            return Array.from(teamInfo.querySelectorAll('dd'))
                .slice(5)
                .filter(dd => dd.textContent.includes(ageGroup))
                .map(dd => extractLeagueInfo(dd))
                .filter(info => info !== null);
        }

        async function fetchTeamPage(url) {
            try {
                const response = await fetch(url);
                return response.ok ? await response.text() : null;
            } catch { return null; }
        }

        function findMatchingLeagues(team1Leagues, team2Leagues) {
            return team1Leagues.filter(league1 =>
                team2Leagues.some(league2 => league1.sid === league2.sid)
            );
        }

        async function updateMatchHeader() {
            const matchInfoWrapper = document.querySelector('#match-info-wrapper');
            if (!matchInfoWrapper) return;

            const header = matchInfoWrapper.querySelector('h2');
            if (!header || header.textContent.trim()) return;

            const matchHeader = matchInfoWrapper.querySelector('h1');
            if (!matchHeader) return;

            const ageGroup = ['18', '21', '23'].find(age =>
                matchHeader.textContent.trim().includes(age));
            if (!ageGroup) return;

            const teamLinks = getUniqueTeamLinks(matchInfoWrapper);
            if (teamLinks.length !== 2) return;

            const team1Html = await fetchTeamPage(teamLinks[0].href);
            const team2Html = await fetchTeamPage(teamLinks[1].href);
            if (!team1Html || !team2Html) return;

            const team1Leagues = findLeagueEntries(team1Html, ageGroup);
            const team2Leagues = findLeagueEntries(team2Html, ageGroup);

            const matchingLeagues = findMatchingLeagues(team1Leagues, team2Leagues);
            if (!matchingLeagues.length) return;

            header.innerHTML = matchingLeagues.map(league => { const cleanedUrl = league.url.replace(/&tid=\d+/, ''); return `<a href="${cleanedUrl}">${league.name}</a>`; }).join(' | ');
        }

        updateMatchHeader();
    }
})();