// ==UserScript== // @name mzFetchFriendlyMatchesInfo // @namespace http://tampermonkey.net/ // @version 2.2 // @description mz: amount of friendlies played by each player during the current week (27 Jun 2024) // @author Douglas // @match *://www.managerzone.com/?p=challenges* // @grant none // @downloadURL none // ==/UserScript== (function () { "use strict"; const sport = getSport(); const sportId = getSportId(sport); const challengeTemplateUrl = getChallengeTemplateUrl(sport); let teamId; let appearances = new Map(); const modal = createModal(); document.body.appendChild(modal); const playerMatchesTable = createPlayerMatchesTable(); const modalContent = modal.querySelector(".modal-content"); modalContent.appendChild(playerMatchesTable); const loadingMessageDiv = createLoadingMessageDiv(); modalContent.appendChild(loadingMessageDiv); const loadingMessage = createLoadingMessage(); loadingMessageDiv.appendChild(loadingMessage); const miniGameBanner = document.querySelector(".responsive-hide .miniGameBanner"); const topPlacement = document.getElementById("top-placement"); const insertionPoint = miniGameBanner || topPlacement; const toggleButtonText = createToggleButtonText(); insertAfter(toggleButtonText, insertionPoint); const toggleButton = createToggleButton(modal, loadingMessageDiv); insertAfter(toggleButton, toggleButtonText); fetchPageData(); addCustomStyles(); function getSport() { return new URL(document.querySelector("#shortcut_link_thezone").href).searchParams.get("sport"); } function getSportId(sport) { return sport === "soccer" ? 1 : 2; } function getChallengeTemplateUrl(sport) { return `https://www.managerzone.com/ajax.php?p=challenge&sub=personal-challenge-template&sport=${sport}`; } function insertAfter(newNode, referenceNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } function createModal() { const modal = document.createElement("div"); modal.className = "modal"; modal.style.display = "none"; modal.style.position = "fixed"; modal.style.zIndex = "1"; modal.style.left = "0"; modal.style.top = "0"; modal.style.width = "100%"; modal.style.height = "100%"; modal.style.backgroundColor = "rgba(0, 0, 0, 0.8)"; const modalContent = document.createElement("div"); modalContent.className = "modal-content"; modalContent.style.backgroundColor = "#333"; modalContent.style.margin = "10% auto"; modalContent.style.padding = "0"; modalContent.style.border = "none"; modalContent.style.width = "fit-content"; modalContent.style.maxWidth = "80%"; const closeButton = document.createElement("span"); closeButton.className = "close"; closeButton.innerHTML = "×"; closeButton.style.color = "#aaa"; closeButton.style.float = "right"; closeButton.style.fontSize = "28px"; closeButton.style.fontWeight = "bold"; closeButton.onclick = function () { modal.style.display = "none"; loadingMessageDiv.style.display = "none"; }; modalContent.appendChild(closeButton); modal.appendChild(modalContent); return modal; } function createPlayerMatchesTable() { const table = document.createElement("table"); table.className = "player-matches-table"; table.style.borderCollapse = "collapse"; table.style.margin = "0 auto"; table.style.border = "1px solid black"; table.style.backgroundColor = "#000"; table.style.fontFamily = "Montserrat"; return table; } function createLoadingMessageDiv() { const div = document.createElement("div"); div.style.display = "none"; div.style.justifyContent = "center"; div.style.alignItems = "center"; div.style.width = "100%"; div.style.height = "100%"; return div; } function createLoadingMessage() { const p = document.createElement("p"); p.textContent = "Loading…"; p.style.color = "#d6204e"; p.style.fontFamily = "Montserrat"; p.style.fontSize = "16px"; return p; } function createToggleButton(modal, loadingMessageDiv) { const button = document.createElement("button"); button.style.width = "30px"; button.style.height = "25px"; button.style.borderRadius = "70%"; button.style.border = "none"; button.style.cursor = "pointer"; button.style.color = "white"; button.style.marginBottom = "15px"; button.style.marginTop = "10px"; button.style.marginLeft = "5px"; button.style.background = "navy"; button.style.transition = "background 0.5s"; button.onclick = function () { if (modal.style.display === "none") { if (appearances.size === 0) { loadingMessageDiv.style.display = "flex"; } modal.style.display = "block"; } else { modal.style.display = "none"; loadingMessageDiv.style.display = "none"; } }; return button; } function createToggleButtonText() { const text = document.createElement("span"); text.textContent = "Click this button to view friendly match info ->"; text.style.marginLeft = "10px"; text.style.fontFamily = "Montserrat"; text.style.color = "navy"; text.style.fontSize = "16px"; text.style.textShadow = "2px 2px 4px orange"; return text; } function fetchPageData() { fetch(window.location.href) .then(response => response.text()) .then(data => parsePageData(data)) .catch(e => console.warn("Error: ", e)); } function parsePageData(data) { const parser = new DOMParser(); const doc = parser.parseFromString(data, "text/html"); const username = doc.getElementById("header-username").textContent; fetchManagerData(username); } function fetchManagerData(username) { fetch(`https://www.managerzone.com/xml/manager_data.php?sport_id=1&username=${username}`) .then(response => response.text()) .then(xmlData => parseManagerData(xmlData)) .catch(e => console.warn("Error fetching manager data: ", e)); } function parseManagerData(xmlData) { const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlData, "text/xml"); const teamElement = Array.from(xmlDoc.getElementsByTagName("Team")) .find(teamElement => teamElement.getAttribute("sport") === sport); teamId = teamElement.getAttribute("teamId"); fetchChallengeTemplate(); } function fetchChallengeTemplate() { fetch(challengeTemplateUrl) .then(response => response.text()) .then(data => parseChallengeTemplate(data)) .catch(e => console.warn("Error fetching challenge template: ", e)); } function parseChallengeTemplate(data) { const parser = new DOMParser(); const doc = parser.parseFromString(data, "text/html"); const currentWeekFriendlyMatchesDiv = getCurrentWeekFriendlyMatchesDiv(doc); if (currentWeekFriendlyMatchesDiv.length === 0) { loadingMessage.style.color = "lightgray"; loadingMessage.style.padding = "5px"; loadingMessage.textContent = "No friendly matches have been played this week!"; return; } const matchIds = extractMatchIds(currentWeekFriendlyMatchesDiv); if (matchIds.length === 0) { loadingMessage.style.color = "lightgray"; loadingMessage.style.padding = "5px"; loadingMessage.textContent = "No friendly matches have been played this week!"; return; } fetchMatchInfo(matchIds); } function getCurrentWeekFriendlyMatchesDiv(doc) { const scheduleDiv = doc.getElementById("friendly_series_schedule"); const calendarDiv = scheduleDiv.querySelector(".calendar"); const calendarForm = calendarDiv.querySelector("#saveMatchTactics"); return calendarForm.querySelector("div.flex-nowrap.fss-row.fss-gw-wrapper.fss-has-matches"); } function extractMatchIds(currentWeekFriendlyMatchesDiv) { const matchDivs = ["d1", "d3", "d4", "d5", "d7"].map(className => currentWeekFriendlyMatchesDiv.querySelector(`.${className}`) ); return matchDivs.flatMap(div => { const matchScoresLinks = Array.from(div.querySelectorAll("a.score-shown:not(.gray)")); return matchScoresLinks.map(link => { const matchUrl = link.getAttribute("href"); return matchUrl.split("mid=")[1].split("&")[0]; }); }); } function fetchMatchInfo(matchIds) { matchIds.forEach(matchId => { fetch(`https://www.managerzone.com/xml/match_info.php?sport_id=${sportId}&match_id=${matchId}`) .then(response => response.text()) .then(xmlData => parseMatchInfo(xmlData)) .catch(e => console.warn("Error fetching match info: ", e)); }); } function parseMatchInfo(xmlData) { const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlData, "text/xml"); const teamElements = Array.from(xmlDoc.getElementsByTagName("Team")); const ourTeamElement = teamElements.find(teamElement => teamElement.getAttribute("id") === teamId); updatePlayerAppearances(ourTeamElement); displayPlayerMatches(); } function updatePlayerAppearances(ourTeamElement) { const playerElements = Array.from(ourTeamElement.getElementsByTagName("Player")); playerElements.forEach(playerElement => { const playerId = playerElement.getAttribute("id"); const playerName = playerElement.getAttribute("name"); if (appearances.has(playerId)) { const playerInfo = appearances.get(playerId); playerInfo.appearances += 1; appearances.set(playerId, playerInfo); } else { appearances.set(playerId, { name: playerName, appearances: 1 }); } }); } function displayPlayerMatches() { loadingMessageDiv.style.display = "none"; playerMatchesTable.innerHTML = ""; const headerRow = createHeaderRow(); playerMatchesTable.appendChild(headerRow); const sortedAppearances = sortAppearances(); sortedAppearances.forEach(([playerId, playerInfo]) => { const row = createPlayerRow(playerId, playerInfo); playerMatchesTable.appendChild(row); }); } function sortAppearances() { return Array.from(appearances).sort((a, b) => b[1].appearances - a[1].appearances); } function createHeaderRow() { const headerRow = document.createElement("tr"); const playerNameHeader = document.createElement("th"); playerNameHeader.textContent = "Player"; playerNameHeader.style.color = "#d6204e"; playerNameHeader.style.border = "1px solid black"; playerNameHeader.style.padding = "4px"; const appearancesHeader = document.createElement("th"); appearancesHeader.textContent = "Games This Week"; appearancesHeader.style.color = "#d6204e"; appearancesHeader.style.border = "1px solid black"; appearancesHeader.style.padding = "4px"; headerRow.appendChild(playerNameHeader); headerRow.appendChild(appearancesHeader); return headerRow; } function createPlayerRow(playerId, playerInfo) { const row = document.createElement("tr"); const nameCell = createPlayerNameCell(playerId, playerInfo.name); const appearancesCell = createAppearancesCell(playerInfo.appearances); row.appendChild(nameCell); row.appendChild(appearancesCell); return row; } function createPlayerNameCell(playerId, playerName) { const nameCell = document.createElement("td"); nameCell.style.border = "1px solid black"; nameCell.style.padding = "4px"; nameCell.style.color = "white"; const link = document.createElement("a"); link.href = `https://www.managerzone.com/?p=players&pid=${playerId}`; link.textContent = playerName; link.style.color = "white"; nameCell.appendChild(link); return nameCell; } function createAppearancesCell(appearances) { const appearancesCell = document.createElement("td"); appearancesCell.textContent = appearances; appearancesCell.style.color = "white"; appearancesCell.style.border = "1px solid black"; appearancesCell.style.padding = "4px"; return appearancesCell; } function addCustomStyles() { const style = document.createElement("style"); style.textContent = ` @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap'); @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } @keyframes fade-out { from { opacity: 1; } to { opacity: 0; } } .modal { display: none; position: fixed; z-index: 1; left: 0; top: 0; width: 100%; height: 100%; overflow: hidden; background-color: rgba(0,0,0,0.8); } .modal-content { background-color: #333; margin: 10% auto; padding: 0; border: none; width: fit-content; max-width: 80%; } .close { color: #aaa; float: right; font-size: 28px; font-weight: bold; } .close:hover, .close:focus { color: black; text-decoration: none; cursor: pointer; } .player-matches-table { background-color: #000; } .player-matches-table th { color: #d6204e; } .player-matches-table td { color: white; } .toggle-button-text { margin-left: 10px; font-family: Montserrat; color: navy; font-size: 16px; } `; document.head.appendChild(style); } })();