Nitro Type Team Inviter

Automatically invites users to your team after a race, or adds as friend if team invite not available

От 09.03.2025. Виж последната версия.

// ==UserScript==
// @name         Nitro Type Team Inviter
// @namespace    https://www.nitrotype.com/
// @version      1.1
// @description  Automatically invites users to your team after a race, or adds as friend if team invite not available
// @author       Your Name
// @match        https://www.nitrotype.com/race/*
// @match        https://www.nitrotype.com/race
// @match        https://*.nitrotype.com/race
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    
    // Configuration
    const config = {
        minDelay: 50,  // Minimum delay in milliseconds
        maxDelay: 150, // Maximum delay in milliseconds
        debug: true    // Enable console logging for debugging
    };
    
    // Helper functions
    function log(message) {
        if (config.debug) console.log(`[Team Inviter] ${message}`);
    }
    
    function randomDelay() {
        return Math.floor(Math.random() * (config.maxDelay - config.minDelay + 1)) + config.minDelay;
    }
    
    // Main functions
    function findPlayerRows() {
        const selectors = [
            '.player-row', 
            '[class*="player-container"]', 
            '[class*="racer"]', 
            '[id*="racer"]', 
            '[id*="player"]',
            '[class*="player"]', 
            '.race-results-player'
        ];
        
        for (const selector of selectors) {
            const elements = document.querySelectorAll(selector);
            if (elements.length > 0) {
                log(`Found ${elements.length} player rows using selector: ${selector}`);
                return Array.from(elements);
            }
        }
        
        log("No player rows found with any selector");
        return [];
    }
    
    function simulateHover(element) {
        try {
            element.dispatchEvent(new MouseEvent('mouseenter', {bubbles: true, cancelable: true}));
            element.dispatchEvent(new MouseEvent('mouseover', {bubbles: true, cancelable: true}));
            return true;
        } catch (e) {
            log(`Error simulating hover: ${e.message}`);
            return false;
        }
    }
    
    function findAndClickButtons() {
        try {
            // Method 1: Try to find team invite button by text content
            const visibleInviteButtons = Array.from(document.querySelectorAll('a, button, .btn, [role="button"], div[class*="button"]'))
                .filter(el => {
                    const text = (el.textContent || '').toLowerCase();
                    const isVisible = el.offsetParent !== null;
                    const hasInviteText = text.includes('invite') && text.includes('team');
                    return isVisible && hasInviteText;
                });
            
            if (visibleInviteButtons.length > 0) {
                log("Clicking invite button found by text");
                visibleInviteButtons[0].click();
                return true;
            }
            
            // Method 2: Try to find team invite button by class name
            const specificButton = document.querySelector('a[class*="invite-team"], a[class*="team-invite"], [class*="invite-to-team"]');
            if (specificButton && specificButton.offsetParent !== null) {
                log("Clicking invite button found by class");
                specificButton.click();
                return true;
            }
            
            // Method 3: If no team invite button found, try Add As A Friend button
            const friendButtons = Array.from(document.querySelectorAll('a, button, .btn, [role="button"], div[class*="button"]'))
                .filter(el => {
                    const text = (el.textContent || '').toLowerCase();
                    const isVisible = el.offsetParent !== null;
                    return isVisible && text.includes('add') && text.includes('friend');
                });
            
            if (friendButtons.length > 0) {
                log("No team invite button found. Clicking Add As Friend instead");
                friendButtons[0].click();
                return true;
            }
            
            log("No invite or add friend buttons found");
            return false;
        } catch (e) {
            log(`Error finding/clicking buttons: ${e.message}`);
            return false;
        }
    }
    
    function reloadPage() {
        try {
            log("Reloading the page");
            document.body.dispatchEvent(new MouseEvent('mouseout', {bubbles: true, cancelable: true}));
            window.location.reload();
            return true;
        } catch (e) {
            log(`Error reloading page: ${e.message}`);
            return false;
        }
    }
    
    function processPlayerRows(rows, index = 0) {
        if (index >= rows.length) {
            log("Finished processing all player rows");
            setTimeout(reloadPage, randomDelay());
            return;
        }
        
        const row = rows[index];
        log(`Processing player row ${index + 1} of ${rows.length}`);
        
        // Hover over player row
        if (simulateHover(row)) {
            // Wait for button to appear, then try to click it
            setTimeout(() => {
                findAndClickButtons();
                
                // Continue to next player after a delay
                setTimeout(() => {
                    processPlayerRows(rows, index + 1);
                }, randomDelay());
            }, randomDelay());
        } else {
            // If hover fails, continue to next player
            setTimeout(() => {
                processPlayerRows(rows, index + 1);
            }, randomDelay());
        }
    }
    
    // Main function that checks for race results
    function checkForRaceResults() {
        const resultsCheckInterval = setInterval(() => {
            if (document.querySelector(".raceResults") || 
                document.querySelector("[class*='race-results']") ||
                document.querySelector(".race-results-container")) {
                
                log("Race results detected, starting team inviter");
                clearInterval(resultsCheckInterval);
                
                // Wait a moment for the UI to stabilize
                setTimeout(() => {
                    const playerRows = findPlayerRows();
                    if (playerRows.length > 0) {
                        processPlayerRows(playerRows);
                    } else {
                        log("No player rows found, reloading page");
                        reloadPage();
                    }
                }, 1000);
            }
        }, 500);
    }
    
    // Safety fallback to refresh if stuck
    function setupSafetyRefresh() {
        setTimeout(() => {
            log("Safety refresh triggered");
            window.location.reload();
        }, 120000); // 2 minutes timeout
    }
    
    // Initialize
    function initialize() {
        log("Team Inviter script initialized");
        checkForRaceResults();
        setupSafetyRefresh();
    }
    
    // Start the script
    if (document.readyState === "complete" || document.readyState === "interactive") {
        setTimeout(initialize, 1000);
    } else {
        document.addEventListener("DOMContentLoaded", initialize);
    }
})();