// ==UserScript== // @name MZ - Track Youth Exchange Players // @namespace http://tampermonkey.net/ // @version 2.7 // @description Persist player data from Youth Academy page when swapping or rejecting players — optimized version // @author // @match *://www.managerzone.com/?p=youth_academy* // @grant GM_xmlhttpRequest // @require https://cdn.jsdelivr.net/npm/sweetalert2@11 // @connect www.managerzone.com // @connect u18mz.vercel.app // @connect youth-exchange-worker.douglasdotv.workers.dev // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; console.log("| MZ_Track_Youth_Exchange_Players is running and will save youth exchange data to db. |"); const usernameCountryMap = { douglaskampl: 'BR', /* Put your username and country/code (for example, 'Brazil' or 'BR') here */ }; const youthExchangePlayerAge = 16; let username = 'Unknown'; let nationality = 'Unknown'; let storedPlayerData = null; let dataReady = false; let lastPlayerID = null; const currentSeason = document.querySelector('#header-stats-wrapper h5.linked').textContent.match(/(\d+)/)[1]; const showToast = (color, message) => { Swal.fire({ toast: true, position: 'bottom-right', iconColor: color, icon: color === 'blue' ? 'info' : color === 'green' ? 'success' : color === 'orange' ? 'warning' : 'error', title: message, showConfirmButton: false, timer: 3000, background: color, color: 'white' }); }; const fetchNationality = async (username) => { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: `http://www.managerzone.com/xml/manager_data.php?sport_id=1&username=${username}`, onload: function (response) { const parser = new DOMParser(); const xmlDoc = parser.parseFromString(response.responseText, "text/xml"); const countryShortname = xmlDoc.querySelector('UserData') ? xmlDoc.querySelector('UserData').getAttribute('countryShortname') : 'Not found'; resolve(countryShortname); }, onerror: function () { console.log("Error fetching nationality."); reject(new Error("Failed to fetch nationality")); } }); }); }; const getCountryFullName = async (shortName) => { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: 'https://u18mz.vercel.app/json/countries.json', onload: function (response) { const countries = JSON.parse(response.responseText); const country = countries.find(c => c.code === shortName); resolve(country ? country.name : shortName); }, onerror: function () { console.log("Error fetching full country name."); reject(new Error("Failed to fetch country name")); } }); }); }; const sendDataToFirebase = (youthExchangeObj) => { showToast('blue', 'Sending data...'); GM_xmlhttpRequest({ method: "POST", url: "https://youth-exchange-worker.douglasdotv.workers.dev/", headers: { "Content-Type": "application/json" }, data: JSON.stringify(youthExchangeObj), onload: function (response) { const responseText = response.responseText || 'No additional information provided'; if (response.status >= 200 && response.status < 300) { showToast('green', `Your player was sent to the database. Thank you for contributing.`); } else if (response.status === 400) { showToast('red', `Bad Request (400): ${responseText}`); } else if (response.status === 401) { showToast('red', `Unauthorized (401): ${responseText}`); } else if (response.status === 403) { showToast('red', `Forbidden (403): ${responseText}`); } else if (response.status === 404) { showToast('red', `Not Found (404): ${responseText}`); } else if (response.status === 500) { showToast('red', `Server Error (500): ${responseText}`); } else if (response.status === 503) { showToast('red', `Service Unavailable (503): ${responseText}`); } else { showToast('red', `Unexpected Error (${response.status}): ${responseText}`); } console.log(`Data sent. HTTP Status Code: ${response.status}. Response: ${responseText}`); }, onerror: function (error) { showToast('red', 'Network Error: Failed to send data'); console.log('Error:', error); } }); }; const preparePlayerData = (playerData) => { return { id: playerData.playerID, name: playerData.playerName, age: youthExchangePlayerAge, country: nationality, hp: playerData.hp, firstHpSkill: playerData.firstHpSkill, secondHpSkill: playerData.secondHpSkill, lp: playerData.lp, firstLpSkill: playerData.firstLpSkill, secondLpSkill: playerData.secondLpSkill, trainingSpeed: playerData.trainingSpeed, totalBalls: parseInt(playerData.totalSkillBalls, 10), owner: username, stats: playerData.stats, season: parseInt(currentSeason, 10), }; }; const extractPlayerStats = (playerContainer) => { const stats = {}; const skillsNames = [ "speed", "stamina", "playIntelligence", "passing", "shooting", "heading", "keeping", "ballControl", "tackling", "aerialPassing", "setPlays", "experience", "form" ]; const skillsRows = playerContainer.querySelectorAll('.player_skills tr'); skillsRows.forEach((row, index) => { if (index < skillsNames.length) { const skillValueElement = row.querySelector('.skillval span'); const skillValue = skillValueElement ? parseInt(skillValueElement.textContent.trim()) : 0; const skillName = skillsNames[index]; stats[skillName] = skillValue; } }); return stats; }; const extractPlayerData = () => { const playerContainer = document.getElementById("thePlayers_x"); if (!playerContainer) { console.error("Player container not found"); return; } const currentPlayerID = playerContainer.querySelector('.player_id_span')?.textContent; if (currentPlayerID === lastPlayerID && storedPlayerData) { return; } lastPlayerID = currentPlayerID; dataReady = false; showToast('orange', '/16 running!'); GM_xmlhttpRequest({ method: "GET", url: `https://www.managerzone.com/ajax.php?p=players&sub=scout_report&pid=null&sport=soccer`, onload: function (response) { let responseText = response.responseText.replace(/Trzxyvopaxis/g, ''); const parser = new DOMParser(); const doc = parser.parseFromString(responseText, "text/html"); const dataList = doc.querySelectorAll('dl > dd'); const extractSkillsAndPotentials = (skillContainers) => { const skills = { firstHpSkill: "", secondHpSkill: "", firstLpSkill: "", secondLpSkill: "" }; if (skillContainers.length > 1) { const hpSkills = Array.from(skillContainers[0].querySelectorAll('li > span:last-child')).map(span => span.textContent.trim()); const lpSkills = Array.from(skillContainers[1].querySelectorAll('li > span:last-child')).map(span => span.textContent.trim()); if (hpSkills.length >= 2) { skills.firstHpSkill = hpSkills[0]; skills.secondHpSkill = hpSkills[1]; } if (lpSkills.length >= 2) { skills.firstLpSkill = lpSkills[0]; skills.secondLpSkill = lpSkills[1]; } } return skills; }; const skillsAndPotentials = extractSkillsAndPotentials(dataList); const stats = extractPlayerStats(playerContainer); const playerData = { playerID: playerContainer.querySelector('.player_id_span').textContent, playerName: playerContainer.querySelector('.player_name').textContent, hp: dataList[0].querySelectorAll('.lit').length, lp: dataList[1].querySelectorAll('.lit').length, totalSkillBalls: playerContainer.querySelectorAll('tbody > tr')[6].querySelector('.bold').textContent, trainingSpeed: dataList[2].querySelectorAll('.lit').length, stats: stats, ...skillsAndPotentials }; const youthExchangeObj = preparePlayerData(playerData); storedPlayerData = youthExchangeObj; dataReady = true; console.log("Player data extracted and stored:", storedPlayerData); showToast('green', 'Data is ready to be sent.'); console.log('(Data is ready)'); }, onerror: function () { console.error("Error fetching player data."); dataReady = false; } }); }; const setUpEventListeners = () => { const observeRejectButton = () => { const rejectButton = document.querySelector('#discard_youth_button'); if (rejectButton && !rejectButton.dataset.listenerAdded) { rejectButton.addEventListener('click', (event) => { if (!dataReady) { event.preventDefault(); showToast('red', 'Data is not ready yet. Please wait.'); return; } console.log("Reject button clicked."); sendDataToFirebase(storedPlayerData); }); rejectButton.dataset.listenerAdded = true; console.log("Listener added to Reject button."); } }; const exchangeButton = document.querySelector('#exchange_button'); if (exchangeButton && !exchangeButton.dataset.listenerAdded) { exchangeButton.addEventListener('click', (event) => { if (!dataReady) { event.preventDefault(); showToast('red', 'Data is not ready yet. Please wait.'); return; } console.log("Exchange button clicked."); sendDataToFirebase(storedPlayerData); }); exchangeButton.dataset.listenerAdded = true; console.log("Listener added to Exchange button."); } const playerContainer = document.getElementById("thePlayers_x"); if (playerContainer) { const observer = new MutationObserver(() => { const currentPlayerID = playerContainer.querySelector('.player_id_span')?.textContent; if (currentPlayerID && currentPlayerID !== lastPlayerID) { extractPlayerData(); } else if (!dataReady) { showToast('orange', '/16 running!'); } observeRejectButton(); }); observer.observe(playerContainer, { childList: true, subtree: true }); console.log("MutationObserver set up for player container changes."); extractPlayerData(); observeRejectButton(); } else { console.log("Player container not found. Cannot observe player data."); } }; const checkForPlayerContainer = () => { const playerContainer = document.getElementById("thePlayers_x"); if (playerContainer) { setUpEventListeners(); clearInterval(containerCheckInterval); } }; const containerCheckInterval = setInterval(checkForPlayerContainer, 1000); window.addEventListener('load', async () => { const usernameElement = document.getElementById('header-username'); username = usernameElement ? usernameElement.textContent : 'Unknown'; if (usernameCountryMap[username]) { nationality = usernameCountryMap[username]; } else { try { const countryShortName = await fetchNationality(username); nationality = await getCountryFullName(countryShortName); } catch (error) { console.error(error); nationality = 'Unknown'; } } }); })();