≮王者归来≯

Fetch federation members info

// ==UserScript==
// @name         ≮王者归来≯ 
// @namespace    douglaskampl
// @version      1.0
// @description  Fetch federation members info
// @author       Douglas
// @match        https://www.managerzone.com/?p=federations*
// @grant        GM_xmlhttpRequest
// @license      MIT
// ==/UserScript==

(function () {
  "use strict";

  const sport = new URL(
    document.querySelector("#shortcut_link_thezone").href
  ).searchParams.get("sport");
  const sportId = sport === "soccer" ? 1 : 2;

  const conversionRatesToUSD = {
    USD: 1,
    R$: 2.827003,
    SEK: 7.4234,
    EUR: 0.80887,
    GBP: 0.555957,
    DKK: 6.00978,
    NOK: 6.921908,
    CHF: 1.265201,
    CAD: 1.3003,
    AUD: 1.309244,
    ILS: 4.378812,
    MXN: 10.82507,
    ARS: 2.807162,
    BOB: 7.905644,
    PYG: 5671.047,
    UYU: 28.88898,
    RUB: 28.21191,
    PLN: 3.801452,
    ISK: 71.15307,
    BGN: 1.576971,
    ZAR: 5.999531,
    THB: 43.46507,
    SIT: 190.539,
    SKK: 29.75788,
    JPY: 123.7233,
    INR: 43.66706,
    MZ: 7.4234,
    MM: 7.4234,
    点: 7.4234,
  };

  // const fid = 63;
  let totalRequests = 0;
  let completedRequests = 0;

  let userTeamIdMap = {};
  const usernames = [];

  function addButton() {
    const competitionHeaderDiv = document.getElementById("competition-header");
    if (!competitionHeaderDiv) return;

    const buttonContainer = document.createElement("div");
    buttonContainer.style.display = "flex";
    buttonContainer.style.alignItems = "center";
    buttonContainer.style.justifyContent = "flex-start";
    buttonContainer.style.marginTop = "10px";

    const button = document.createElement("button");
    button.textContent = "The ≮王者归来≯ Button";
    button.style.backgroundColor = "#FF4500";
    button.style.color = "#FFD700";
    button.style.padding = "4px 6px";
    button.style.border = "1px solid #FFD700";
    button.style.borderRadius = "2px";
    button.style.cursor = "pointer";
    button.style.boxShadow = "0 2px 4px rgba(0, 0, 0, 0.2)";
    button.style.transition = "background-color 0.3s, transform 0.3s";

    button.addEventListener("mouseover", function () {
      button.style.backgroundColor = "#CD3700";
      button.style.transform = "scale(1.05)";
    });

    button.addEventListener("mouseout", function () {
      button.style.backgroundColor = "#FF4500";
      button.style.transform = "scale(1)";
    });

    button.addEventListener("click", function () {
      console.log("fetching");
      fetchFederationMembers();
    });

    buttonContainer.appendChild(button);

    const insertLocation =
      competitionHeaderDiv.querySelector("div.flex-grow-1");
    insertLocation.appendChild(buttonContainer);
  }

  function fetchFederationMembers() {
    const fid = getFederationId();
    const memberCount = getMemberCount();
    console.log("fid:", fid);
    console.log("members:", memberCount);
    for (let offset = 0; offset < memberCount; offset += 10) {
      const url = `https://www.managerzone.com/ajax.php?p=federations&sub=federation_members&fid=${fid}&offset=${offset}&sport=soccer`;
      GM_xmlhttpRequest({
        method: "GET",
        url: url,
        onload: function (response) {
          processMemberList(response.responseText);
        },
      });
    }
  }

  function getFederationId() {
    const url = new URL(window.location.href);
    const hash = url.hash;
    return hash.split("=")[1];
  }

  function getMemberCount() {
    const memberCountElement = document.querySelector(
      "#federation_header_content_body_1 > p:nth-child(3)"
    );
    const memberCountText = memberCountElement.innerText;
    const match = memberCountText.match(/(\d+) de (\d+) membros/);
    return match ? parseInt(match[2], 10) : 0;
  }

  function processMemberList(html) {
    getUsernames(html);
    for (const username of usernames) {
      totalRequests++;
      getUserData(username);
    }
  }

  function getUsernames(html) {
    const doc = new DOMParser().parseFromString(JSON.parse(html), "text/html");
    const userLinks = doc.querySelectorAll("span.user-link-wrapper a");
    for (const link of userLinks) {
      const username = link.textContent.trim();
      if (username) usernames.push(username);
    }
  }

  function getUserData(username) {
    GM_xmlhttpRequest({
      method: "GET",
      url: `https://www.managerzone.com/xml/manager_data.php?sport_id=${sportId}&username=${username}`,
      onload: function (resp) {
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(resp.responseText, "text/xml");

        const teamId = xmlDoc
          .querySelector(`Team[sport="${sport}"]`)
          .getAttribute("teamId");
        const country = xmlDoc
          .querySelector("UserData")
          .getAttribute("countryShortname");
        const teamName = xmlDoc
          .querySelector(`Team[sport="${sport}"]`)
          .getAttribute("teamName");
        const league = xmlDoc
          .querySelector(`Team[sport="${sport}"]`)
          .getAttribute("seriesName");
        const seriesId = xmlDoc
          .querySelector(`Team[sport="${sport}"]`)
          .getAttribute("seriesId");
        const rank = xmlDoc
          .querySelector(`Team[sport="${sport}"]`)
          .getAttribute("rankPos");

        GM_xmlhttpRequest({
          method: "GET",
          url: `https://www.managerzone.com/xml/team_league.php?sport_id=${sportId}&league_id=${seriesId}`,
          onload: function (leagueResp) {
            const leagueDoc = parser.parseFromString(
              leagueResp.responseText,
              "text/xml"
            );
            const teams = leagueDoc.querySelectorAll("Team");
            let position;
            for (const team of teams) {
              if (team.getAttribute("teamId") === teamId) {
                position = team.getAttribute("pos");
                break;
              }
            }

            userTeamIdMap[username] = {
              username,
              teamName,
              teamId,
              country,
              league,
              position,
              rank,
            };
            getPlayerData(teamId, username);
          },
        });
      },
    });
  }

  function getPlayerData(teamId, user) {
    GM_xmlhttpRequest({
      method: "GET",
      url: `https://www.managerzone.com/xml/team_playerlist.php?sport_id=1&team_id=${teamId}`,
      onload: function (resp) {
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(resp.responseText, "text/xml");
        const players = Array.from(
          xmlDoc.querySelectorAll("Player[junior='0']")
        );
        const sortedPlayers = players.sort(
          (a, b) =>
            Number(b.getAttribute("value")) - Number(a.getAttribute("value"))
        );

        let totalValue = 0;
        const count = Math.min(11, sortedPlayers.length);
        for (let i = 0; i < count; i++) {
          totalValue += Number(sortedPlayers[i].getAttribute("value"));
        }
        const avgValue = totalValue / (count || 1);
        const currency = xmlDoc
          .querySelector("TeamPlayers")
          .getAttribute("teamCurrency");

        let avgValueInUSD = avgValue;
        if (currency !== "USD") {
          avgValueInUSD = avgValue / (conversionRatesToUSD[currency] || 1);
        }

        userTeamIdMap[user].avgValue =
          avgValueInUSD > 0 ? `${avgValueInUSD.toFixed(0)} USD` : "U18 Squad";

        completedRequests++;
        if (completedRequests === totalRequests) {
          console.log("done");
          displayResults();
        }
      },
    });
  }

  function displayResults() {
    const modal = document.createElement("div");
    modal.style.position = "fixed";
    modal.style.left = "50%";
    modal.style.top = "50%";
    modal.style.transform = "translate(-50%, -50%)";
    modal.style.backgroundColor = "#F5F5F5";
    modal.style.color = "#D70000";
    modal.style.padding = "20px";
    modal.style.border = "3px solid darkblue";
    modal.style.zIndex = "1000";
    modal.style.maxHeight = "80vh";
    modal.style.overflowY = "auto";
    modal.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.1)";
    modal.style.backgroundColor = "#F5F5F5";
    modal.style.color = "#FF4500";
    modal.style.width = "80%";

    const table = document.createElement("table");
    table.style.width = "100%";
    table.style.borderCollapse = "collapse";

    const headerRow = table.insertRow();
    const headers = [
      "Username",
      "Team",
      "ID",
      "Country",
      "League",
      "Position",
      "Rank",
      "Avg. Value",
    ];
    headers.forEach((headerText, index) => {
      const headerCell = document.createElement("th");
      headerCell.textContent = headerText;
      headerCell.style.border = "1px solid #ddd";
      headerCell.style.padding = "8px";
      headerCell.style.backgroundColor = "darkblue";
      headerCell.style.color = "lightgray";
      headerCell.style.cursor = "pointer";

      headerCell.addEventListener("click", () =>
        sortTableByColumn(table, index)
      );
      headerRow.appendChild(headerCell);

      headerRow.appendChild(headerCell);
    });

    const sortedUsers = Object.keys(userTeamIdMap).sort((a, b) => {
      const valueA = userTeamIdMap[a].avgValue.includes("USD")
        ? parseFloat(userTeamIdMap[a].avgValue)
        : 0;
      const valueB = userTeamIdMap[b].avgValue.includes("USD")
        ? parseFloat(userTeamIdMap[b].avgValue)
        : 0;
      return valueB - valueA;
    });

    sortedUsers.forEach((username) => {
      const row = table.insertRow();
      const userData = userTeamIdMap[username];

      Object.values(userData).forEach((value) => {
        const cell = row.insertCell();
        cell.textContent = value;
        cell.style.border = "1px solid #ddd";
        cell.style.padding = "8px";
      });
    });

    modal.appendChild(table);

    const closeButton = document.createElement("button");
    closeButton.textContent = "Close";
    closeButton.style.marginTop = "10px";
    closeButton.style.backgroundColor = "#D70000";
    closeButton.style.color = "#FFD700";
    closeButton.style.border = "none";
    closeButton.style.padding = "5px 10px";
    closeButton.style.borderRadius = "4px";
    closeButton.style.cursor = "pointer";
    closeButton.addEventListener("click", () => modal.remove());

    modal.appendChild(closeButton);

    document.body.appendChild(modal);
  }

  function sortTableByColumn(table, columnIndex) {
    const rows = Array.from(table.rows).slice(1);
    const isNumeric = !isNaN(rows[0].cells[columnIndex].textContent);

    rows.sort((rowA, rowB) => {
      const cellA = rowA.cells[columnIndex].textContent;
      const cellB = rowB.cells[columnIndex].textContent;

      if (isNumeric) {
        return parseFloat(cellA) - parseFloat(cellB);
      } else {
        return cellA.localeCompare(cellB);
      }
    });

    rows.forEach((row) => table.appendChild(row));
  }

  addButton();
})();