Auto Scavenger with optimizer

Script Auto Scavenging for Tribal Wars single village.

// ==UserScript==
// @name         Auto Scavenger with optimizer
// @namespace    http://tampermonkey.net/
// @version      3.1
// @description  Script Auto Scavenging for Tribal Wars single village.
// @author       MrNobody97
// @match        *://*/*game.php?*screen=place&mode=scavenge
// @grant        unsafeWindow
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// @license MIT
// ==/UserScript==


(function () {
    'use strict';

    // Costanti per lo stato
    const STATE_START = 'start';
    const STATE_STOP = 'stop';

    // Variabile per il timer
    let timerInterval = null;

    // Attendi che la pagina sia completamente caricata
    window.addEventListener('load', function () {
        console.log('Pagina completamente caricata, aggiungo la UI...');
        addUI(); // Aggiungi la UI dopo il caricamento della pagina
        restoreState(); // Ripristina lo stato salvato
    });

    // Configura jQuery per caricare script
    $.ajaxSetup({ dataType: 'script' });

    // Carica lo script esterno
    $.getScript('https://cdn.jsdelivr.net/gh/MrNobody97/wewe@main/outstanding_organizer.js')
        .done(function () {
            console.log('Script outstanding_organizer.js caricato con successo!');
        })
        .fail(function (jqxhr, settings, exception) {
            console.error('Errore durante il caricamento dello script:', exception);
        });

    // Funzione per aggiungere la UI
    function addUI() {
        // Crea un contenitore per la UI
        const uiContainer = document.createElement('div');
        uiContainer.id = 'scavengeUI'; // Usa l'ID specificato

        // Applica lo stile personalizzato (ripristinato alla posizione originale)
        uiContainer.style.position = 'fixed';
        uiContainer.style.left = '8%'; // Posizione originale
        uiContainer.style.top = '50%'; // Posizione originale
        uiContainer.style.transform = 'translateY(-50%)'; // Centrato verticalmente
        uiContainer.style.backgroundColor = 'rgba(245, 245, 245, 0.95)'; // Sfondo chiaro
        uiContainer.style.border = '1px solid #967444'; // Bordo marrone
        uiContainer.style.borderRadius = '4px'; // Bordi arrotondati
        uiContainer.style.padding = '8px'; // Spazio interno
        uiContainer.style.zIndex = '9999';
        uiContainer.style.width = '140px'; // Larghezza originale
        uiContainer.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)'; // Ombra leggera
        uiContainer.style.fontFamily = 'Arial, sans-serif'; // Font originale
        uiContainer.style.fontSize = '14px'; // Dimensione del font originale
        uiContainer.style.color = '#333'; // Testo scuro

        // Crea un pulsante "Start"
        const startButton = document.createElement('button');
        startButton.id = 'startButton';
        startButton.innerText = 'Start';
        startButton.style.width = '100%';
        startButton.style.padding = '5px'; // Spazio interno
        startButton.style.marginBottom = '10px'; // Margine inferiore
        startButton.style.cursor = 'pointer';
        startButton.style.backgroundColor = '#4CAF50'; // Verde
        startButton.style.color = '#fff'; // Testo bianco
        startButton.style.border = 'none';
        startButton.style.borderRadius = '4px'; // Bordi arrotondati
        startButton.onclick = function () {
            console.log('Pulsante Start cliccato, avvio il timer...');
            startAutomation();
        };

        // Crea un pulsante "Stop"
        const stopButton = document.createElement('button');
        stopButton.id = 'stopButton';
        stopButton.innerText = 'Stop';
        stopButton.style.width = '100%';
        stopButton.style.padding = '5px'; // Spazio interno
        stopButton.style.marginBottom = '10px'; // Margine inferiore
        stopButton.style.cursor = 'pointer';
        stopButton.style.backgroundColor = '#f44336'; // Rosso
        stopButton.style.color = '#fff'; // Testo bianco
        stopButton.style.border = 'none';
        stopButton.style.borderRadius = '4px'; // Bordi arrotondati
        stopButton.onclick = function () {
            console.log('Pulsante Stop cliccato, interrompo il timer...');
            stopAutomation();
        };

        // Crea un elemento per visualizzare il timer di avvio
        const timerElement = document.createElement('div');
        timerElement.id = 'timer';
        timerElement.innerText = 'Avvio tra: 10 secondi';
        timerElement.style.marginBottom = '10px'; // Margine inferiore
        timerElement.style.fontWeight = 'bold';
        timerElement.style.textAlign = 'center'; // Allineamento al centro

        // Crea un elemento per visualizzare l'orario del prossimo refresh
        const refreshTimeElement = document.createElement('div');
        refreshTimeElement.id = 'refresh-time';
        refreshTimeElement.innerText = 'Prossimo refresh: calcolo...';
        refreshTimeElement.style.fontWeight = 'bold';
        refreshTimeElement.style.textAlign = 'center'; // Allineamento al centro

        // Aggiungi gli elementi al contenitore
        uiContainer.appendChild(startButton);
        uiContainer.appendChild(stopButton);
        uiContainer.appendChild(timerElement);
        uiContainer.appendChild(refreshTimeElement);

        // Aggiungi il contenitore al corpo della pagina
        document.body.appendChild(uiContainer);
        console.log('UI aggiunta con successo!');
    }

    // Funzione per ripristinare lo stato salvato
    function restoreState() {
        const savedState = localStorage.getItem('scavengeState');
        if (savedState === STATE_START) {
            console.log('Ripristino lo stato: Start');
            toggleButtons(true); // Mostra "Stop" e nascondi "Start"
            startAutomationAfterDelay(); // Avvia il timer
        } else {
            console.log('Ripristino lo stato: Stop');
            toggleButtons(false); // Mostra "Start" e nascondi "Stop"
        }
    }

    // Funzione per alternare la visibilità dei pulsanti
    function toggleButtons(isStart) {
        const startButton = document.getElementById('startButton');
        const stopButton = document.getElementById('stopButton');
        if (isStart) {
            startButton.style.display = 'none'; // Nascondi "Start"
            stopButton.style.display = 'block'; // Mostra "Stop"
        } else {
            startButton.style.display = 'block'; // Mostra "Start"
            stopButton.style.display = 'none'; // Nascondi "Stop"
        }
    }

    // Funzione per avviare l'automazione
    function startAutomation() {
        // Salva lo stato "Start" nel localStorage
        localStorage.setItem('scavengeState', STATE_START);

        // Mostra "Stop" e nascondi "Start"
        toggleButtons(true);

        // Avvia il timer
        startAutomationAfterDelay();
    }

    // Funzione per interrompere l'automazione
    function stopAutomation() {
        // Salva lo stato "Stop" nel localStorage
        localStorage.setItem('scavengeState', STATE_STOP);

        // Mostra "Start" e nascondi "Stop"
        toggleButtons(false);

        // Interrompi il timer
        if (timerInterval) {
            clearInterval(timerInterval);
            timerInterval = null;
        }

        // Resetta il timer nella UI
        const timerElement = document.getElementById('timer');
        if (timerElement) {
            timerElement.innerText = 'Avvio tra: 10 secondi';
        }
    }

    // Funzione per avviare l'automazione dopo un ritardo
    function startAutomationAfterDelay() {
        const delay = 10000; // Ritardo di 10 secondi (puoi modificare questo valore)
        let timeLeft = delay / 1000; // Tempo rimanente in secondi

        // Aggiorna il timer ogni secondo
        timerInterval = setInterval(() => {
            timeLeft -= 1;
            const timerElement = document.getElementById('timer');
            if (timerElement) {
                timerElement.innerText = `Avvio tra: ${timeLeft} secondi`;
            }

            // Se il tempo è scaduto, avvia l'automazione e ferma il timer
            if (timeLeft <= 0) {
                clearInterval(timerInterval);
                timerInterval = null;
                automateScavenging();
            }
        }, 1000);
    }

    // Funzione principale per automatizzare le azioni
    async function automateScavenging() {
        console.log("Avvio automazione...");

        // 1. Clicca su "All troops"
        if (await clickButtonWithRetry("All troops", 3)) {
            console.log("Cliccato su 'All troops'");
            await wait(5000); // Attendi 5 secondi (invece di 3)
        } else {
            console.error("Pulsante 'All troops' non trovato dopo 3 tentativi!");
            return;
        }

        // 2. Clicca su "Distribute"
        if (await clickButtonWithRetry("Distribute", 3)) {
            console.log("Cliccato su 'Distribute'");
            await wait(5000); // Attendi 5 secondi (invece di 3)
        } else {
            console.error("Pulsante 'Distribute' non trovato dopo 3 tentativi!");
            return;
        }

        // 3. Clicca sui pulsanti "Fill" per i livelli attivi
        await clickFillButtons(); // Attendiamo il completamento della funzione
        await wait(5000); // Attendi 5 secondi (invece di 3)

        console.log("Automazione completata!");

        // Programma il refresh della pagina dopo un intervallo casuale tra 8 e 12 minuti
        schedulePageRefresh();
    }

    // Funzione per cliccare un pulsante con tentativi ripetuti
    async function clickButtonWithRetry(buttonText, maxRetries) {
        for (let i = 0; i < maxRetries; i++) {
            if (clickButton(buttonText)) {
                return true; // Pulsante trovato e cliccato
            }
            console.log(`Tentativo ${i + 1} fallito per il pulsante: ${buttonText}`);
            await wait(4000); // Attendi 4 secondi (invece di 2)
        }
        return false; // Pulsante non trovato dopo i tentativi
    }

    // Funzione per cliccare un pulsante in base al testo
    function clickButton(buttonText) {
        const buttons = document.querySelectorAll("button, a");
        for (const button of buttons) {
            if (button.innerText.trim() === buttonText && !button.disabled) {
                console.log(`Trovato pulsante: ${buttonText}`);
                button.click();
                return true; // Pulsante trovato e cliccato
            }
        }
        console.error(`Pulsante non trovato: ${buttonText}`);
        return false; // Pulsante non trovato
    }

    // Funzione per cliccare sui pulsanti "Fill" e procedere con lo "Start" dopo 4 secondi
    async function clickFillButtons() {
        console.log("Clicco sui pulsanti 'Fill'...");

        const fillButtons = document.querySelectorAll("button.btn[title='Fill']:not(.btn-disabled)");
        if (fillButtons.length === 0) {
            console.error("Nessun pulsante 'Fill' attivo trovato!");
            return;
        }

        for (let i = 0; i < fillButtons.length; i++) {
            const button = fillButtons[i];
            console.log(`Tentativo di clic su: ${button.innerText.trim()} (indice ${i})`);
            try {
                button.click(); // Simula il clic sul pulsante
                console.log(`Cliccato su: ${button.innerText.trim()} (indice ${i})`);

                // Attendi 4 secondi dopo il "Fill" (invece di 2)
                await wait(4000);

                // Procedi con lo "Start" del livello
                await clickStartButtons();
            } catch (error) {
                console.error(`Errore durante il clic su ${button.innerText.trim()}:`, error);
            }
        }
    }

    // Funzione per attendere un determinato tempo
    function wait(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // Funzione per cliccare sui pulsanti "Inizia" e attendere il completamento
    async function clickStartButtons() {
        console.log("Clicco sui pulsanti 'Inizia'...");

        const levels = [
            { level: 1, title: "Razziatore svogliato", selector: "a.free_send_button:not([disabled])" },
            { level: 2, title: "Trasportatori Umili", selector: "a.free_send_button:not([disabled])" },
            { level: 3, title: "Rovistamento astuto", selector: "a.free_send_button:not([disabled])" },
            { level: 4, title: "Ottimi Raccoglitori", selector: "a.free_send_button:not([disabled])" }
        ];

        for (const level of levels) {
            const levelContainer = findLevelContainer(level.title);
            if (levelContainer) {
                console.log(`Trovato contenitore per il livello: ${level.title}`);
                const startButton = levelContainer.querySelector(level.selector);
                if (startButton) {
                    console.log(`Tentativo di clic su: ${level.title} (Livello ${level.level})`);
                    try {
                        startButton.click(); // Simula il clic sul pulsante
                        console.log(`Cliccato su: ${level.title} (Livello ${level.level})`);

                        // Attendi che l'operazione di "Start" sia completata
                        await waitForStartCompletion();
                    } catch (error) {
                        console.error(`Errore durante il clic su ${level.title}:`, error);
                    }
                } else {
                    console.error(`Pulsante "Inizia" non trovato o disabilitato per il livello: ${level.title}`);
                }
            } else {
                console.error(`Contenitore del livello non trovato: ${level.title}`);
            }
        }
    }

// Funzione per attendere il completamento dello "Start"
async function waitForStartCompletion() {
    console.log("Attendo il completamento dello 'Start'...");

    const maxWaitTime = 5000; // Tempo massimo di attesa: 5 secondi
    const startTime = Date.now();

    while (Date.now() - startTime < maxWaitTime) {
        const confirmationMessage = document.querySelector(".confirmation-message");
        if (confirmationMessage && confirmationMessage.innerText.includes("Missione avviata")) {
            console.log("Operazione di 'Start' completata!");
            return;
        }
        await wait(500); // Controlla ogni 500 millisecondi
    }

    console.log("Timeout: procedo senza conferma dello 'Start'.");
}

    // Funzione per trovare il contenitore di un livello in base al titolo
    function findLevelContainer(levelTitle) {
        const titles = document.querySelectorAll("div.title");
        for (const title of titles) {
            if (title.innerText.trim() === levelTitle) {
                return title.closest("div.scavenge-option"); // Restituisce il contenitore del livello
            }
        }
        return null; // Livello non trovato
    }

    // Funzione per programmare il refresh della pagina
    function schedulePageRefresh() {
        const randomTime = Math.floor(Math.random() * (12 - 8 + 1) + 8) * 60000; // Tempo casuale tra 8 e 12 minuti
        const refreshTime = new Date(Date.now() + randomTime);

        // Aggiorna l'UI con l'orario del prossimo refresh
        const refreshTimeElement = document.getElementById('refresh-time');
        if (refreshTimeElement) {
            refreshTimeElement.innerText = `Prossimo refresh: ${refreshTime.toLocaleTimeString()}`;
        }

        console.log(`Riavvio della pagina alle ${refreshTime.toLocaleTimeString()}...`);
        setTimeout(() => {
            window.location.reload();
        }, randomTime);
    }
})();