Auto Scavenger with optimizer

Script Auto Scavenging for Tribal Wars single village.

目前為 2025-01-10 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Auto Scavenger with optimizer
// @namespace    http://tampermonkey.net/
// @version      2.6
// @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
        uiContainer.style.position = 'fixed';
        uiContainer.style.left = '8%';
        uiContainer.style.top = '50%';
        uiContainer.style.transform = 'translateY(-50%)';
        uiContainer.style.backgroundColor = 'rgba(245, 245, 245, 0.95)';
        uiContainer.style.border = '1px solid #967444';
        uiContainer.style.borderRadius = '4px';
        uiContainer.style.padding = '8px';
        uiContainer.style.zIndex = '9999';
        uiContainer.style.width = '140px';
        uiContainer.style.height = '140px';
        uiContainer.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
        uiContainer.style.fontFamily = 'Arial, sans-serif'; // Font leggibile
        uiContainer.style.fontSize = '14px'; // Dimensione del font
        uiContainer.style.color = '#333'; // Colore del testo

        // Crea un pulsante "Start"
        const startButton = document.createElement('button');
        startButton.id = 'startButton';
        startButton.innerText = 'Start';
        startButton.style.width = '100%';
        startButton.style.padding = '5px';
        startButton.style.marginBottom = '10px';
        startButton.style.cursor = 'pointer';
        startButton.style.backgroundColor = '#4CAF50'; // Colore verde
        startButton.style.color = '#fff'; // Testo bianco
        startButton.style.border = 'none';
        startButton.style.borderRadius = '4px';
        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';
        stopButton.style.marginBottom = '10px';
        stopButton.style.cursor = 'pointer';
        stopButton.style.backgroundColor = '#f44336'; // Colore rosso
        stopButton.style.color = '#fff'; // Testo bianco
        stopButton.style.border = 'none';
        stopButton.style.borderRadius = '4px';
        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';
        timerElement.style.fontWeight = 'bold';
        timerElement.style.textAlign = 'center'; // Allinea il testo 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'; // Allinea il testo 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(3000); // Attendi 3 secondi
        } 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(3000); // Attendi 3 secondi
        } 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(3000); // Attendi 3 secondi dopo i clic

        // 4. Clicca sui pulsanti "Inizia" per avviare le missioni
        await clickStartButtons(); // Attendiamo il completamento della funzione
        await wait(3000); // Attendi 3 secondi dopo i clic

        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(2000); // Attendi 2 secondi prima di riprovare
        }
        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" per i livelli attivi
    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})`);
            } catch (error) {
                console.error(`Errore durante il clic su ${button.innerText.trim()}:`, error);
            }

            // Aggiungi un ritardo tra i clic (ad esempio, 2 secondi)
            await wait(2000); // Ritardo di 2 secondi
        }
    }

    // Funzione per cliccare sui pulsanti "Inizia" per i livelli attivi
    async function clickStartButtons() {
        console.log("Clicco sui pulsanti 'Inizia'...");

        // Mappa dei livelli e dei loro titoli
        const levels = [
            { level: 1, title: "Razziatore svogliato", selector: "a.free_send_button:not([disabled])" }, // Livello 1
            { level: 2, title: "Trasportatori Umili", selector: "a.free_send_button:not([disabled])" },  // Livello 2
            { level: 3, title: "Rovistamento astuto", selector: "a.free_send_button:not([disabled])" },  // Livello 3
            { level: 4, title: "Ottimi Raccoglitori", selector: "a.free_send_button:not([disabled])" },  // Livello 4
            // Aggiungi altri livelli qui se necessario
        ];

        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})`);
                    } catch (error) {
                        console.error(`Errore durante il clic su ${level.title}:`, error);
                    }

                    // Aggiungi un ritardo tra i clic (ad esempio, 2 secondi)
                    await wait(2000); // Ritardo di 2 secondi
                } 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 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 attendere un determinato tempo
    function wait(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

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