您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Nitro Type Current Race Tracker w/ Leagues and NT Comps WIP
当前为
// ==UserScript== // @name Nitro Type Current Race Tracker w/ Leagues and NT Comps // @version 1.3 // @description Nitro Type Current Race Tracker w/ Leagues and NT Comps WIP // @author TensorFlow - Dvorak // @match *://*.nitrotype.com/race // @match *://*.nitrotype.com/race/* // @grant none // @require https://cdnjs.cloudflare.com/ajax/libs/dexie/3.2.1/dexie.min.js#sha512-ybuxSW2YL5rQG/JjACOUKLiosgV80VUfJWs4dOpmSWZEGwdfdsy2ldvDSQ806dDXGmg9j/csNycIbqsrcqW6tQ== // @require https://gf.qytechs.cn/scripts/443718-nitro-type-userscript-utils/code/Nitro%20Type%20Userscript%20Utils.js?version=1042360 // @license MIT // @namespace https://gf.qytechs.cn/users/1331131-tensorflow-dvorak // ==/UserScript== /* globals Dexie findReact createLogger */ const logging = createLogger("Nitro Type Racer IDs Extractor"); // Config storage const db = new Dexie("NTRacerIDsExtractor"); db.version(1).stores({ users: "id, &username, team, displayName, status, league", }); db.open().catch(function (e) { logging.error("Init")("Failed to open up the config database", e); }); //Race if (window.location.pathname === "/race" || window.location.pathname.startsWith("/race/")) { const raceContainer = document.getElementById("raceContainer"); const raceObj = raceContainer ? findReact(raceContainer) : null; if (!raceContainer || !raceObj) { logging.error("Init")("Could not find the race container or race object"); return; } if (!raceObj.props.user.loggedIn) { logging.error("Init")("Extractor is not available for Guest Racing"); return; } const displayedUserIDs = new Set(); const leagueTierText = { 0: "None", 1: "Learner", 2: "Novice", 3: "Rookie", 4: "Pro", 5: "Ace", 6: "Expert", 7: "Champion", 8: "Master", 9: "Epic", 10: "Legend", 11: "Tournament", 12: "Semi-Finals", 13: "Finals" }; function createLeagueInfoUI() { const leagueInfoContainer = document.createElement("div"); leagueInfoContainer.id = "league-info-container"; leagueInfoContainer.style.zIndex = "1000"; leagueInfoContainer.style.backgroundColor = "rgba(0, 0, 0, 0.85)"; leagueInfoContainer.style.color = "#fff"; leagueInfoContainer.style.padding = "15px"; leagueInfoContainer.style.borderRadius = "8px"; leagueInfoContainer.style.fontFamily = "'Nunito', sans-serif"; leagueInfoContainer.style.fontSize = "14px"; leagueInfoContainer.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.1)"; leagueInfoContainer.style.width = "100%"; leagueInfoContainer.style.overflowY = "auto"; leagueInfoContainer.style.maxHeight = "70vh"; leagueInfoContainer.innerHTML = ` <h2 style="margin: 0 0 10px; font-size: 18px; border-bottom: 1px solid #ccc; padding-bottom: 5px;">Racers' League Info</h2> <table id='league-info-table' style="width: 100%; border-collapse: collapse; text-align: left;"> <thead> <tr style="border-bottom: 1px solid #444;"> <th style="padding: 5px; color: #f4b400;">Name</th> <th style="padding: 5px; color: #e74c3c;">Level</th> <th style="padding: 5px; color: #0f9d58;">League</th> <th style="padding: 5px; color: #4285f4;">Session Races</th> <th style="padding: 5px; color: #ff5722;">Races This Week</th> </tr> </thead> <tbody id='league-info-list' style="color: #ddd;"></tbody> </table> `; const targetElement = document.querySelector("#raceContainer"); if (targetElement) { targetElement.appendChild(leagueInfoContainer); } else { document.body.appendChild(leagueInfoContainer); } } function fetchAdditionalData(username, listItem) { const proxyUrl = 'https://api.allorigins.win/get?url='; const targetUrl = `https://www.ntcomps.com/racers/${username}`; fetch(`${proxyUrl}${encodeURIComponent(targetUrl)}`) .then(response => response.json()) .then(data => { const parser = new DOMParser(); const doc = parser.parseFromString(data.contents, "text/html"); const foundIndicator = "<td>This week</td>"; if (!data.contents.includes(foundIndicator)) { listItem.querySelector('.races-this-week').textContent = 'N/A'; return; } let racesCompleted = doc.querySelector('tr:nth-child(3) td:nth-child(2)').textContent.trim(); racesCompleted = racesCompleted.replace(/,/g, ''); let racesCompletedInt = parseInt(racesCompleted, 10); if (isNaN(racesCompletedInt) || racesCompletedInt > 100000) { racesCompleted = 'N/A'; } else { racesCompleted = racesCompletedInt.toLocaleString(); } listItem.querySelector('.races-this-week').textContent = racesCompleted; }) .catch(error => { console.error('Error fetching additional data:', error); listItem.querySelector('.races-this-week').textContent = 'N/A'; }); } function updateLeagueInfoUI(user) { const leagueInfoList = document.getElementById("league-info-list"); if (!leagueInfoList || displayedUserIDs.has(user.userID)) return; displayedUserIDs.add(user.userID); const listItem = document.createElement("tr"); const leagueText = leagueTierText[user.profile.leagueTier] || "Unknown"; listItem.style.borderBottom = "1px solid #444"; listItem.style.fontWeight = "bold"; listItem.innerHTML = ` <td style="padding: 5px; color: #f4b400;">${user.profile.displayName}</td> <td style="padding: 5px; color: #e74c3c;">${user.profile.level}</td> <td style="padding: 5px; color: #0f9d58;">${leagueText}</td> <td style="padding: 5px; color: #4285f4;">${user.profile.sessionRaces}</td> <td style="padding: 5px; color: #ff5722;" class="races-this-week">Loading...</td> `; leagueInfoList.appendChild(listItem); fetchAdditionalData(user.profile.userID, listItem); } function logPlayerIDsAndLeagues() { const server = raceObj.server; server.on("joined", (user) => { if (!user.robot) { updateLeagueInfoUI(user); } }); server.on("update", (e) => { if (e && e.racers) { e.racers.forEach((racer) => { if (!racer.robot && !displayedUserIDs.has(racer.userID)) { updateLeagueInfoUI(racer); } }); } }); } function initializeRaceObj() { const raceContainer = document.getElementById("raceContainer"); if (raceContainer) { createLeagueInfoUI(); logPlayerIDsAndLeagues(); const resultObserver = new MutationObserver(([mutation], observer) => { for (const node of mutation.addedNodes) { if (node.classList?.contains("race-results")) { observer.disconnect(); logging.info("Update")("Race Results received"); const leagueInfoContainer = document.getElementById("league-info-container"); const targetElement = document.querySelector("#raceContainer").parentElement; if (leagueInfoContainer && targetElement) { targetElement.appendChild(leagueInfoContainer); } break; } } }); resultObserver.observe(raceContainer, { childList: true, subtree: true }); } else { logging.error("Init")("Race container not found, retrying..."); setTimeout(initializeRaceObj, 1000); } } window.addEventListener("load", initializeRaceObj); }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址