您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
See the Leaderboard of an e-sim Tournament
当前为
// ==UserScript== // @name eSim Event Leaderboard // @namespace eSim-Events // @version 0.9.1 // @description See the Leaderboard of an e-sim Tournament // @author gg // @include https://*.e-sim.org/tournamentEvent.html?id=* // @include https://*.e-sim.org/teamTournament.html?id=* // @include https://*.e-sim.org/countryTournament.html?id=* // @icon https://cdn.discordapp.com/icons/316566483021070356/cfffdee309ec53078e9a9698ec4eef42.png?size=256 // @grant none // ==/UserScript== // I could only test finished Events, there were no running Events on any Server // ! If you are running it for Country Tournament results, make sure you are on the 'SCHEDULER' TAB (/countryTournament.html?id=37#slideShedule) // Country Tournaments have a lot Battles, therefore it takes much longer than other Events, however, // if the Status color is not changing for +5s either your Internet or the E-sim is slow. // Global variables const eventBattleIds = [] // This will store all the Battle ids the Event has [ 7732, 7733, ...] const jsonEventResults = {} // This will store all Player that have participated {123(Player Id): Object { damage: 123456, q5Weapons: 1234 }} let newTab // pre-defining the new Tab that will be opened let indexStatus = 0 // Index for color changing // sleep function function delay (ms) { return new Promise((resolve) => setTimeout(resolve, ms)) } (function () { // create and place Button, then wait for button press and call main func const btn = document.createElement('BUTTON') const place = document.getElementsByClassName('testDivwhite')[0] place.after(btn) btn.style = 'font-size: 15px' btn.innerText = 'Leaderboard' btn.addEventListener('click', function () { main() }) })() // This function will get called when the Button is pressed. async function main () { // Try to find all Battlinks. if ((await findAllBattleLinks()) !== false) { // The function findAllBattleLinks didn't return false. which means battle links have been found successfully createNewTabAndWriteHTML() // Create a new Empty Tab inject some HTML // Loop through every Battle for (let index = 0; index < eventBattleIds.length; index++) { const battleId = eventBattleIds[index] await calcDamageDoneInBattle(battleId) // Check which Player hit in that Battle and how much damage they have done. } // All Battle have been looped through. Now sort the Array, highest dmg first. // copied from https://stackoverflow.com/questions/1069666/sorting-object-property-by-values const sortable = [] for (const player in jsonEventResults) { sortable.push([ player, jsonEventResults[player].damage, jsonEventResults[player].q5Weapons, jsonEventResults[player].q1Weapons ]) } sortable.sort(function (a, b) { return b[1] - a[1] }) // Now update the new Tab with the sorted results await updateLeaderboard(sortable) } else { // No Battle links could be found > raise an Alert alert( 'Do not press the Button before the Page has fully loaded and make sure that you are on the page where you self can see the Battles.\nFor County Tournament it should be the "SCHEDULER" Tab' ) } } async function findAllBattleLinks () { // Find all elements <a class="battle-links" href="/battle.html?id=123"> let arrayOfBattleLinkElements = document.querySelectorAll('.battle-link') /* Some Events are coded different than others... If no Battles could be find with 'battle-link' class names, it will instead look for elements with 'cup-final-scores' class Names Note: This option can find elements that aren't Battle link */ if (arrayOfBattleLinkElements.length === 0) { const cupTable = document.getElementsByClassName('cup-final-scores')[0] // If this also doesn't find anything it will stop here and raise an Alert if (cupTable === undefined) { return false } arrayOfBattleLinkElements = cupTable.getElementsByTagName('a') } /* Loop through all elements in the Array and get their href link Check if it starts with 'battle.html?id=' and if so, remove that part, which leaves only the id behind. Finally, append the id to eventBattleIds */ for (const element of arrayOfBattleLinkElements) { const link = element.getAttribute('href') if (link.startsWith('battle')) { const battleId = link.replace('battle.html?id=', '') if (!eventBattleIds.includes(battleId)) { eventBattleIds.push(battleId) } } } // If none of the elements were battleLinks -> stop here and raise an Alert if (eventBattleIds.length === 0) { return false } // Sort the eventBattleIds Array eventBattleIds.sort(function (a, b) { return a - b }) } function createNewTabAndWriteHTML () { newTab = window.open('') // open a blank tab let title // Change the Tab Title to the Event Type. (Again, eSim has been coded so terribly that I need to do try-catch..) try { title = document.getElementsByTagName('h1')[1].innerText } catch { title = document.getElementsByClassName('tournament-state-info')[0] .innerText } // ? https://forum.freecodecamp.org/t/how-to-open-a-blank-tab-and-insert-js/158289/3 // ? Doesn't seem to be the so great, but works for now. // TODO figure something else out newTab.document.write(` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <style> h1 { display: inline-block; margin-right: 5px; } #dot { height: 25px; width: 25px; background-color: white; border-radius: 50%; display: inline-block; } </style> <body style="text-align: center; background-color: #333333; color:white"> <div id="info">Important:<br />If the Status Color is changing, the script is still running<br /> If the Colors don't change, the Server/your Internet might be slow<br/> Do <strong style="color: red">not</strong> refresh any e-sim page. <br />Do <strong style="color: red">not</strong> fight. </div> <div style="text-align:center"> <h1>Status: </h1> <span id="dot"></span> </div> <h1>Rankings</h1> <table id="leaderboard" style="margin: auto;"> <tr id="table-header"> <th>#</th> <th>Player</th> <th>Damage</th> <th>Q5 Weapons</th> <th>Q1 Weapons</th> </tr> </table> </body> </html>`) newTab.document.title = title } /* Check all hits done in a Battle. Add up how much damage every Player did and how many weapons they used. API Request -> loop through all hits -> Create a new Object if its the Players first hit (ex. { damage: 123456, q5Weapons: 5 } else add up the damage and weps used.) */ async function calcDamageDoneInBattle (battleId) { const currentBattleStats = {} const jsonApiFights = await sendApiRequest( '/apiFights.html?battleId=' + battleId) for (const hit of jsonApiFights) { const citizenId = hit.citizenId const berserkAndWepQ = checkWeaponQualityAndIfBerserk(hit) let q1Wep = 0 let q5Wep = 0 if (berserkAndWepQ[0] === 5 && berserkAndWepQ[1] === 5) { // Berserk and Q5 q5Wep = 5 } else if (berserkAndWepQ[0] === 1 && berserkAndWepQ[1] === 5) { // Single Hit and Q5 q5Wep = 1 } else if (berserkAndWepQ[0] === 5 && berserkAndWepQ[1] === 1) { // Berserk and Q1 q1Wep = 5 } else if (berserkAndWepQ[0] === 1 && berserkAndWepQ[1] === 1) { // Single hit and Q1 q1Wep = 1 } if (citizenId in currentBattleStats) { currentBattleStats[citizenId].damage += hit.damage currentBattleStats[citizenId].q5Weapons += q5Wep currentBattleStats[citizenId].q1Weapons += q1Wep } else { currentBattleStats[citizenId] = { damage: hit.damage, q5Weapons: q5Wep, q1Weapons: q1Wep } } } await addCitizensToFinalStats(currentBattleStats) } // Fetch the API async function sendApiRequest (url) { console.log(url) changeStatusColor() let response let jsonResponse try { response = await fetch(url) // send api request jsonResponse = await response.json() // wait for server to return the json api return jsonResponse } catch (err) { /* An can error occur if you do to many requests), simply wait 3secs and then do the same request again */ await delay(3000) response = await fetch(url) jsonResponse = await response.json() return jsonResponse } } function changeStatusColor () { const dotElement = newTab.document.getElementById('dot') if (indexStatus === 0 || indexStatus === 6) { dotElement.style = 'background-color: #E50000' indexStatus = 1 } else if (indexStatus === 1) { dotElement.style = 'background-color: #FF8D00' indexStatus = 2 } else if (indexStatus === 2) { dotElement.style = 'background-color: #FFEE00' indexStatus = 3 } else if (indexStatus === 3) { dotElement.style = 'background-color: #008121' indexStatus = 4 } else if (indexStatus === 4) { dotElement.style = 'background-color: #004CFF' indexStatus = 5 } else if (indexStatus === 5) { dotElement.style = 'background-color: #760188' indexStatus = 6 } } // Check if the Player has used Q5 Weapons and did a 'Berserk' function checkWeaponQualityAndIfBerserk (hit) { if (hit.berserk) { if (hit.weapon === 5) { return [5, 5] } else if (hit.weapon === 1) { return [5, 1] } else { return [5, 0] } } else { if (hit.weapon === 5) { return [1, 5] } else if (hit.weapon === 1) { return [1, 1] } else { return [1, 0] } } } // After one Battle has been checked and calculated which Player did how much damage -> Merge the Results together with the other Battles. Until all Battles are checked. async function addCitizensToFinalStats (playersToAdd) { for (const player in playersToAdd) { if (player in jsonEventResults) { jsonEventResults[player].damage += playersToAdd[player].damage jsonEventResults[player].q5Weapons += playersToAdd[player].q5Weapons jsonEventResults[player].q1Weapons += playersToAdd[player].q1Weapons } else { jsonEventResults[player] = { damage: playersToAdd[player].damage, q5Weapons: playersToAdd[player].q5Weapons, q1Weapons: playersToAdd[player].q1Weapons } } } } async function updateLeaderboard (finalResults) { const lb = newTab.document.getElementById('leaderboard') let i = 1 for (const element of finalResults) { const newRow = newTab.document.createElement('tr') const newCellPlace = newTab.document.createElement('th') const newCellPlayer = newTab.document.createElement('th') const newCellDamage = newTab.document.createElement('th') const newCellQ5Weapons = newTab.document.createElement('th') const newCellQ1Weapons = newTab.document.createElement('th') newCellPlace.innerText = i let citizen = element[0] if (i < 16) { const citizenApi = await sendApiRequest( '/apiCitizenById.html?id=' + element[0] ) citizen = citizenApi.login } newCellPlayer.innerText = citizen newCellDamage.innerText = element[1].toLocaleString('de') newCellQ5Weapons.innerText = element[2].toLocaleString('fr') newCellQ1Weapons.innerText = element[3].toLocaleString('fr') lb.append(newRow) newRow.append(newCellPlace, newCellPlayer, newCellDamage, newCellQ5Weapons, newCellQ1Weapons) i++ } indexStatus = 3 changeStatusColor() location.reload() }