Auto Scavenger with optimizer

Script Auto Scavenging for Tribal Wars single village.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==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);
    }
})();