// ==UserScript== // @name TMVN Cup HOF // @namespace https://trophymanager.com // @version 3 // @description Trophymanager: hall of fame of tournament // @match https://trophymanager.com/history/cup/* // @grant none // @downloadURL none // ==/UserScript== (function () { /* --------------------------- STORE --------------------------- */ const championsBySeason = new Map(); // season -> {id, nth} const championIdOfSeason = new Map(); // season -> clubId (raw, before nth calc) const titleCounter = new Map(); // clubId -> running nth counter const clubNameById = new Map(); // clubId -> latest name const cupChampTotal = new Map(); // clubId -> #champion const cupRunnerTotal = new Map(); // clubId -> #runner‑up const lastSeasonAppear = new Map(); // clubId -> most recent season they reached final /* --------------------------- HELPERS ------------------------- */ const inc = (map, key) => map.set(key, (map.get(key) || 0) + 1); function ensureRightColumn() { let column = document.querySelector('div.column3_a'); if (!column) { const old = document.querySelector('div.column3'); if (old) old.parentNode.removeChild(old); column = document.createElement('div'); column.className = 'column3_a'; const centers = document.querySelectorAll('div.main_center'); const target = centers[centers.length === 4 ? 3 : 2]; target.appendChild(column); } return column; } function renderTables() { /* Champions by season table (desc) */ const seasonsDesc = Array.from(championsBySeason.keys()).sort((a,b)=>b-a); let championsHTML = ""; seasonsDesc.forEach((season,idx) => { const {id,nth} = championsBySeason.get(season); const name = clubNameById.get(id); const odd = (idx & 1) ? " class='odd'" : ""; championsHTML += ``; }); championsHTML += "
SeasonClubNth
${season}${name}${nth}
"; /* Hall of Fame */ const allIds = new Set([...cupChampTotal.keys(), ...cupRunnerTotal.keys()]); const hofList = Array.from(allIds).sort((a,b)=>{ const scoreB = (cupChampTotal.get(b)||0)*1000 + (cupRunnerTotal.get(b)||0); const scoreA = (cupChampTotal.get(a)||0)*1000 + (cupRunnerTotal.get(a)||0); if (scoreB !== scoreA) return scoreB - scoreA; // tie‑break by most recent appearance (descending season) return (lastSeasonAppear.get(b)||0) - (lastSeasonAppear.get(a)||0); }); let hofHTML = ""; hofList.forEach((id,index)=>{ const name = clubNameById.get(id); const c = cupChampTotal.get(id)||''; const r = cupRunnerTotal.get(id)||''; const odd = (index & 1) ? " class='odd'" : ""; hofHTML += ``; }); hofHTML += "
#Club#1#2
${index+1}${name}${c}${r}
"; /* inject */ const col = ensureRightColumn(); if (!document.getElementById('tmvn_cup_champions')) { col.insertAdjacentHTML('beforeend', `

CHAMPION LIST

${championsHTML}
`); } else { document.querySelector('#tmvn_cup_champions .box_body').innerHTML = `
${championsHTML}`; } if (!document.getElementById('tmvn_cup_hof')) { col.insertAdjacentHTML('beforeend', `

HALL OF FAME

${hofHTML}
`); } else { document.querySelector('#tmvn_cup_hof .box_body').innerHTML = `
${hofHTML}`; } } /* --------------------------- SCAN --------------------------- */ const currentSeason = parseInt(document.querySelector('#top_menu a.none.white.small').innerText.split(/(\s+)/)[2],10); const country = location.href.split('/')[5]; let scanned = 0; for (let season = 1; season < currentSeason; season++) { $.ajax(`https://trophymanager.com/history/cup/${country}/${season}`, { type: 'GET', dataType: 'html', crossDomain: true, success: response => { const final = $('.match_list.border_bottom li', response)[0]; if (final) { const a = final.querySelectorAll('a'); const id1 = a[0].getAttribute('club_link'); const id2 = a[2].getAttribute('club_link'); const name1 = a[0].innerText; const name2 = a[2].innerText; clubNameById.set(id1, name1); clubNameById.set(id2, name2); const [s1,s2] = a[1].innerText.split('-').map(n=>parseInt(n,10)); const champId = s1 > s2 ? id1 : id2; const runId = s1 > s2 ? id2 : id1; championIdOfSeason.set(season, champId); // save raw champ -> compute nth later inc(cupChampTotal, champId); inc(cupRunnerTotal, runId); lastSeasonAppear.set(champId, season); lastSeasonAppear.set(runId, season); } if (++scanned === currentSeason-1) finalize(); }, error: () => { if (++scanned === currentSeason-1) finalize(); } }); } function finalize() { /* compute nth titles in chronological order to avoid async issues */ const seasonsAsc = Array.from(championIdOfSeason.keys()).sort((a,b)=>a-b); seasonsAsc.forEach(season=>{ const champId = championIdOfSeason.get(season); if (!champId) return; inc(titleCounter, champId); const nth = titleCounter.get(champId); championsBySeason.set(season, {id: champId, nth}); }); renderTables(); } })();