MazyarTools

Mazyar Tools & Utilities

目前為 2024-10-18 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/513041/1466977/MazyarTools.js

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         MazyarTools
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Mazyar Tools & Utilities
// @copyright    z7z from managerzone.com
// @author       z7z from managerzone.com
// @license      MIT
// @match        https://www.managerzone.com/*
// @match        https://test.managerzone.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=managerzone.com
// @supportURL   https://github.com/mz-ir/mazyar
// ==/UserScript==

function mazyarParseMzDate(dateString) {
    const [day, month, year] = dateString.split('-').map(Number);
    return new Date(year, month - 1, day);
}

function mazyarParseMzDateTime(dateTimeString) {
    const [date, time] = dateTimeString.split(' ');
    const [day, month, year] = date.split('-').map(Number);
    const [hours, minutes] = time.split(':').map(Number);
    return new Date(year, month - 1, day, hours, minutes);
}

function mazyarGenerateUuidV4() {
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
        const r = (Math.random() * 16) | 0,
            v = c == "x" ? r : (r & 0x3) | 0x8;
        return v.toString(16);
    });
}

function mazyarIsFilterHitsValid(hits) {
    return typeof hits === "number" && hits >= 0;
}

function mazyarHasDuplicates(array) {
    return new Set(array).size !== array.length;
}

function mazyarExtractSportType(doc = document) {
    const zone = doc.querySelector("a#shortcut_link_thezone");
    if (zone) {
        return zone.href.indexOf("hockey") > -1 ? "hockey" : "soccer";
    }
    return "soccer";
}

function mazyarExtractClubCurrency(doc) {
    const players = doc.getElementById("playerAltViewTable")?.querySelectorAll("tbody tr");
    if (players && players.length > 0) {
        const parts = players[0].querySelector("td:nth-child(3)")?.innerText.split(" ");
        return parts[parts.length - 1].trim();
    }
    return "";
}

function mazyarExtractNationalCurrency(doc) {
    // works for both domestic and foreign countries
    const playerNode = doc.getElementById("thePlayers_0")?.querySelector("table tbody tr:nth-child(6)");
    if (playerNode) {
        const parts = playerNode.innerText.split(" ");
        return parts[parts.length - 1].trim();
    }
    return "";
}

function mazyarExtractTeamId(link) {
    const regex = /tid=(\d+)/;
    const match = regex.exec(link);
    return match ? match[1] : null;
}

function mazyarExtractPlayerIdFromProfileLink(link) {
    const regex = /pid=(\d+)/;
    const match = regex.exec(link);
    return match ? match[1] : null;
}

function mazyarExtractMatchId(link) {
    const regex = /mid=(\d+)/;
    const match = regex.exec(link);
    return match ? match[1] : null;
}

function mazyarExtractPlayerIdFromTransferMonitor(link) {
    const regex = /u=(\d+)/;
    const match = regex.exec(link);
    return match ? match[1] : null;
}

function mazyarExtractPlayerIdFromContainer(player) {
    return player?.querySelector("h2 span.player_id_span")?.innerText;
}

function mazyarIsMatchInProgress(resultText) {
    const scoreRegex = /\b(X|0|[1-9]\d*) - (X|0|[1-9]\d*)\b/;
    return !scoreRegex.test(resultText);
}

function mazyarGetSquadSummaryLink(tid) {
    return `https://${location.hostname}/?p=players&sub=alt&tid=${tid}`;
}

function mazyarFormatBigNumber(n, sep = " ") {
    if (n) {
        const numberString = n.toString();
        let formattedParts = [];
        for (let i = numberString.length - 1; i >= 0; i -= 3) {
            let part = numberString.substring(Math.max(i - 2, 0), i + 1);
            formattedParts.unshift(part);
        }
        return formattedParts.join(sep);
    }
    return "0";
}

function mazyarFormatAverageAge(age, fractionDigits = 1) {
    if (age) {
        return age.toFixed(fractionDigits);
    }
    return "0.0";
}

function mazyarFormatFileSize(b) {
    const s = 1024;
    let u = 0;
    while (b >= s || -b >= s) {
        b /= s;
        u++;
    }
    return (u ? b.toFixed(1) + " " : b) + " KMGTPEZY"[u] + "B";
}

function mazyarExtractClubPlayersDetails(doc, currency) {
    const players = [];
    const playerNodes = doc.querySelectorAll("table#playerAltViewTable tr");
    for (const playerNode of playerNodes) {
        const age = playerNode.querySelector("td:nth-child(5)")?.innerText.replace(/\s/g, "");
        if (age) {
            const value = playerNode.querySelector("td:nth-child(3)")?.innerText.replaceAll(currency, "").replace(/\s/g, "");
            const shirtNumber = playerNode.querySelector("td:nth-child(0)")?.innerText.replace(/\s/g, "");
            const pid = playerNode.querySelector("a")?.href;
            players.push({
                shirtNumber,
                age: parseInt(age, 10),
                value: parseInt(value, 10),
                id: mazyarExtractPlayerIdFromProfileLink(pid),
            });
        }
    }
    return players;
}

function mazyarExtractNumberOfFlags(infoTable) {
    const images = infoTable.getElementsByTagName("img");
    return images ? [...images].filter((img) => img.src.indexOf("/flags/") > -1).length : 0;
}

function mazyarIsPlayerDomestic(infoTable) {
    return mazyarExtractNumberOfFlags(infoTable) === 1;
}

function mazyarExtractNationalPlayersDetails(doc, currency) {
    const players = [];
    const playerNodes = doc.querySelectorAll("div.playerContainer");
    for (const playerNode of playerNodes) {
        const id = mazyarExtractPlayerIdFromProfileLink(playerNode.querySelector("h2 a")?.href);
        const infoTable = playerNode.querySelector("div.dg_playerview_info table");
        const age = infoTable.querySelector("tbody tr:nth-child(1) td strong").innerText;
        const selector = mazyarIsPlayerDomestic(infoTable) ? "tbody tr:nth-child(5) td span" : "tbody tr:nth-child(6) td span";
        const value = infoTable.querySelector(selector)?.innerText.replaceAll(currency, "").replace(/\s/g, "");
        players.push({
            age: parseInt(age, 10),
            value: parseInt(value, 10),
            id,
        });
    }
    return players;
}

function mazyarGetNumberOfPlayers(players, ageLow = 0, ageHigh = 99) {
    return players.filter((player) => player.age <= ageHigh && player.age >= ageLow).length;
}

function mazyarFilterPlayers(players, count = 0, ageLow = 0, ageHigh = 99) {
    if (players.length === 0) {
        return { values: 0, avgAge: 0.0 };
    }

    const n = count === 0 ? players.length : count;
    const filtered = players
        .filter((player) => player.age <= ageHigh && player.age >= ageLow)
        .sort((a, b) => b.value - a.value)
        .slice(0, n);
    if (filtered.length === 0) {
        return { values: 0, avgAge: 0.0 };
    }
    const values = filtered.map((player) => player.value).reduce((a, b) => a + b, 0);
    const avgAge = filtered.map((player) => player.age).reduce((a, b) => a + b, 0) / filtered.length;
    return { values, avgAge };
}

async function mazyarFetchNationalPlayersAndCurrency(tid, sport) {
    const url = `https://${location.hostname}/ajax.php?p=nationalTeams&sub=players&ntid=${tid}&sport=${sport}`;
    let players = [];
    let currency = '';
    await fetch(url)
        .then((resp) => resp.text())
        .then((content) => {
            const parser = new DOMParser();
            const doc = parser.parseFromString(content, "text/html");
            currency = mazyarExtractNationalCurrency(doc);
            players = mazyarExtractNationalPlayersDetails(doc, currency);
        })
        .catch((error) => {
            console.warn(error);
        });
    return { players, currency };
}

async function mazyarFetchClubPlayersAndCurrency(tid) {
    const url = mazyarGetSquadSummaryLink(tid);
    let players = [];
    let currency = '';
    await fetch(url)
        .then((resp) => resp.text())
        .then((content) => {
            const parser = new DOMParser();
            const doc = parser.parseFromString(content, "text/html");
            currency = mazyarExtractClubCurrency(doc);
            players = mazyarExtractClubPlayersDetails(doc, currency);
        })
        .catch((error) => {
            console.warn(error);
        });
    return { players, currency };
}

async function mazyarFetchPlayersAndCurrency(tid, sport) {
    const url = mazyarGetSquadSummaryLink(tid);
    const isNational = await fetch(url, { method: "HEAD" })
        .then((resp) => (resp.url.search("p=national_teams") > -1));
    return isNational ? await mazyarFetchNationalPlayersAndCurrency(tid, sport) : await mazyarFetchClubPlayersAndCurrency(tid);
}

function mazyarExtractClubTopPlyers(doc) {
    const currency = mazyarExtractClubCurrency(doc);
    const players = mazyarExtractClubPlayersDetails(doc, currency);
    const sport = mazyarExtractSportType(doc);
    const count = sport === "soccer" ? 11 : 21;
    return players ? mazyarFilterPlayers(players, count) : { values: 0, avgAge: 0 };
}

async function mazyarExtractPlayersProfileDetails(teamId) {
    const url = `https://${location.hostname}/?p=players&tid=${teamId}`;
    return await fetch(url)
        .then((resp) => {
            return resp.text();
        }).then((content) => {
            const parser = new DOMParser();
            const doc = parser.parseFromString(content, "text/html");
            const players = doc.getElementById("players_container")?.querySelectorAll("div.playerContainer");
            const info = {};
            for (const player of players) {
                const playerId = player.querySelector("span.player_id_span")?.innerText;
                const inMarket = [...player.querySelectorAll("a")].find((el) => el.href?.indexOf("p=transfer&sub") > -1);
                info[playerId] = {
                    detail: player,
                    shared: !!player.querySelector("i.special_player.fa-share-alt"),
                    market: !!inMarket,
                    marketLink: inMarket?.href,
                }
            }
            return info;
        }).catch((error) => {
            console.warn(error);
            return null;
        });
}

function mazyarExtractSquadSummaryDetails(players, sport = "soccer") {
    if (!players) {
        return [];
    }
    const rows = [];
    if (sport === "hockey") {
        {
            const all = mazyarFilterPlayers(players);
            const top21 = mazyarFilterPlayers(players, 21);
            rows.push({
                title: "All",
                count: players.length,
                all: all.values,
                allAge: all.avgAge,
                top21: top21.values,
                top21Age: top21.avgAge,
            });
        }
        {
            const all = mazyarFilterPlayers(players, 0, 0, 23);
            const top21 = mazyarFilterPlayers(players, 21, 0, 23);
            rows.push({
                title: "U23",
                count: mazyarGetNumberOfPlayers(players, 0, 23),
                all: all.values,
                allAge: all.avgAge,
                top21: top21.values,
                top21Age: top21.avgAge,
            });
        }
        {
            const all = mazyarFilterPlayers(players, 0, 0, 21);
            const top21 = mazyarFilterPlayers(players, 21, 0, 21);
            rows.push({
                title: "U21",
                count: mazyarGetNumberOfPlayers(players, 0, 21),
                all: all.values,
                allAge: all.avgAge,
                top21: top21.values,
                top21Age: top21.avgAge,
            });
        }
        {
            const all = mazyarFilterPlayers(players, 0, 0, 18);
            const top21 = mazyarFilterPlayers(players, 21, 0, 18);
            rows.push({
                title: "U18",
                count: mazyarGetNumberOfPlayers(players, 0, 18),
                all: all.values,
                allAge: all.avgAge,
                top21: top21.values,
                top21Age: top21.avgAge,
            });
        }
    } else {
        {
            const all = mazyarFilterPlayers(players);
            const top16 = mazyarFilterPlayers(players, 16);
            const top11 = mazyarFilterPlayers(players, 11);
            rows.push({
                title: "All",
                count: players.length,
                all: all.values,
                allAge: all.avgAge,
                top16: top16.values,
                top16Age: top16.avgAge,
                top11: top11.values,
                top11Age: top11.avgAge,
            });
        }
        {
            const all = mazyarFilterPlayers(players, 0, 0, 23);
            const top16 = mazyarFilterPlayers(players, 16, 0, 23);
            const top11 = mazyarFilterPlayers(players, 11, 0, 23);
            rows.push({
                title: "U23",
                count: mazyarGetNumberOfPlayers(players, 0, 23),
                all: all.values,
                allAge: all.avgAge,
                top16: top16.values,
                top16Age: top16.avgAge,
                top11: top11.values,
                top11Age: top11.avgAge,
            });
        }
        {
            const all = mazyarFilterPlayers(players, 0, 0, 21);
            const top16 = mazyarFilterPlayers(players, 16, 0, 21);
            const top11 = mazyarFilterPlayers(players, 11, 0, 21);
            rows.push({
                title: "U21",
                count: mazyarGetNumberOfPlayers(players, 0, 21),
                all: all.values,
                allAge: all.avgAge,
                top16: top16.values,
                top16Age: top16.avgAge,
                top11: top11.values,
                top11Age: top11.avgAge,
            });
        }
        {
            const all = mazyarFilterPlayers(players, 0, 0, 18);
            const top16 = mazyarFilterPlayers(players, 16, 0, 18);
            const top11 = mazyarFilterPlayers(players, 11, 0, 18);
            rows.push({
                title: "U18",
                count: mazyarGetNumberOfPlayers(players, 0, 18),
                all: all.values,
                allAge: all.avgAge,
                top16: top16.values,
                top16Age: top16.avgAge,
                top11: top11.values,
                top11Age: top11.avgAge,
            });
        }
    }
    return rows;
}

async function mazyarFetchDocument(url) {
    return await fetch(url)
        .then((resp) => resp.text())
        .then((content) => {
            const parser = new DOMParser();
            return parser.parseFromString(content, "text/html");
        })
        .catch((error) => {
            console.warn(error);
            return null;
        });
}

async function mazyarFetchJson(url) {
    return await fetch(url)
        .then((resp) => resp.json())
        .catch((error) => {
            console.warn(error);
            return null;
        });
}

async function mazyarFetchPlayerProfileDocument(playerId) {
    const url = `https://${location.hostname}/?p=players&pid=${playerId}`;
    return await mazyarFetchDocument(url);
}

async function mazyarFetchTransferMonitorData(sport = "soccer") {
    const url = `https://${location.hostname}/ajax.php?p=transfer&sub=your-bids&sport=${sport}`;
    return await mazyarFetchJson(url);
}

async function mazyarFetchSquadSummaryDocument(teamId) {
    const url = mazyarGetSquadSummaryLink(teamId);
    return await mazyarFetchDocument(url);
}