您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automates scavenging in Tribal Wars.
// ==UserScript== // @name Auto Scavenging - Tutte le Unità // @namespace http://tampermonkey.net/ // @version 1.0.1 // @description Automates scavenging in Tribal Wars. // @author MrNobody97 // @match https://*.tribals.it/game.php?*screen=place&mode=scavenge* // @credit ricardofauch // @license MIT // ==/UserScript== (function () { 'use strict'; // Definizione delle unità const UNITS = [ { name: 'spear', label: 'Lanciere', include: true }, { name: 'sword', label: 'Spadaccino', include: false }, { name: 'axe', label: 'Guerrieri con Ascia', include: false }, { name: 'light', label: 'Cavalleria Leggera', include: false }, { name: 'heavy', label: 'Cavalleria Pesante', include: false }, { name: 'knight', label: 'Paladino', include: false }, ]; // Configurazione const CONFIG = { TOTAL_SPEARS: 100, // Lancieri totali MAX_SPEAR_PERCENTAGE: 1.00, // Percentuale massima di lancieri per run MIN_SPEARS_THRESHOLD: 20, // Minimo lancieri necessari UI_LOAD_DELAY: 6000, // Ritardo per il caricamento dell'UI INPUT_PROCESS_DELAY: 1000, // Ritardo dopo l'impostazione degli input INPUT_RETRY_DELAY: 200, // Ritardo tra i tentativi di input MAX_INPUT_RETRIES: 5, // Massimo numero di tentativi di input MIN_RELOAD_TIME: 8, // Tempo minimo di ricarica (minuti) MAX_RELOAD_TIME: 12, // Tempo massimo di ricarica (minuti) DEBUG: true // Abilita/disabilita il debug }; // Inietta gli stili CSS function injectStyles() { const styles = ` #scavengeUI { position: fixed; left: 8%; top: 50%; transform: translateY(-50%); background-color: rgba(245, 245, 245, 0.95); border: 1px solid #967444; border-radius: 4px; padding: 8px; z-index: 9999; width: 160px; height: auto; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } #scavengeUI .title { font-weight: bold; color: #784B25; font-size: 12px; margin-bottom: 10px; text-align: center; font-family: Arial, sans-serif; } #scavengeUI label { display: block; color: #5C3C1D; font-size: 11px; font-weight: bold; margin-bottom: 4px; font-family: Arial, sans-serif; text-align: center; } #scavengeUI input[type="number"] { width: 100%; padding: 4px; border: 1px solid #967444; background-color: white; color: #4A3011; border-radius: 2px; font-size: 12px; font-weight: bold; text-align: center; outline: none; box-sizing: border-box; margin-bottom: 10px; } #scavengeUI .checkbox-container { display: flex; align-items: center; justify-content: center; margin: 4px 0; padding: 4px; background-color: rgba(255, 255, 255, 0.5); border-radius: 2px; } #scavengeUI .checkbox-container input[type="checkbox"] { margin-right: 5px; } #scavengeUI input:focus { border-color: #784B25; box-shadow: 0 0 2px #967444; } #scavengeUI:hover { background-color: rgba(255, 255, 255, 0.98); } #debugOutput { margin-top: 10px; padding-top: 10px; font-family: Arial, sans-serif; font-size: 10px; color: #5C3C1D; } #nextReloadTime { margin-top: 8px; padding: 4px; background-color: rgba(255, 255, 255, 0.5); border-radius: 2px; text-align: center; font-size: 11px; font-weight: bold; color: #5C3C1D; } #startTimer { margin-top: 8px; padding: 4px; background-color: rgba(255, 255, 255, 0.5); border-radius: 2px; text-align: center; font-size: 11px; font-weight: bold; color: #5C3C1D; } .debug-entry { margin-bottom: 4px; padding: 2px; border-radius: 2px; } .debug-entry.info { color: #0066cc; } .debug-entry.warning { color: #cc6600; } .debug-entry.error { color: #cc0000; } .debug-entry.success { color: #006600; } `; const styleElement = document.createElement('style'); styleElement.textContent = styles; document.head.appendChild(styleElement); } // Crea l'interfaccia utente function createUI() { const ui = document.createElement('div'); ui.id = 'scavengeUI'; ui.innerHTML = ` <div class="title">Auto Scav</div> <label for="totalSpears">Lancieri Tot</label> <input type="number" id="totalSpears" min="0" step="1"> <div id="unitCheckboxes"></div> <div id="nextReloadTime">Refresh Pagina in: --:--</div> <div id="startTimer">Avvio tra: --:--</div> <div id="debugOutput"></div> `; document.body.appendChild(ui); // Aggiungi i checkbox per ogni unità const unitCheckboxes = document.getElementById('unitCheckboxes'); UNITS.forEach(unit => { const checkboxContainer = document.createElement('div'); checkboxContainer.className = 'checkbox-container'; checkboxContainer.innerHTML = ` <input type="checkbox" id="include${unit.name}" ${unit.include ? 'checked' : ''}> <label for="include${unit.name}">Includi ${unit.label}?</label> `; unitCheckboxes.appendChild(checkboxContainer); // Aggiungi event listener per salvare le preferenze const checkbox = checkboxContainer.querySelector(`#include${unit.name}`); checkbox.addEventListener('change', (e) => { unit.include = e.target.checked; localStorage.setItem(`scavengeInclude${unit.name}`, unit.include); debugLog(`Includi ${unit.label} aggiornato a: ${unit.include}`, 'info'); }); }); // Carica i valori salvati const totalSpearsInput = document.getElementById('totalSpears'); const savedSpears = localStorage.getItem('scavengeTotalSpears'); if (savedSpears) { CONFIG.TOTAL_SPEARS = parseInt(savedSpears); totalSpearsInput.value = CONFIG.TOTAL_SPEARS; } else { totalSpearsInput.value = CONFIG.TOTAL_SPEARS; } // Carica le preferenze delle unità UNITS.forEach(unit => { const savedSetting = localStorage.getItem(`scavengeInclude${unit.name}`); if (savedSetting !== null) { unit.include = savedSetting === 'true'; const checkbox = document.getElementById(`include${unit.name}`); if (checkbox) checkbox.checked = unit.include; } }); } // Log di debug function debugLog(message, type = 'info') { if (!CONFIG.DEBUG) return; const styles = { info: 'color: #0099ff; font-weight: bold;', warning: 'color: #ffa500; font-weight: bold;', error: 'color: #ff0000; font-weight: bold;', success: 'color: #00ff00; font-weight: bold;' }; const timestamp = new Date().toLocaleTimeString(); console.log(`%c[${timestamp}] ${message}`, styles[type]); // Aggiorna l'output di debug nell'UI const debugOutput = document.getElementById('debugOutput'); if (debugOutput) { const entry = document.createElement('div'); entry.className = `debug-entry ${type}`; entry.textContent = `[${timestamp}] ${message}`; debugOutput.insertBefore(entry, debugOutput.firstChild); // Mantieni solo gli ultimi 4 messaggi while (debugOutput.children.length > 4) { debugOutput.removeChild(debugOutput.lastChild); } } } // Funzione per aggiornare il timer di avvio function updateStartTimer(seconds) { const startTimerElement = document.getElementById('startTimer'); if (!startTimerElement) return; const minutes = Math.floor(seconds / 60); const secs = seconds % 60; startTimerElement.textContent = `Avvio tra: ${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`; if (seconds > 0) { setTimeout(() => updateStartTimer(seconds - 1), 1000); } else { startTimerElement.textContent = 'Avvio in corso...'; } } // Funzione principale per lo scavenging async function handleScavenging() { debugLog('=== Starting scavenging operation ===', 'info'); // Imposta il timer di avvio (es. 10 secondi) const startDelay = 10; // Tempo in secondi updateStartTimer(startDelay); // Attendi il tempo di avvio await new Promise(resolve => setTimeout(resolve, startDelay * 1000)); // Attendi il caricamento dell'UI await new Promise(resolve => setTimeout(resolve, CONFIG.UI_LOAD_DELAY)); // Trova i pulsanti di avvio const startButtons = Array.from(document.querySelectorAll('a.btn.free_send_button')); if (startButtons.length === 0) { debugLog('Nessun pulsante di avvio trovato!', 'error'); scheduleReload(); return; } // Trova il numero di unità disponibili const availableUnits = {}; UNITS.forEach(unit => { const unitLink = document.querySelector(`a.units-entry-all[data-unit="${unit.name}"]`); if (unitLink) { availableUnits[unit.name] = extractNumber(unitLink.textContent); debugLog(`${unit.label} disponibili: ${availableUnits[unit.name]}`, 'info'); } else { availableUnits[unit.name] = 0; debugLog(`${unit.label} non trovati!`, 'warning'); } }); // Verifica se ci sono abbastanza unità let hasEnoughUnits = false; UNITS.forEach(unit => { if (unit.include && availableUnits[unit.name] > 0) { hasEnoughUnits = true; } }); if (!hasEnoughUnits) { debugLog('Unità insufficienti, in attesa del prossimo ricaricamento', 'warning'); scheduleReload(); return; } // Calcola le unità da inviare const unitsToSend = {}; UNITS.forEach(unit => { if (unit.include) { unitsToSend[unit.name] = Math.min( availableUnits[unit.name], Math.floor(CONFIG.TOTAL_SPEARS / startButtons.length) ); debugLog(`${unit.label} da inviare: ${unitsToSend[unit.name]}`, 'info'); } }); // Trova e imposta gli input let allInputsSuccess = true; UNITS.forEach(unit => { if (unit.include) { const input = document.querySelector(`input[name="${unit.name}"].unitsInput.input-nicer`); if (input) { const success = setInputValueWithVerification(input, unitsToSend[unit.name]); if (!success) allInputsSuccess = false; } else { debugLog(`Input per ${unit.label} non trovato!`, 'error'); allInputsSuccess = false; } } }); if (!allInputsSuccess) { debugLog('Impossibile impostare i valori degli input, ricaricamento in corso...', 'error'); scheduleReload(); return; } // Clicca il pulsante di avvio const lastButton = startButtons[startButtons.length - 1]; debugLog('Cliccando il pulsante di avvio...', 'info'); lastButton.click(); // Ricarica la pagina setTimeout(() => { window.location.reload(); }, 1000); } // Funzione per estrarre numeri dal testo function extractNumber(text) { const match = text.match(/\((\d+)\)/); return match ? parseInt(match[1]) : 0; } // Funzione per impostare i valori degli input con verifica async function setInputValueWithVerification(input, value, retryCount = 0) { debugLog(`Tentativo ${retryCount + 1} per impostare ${input.name} a ${value}`, 'info'); input.value = value; input.dispatchEvent(new Event('input', { bubbles: true })); input.dispatchEvent(new Event('change', { bubbles: true })); await new Promise(resolve => setTimeout(resolve, CONFIG.INPUT_RETRY_DELAY)); if (input.value !== value.toString()) { debugLog(`Verifica fallita per ${input.name}! Valore attuale: ${input.value}`, 'warning'); if (retryCount < CONFIG.MAX_INPUT_RETRIES) { debugLog(`Riprova... (${retryCount + 1}/${CONFIG.MAX_INPUT_RETRIES})`, 'info'); return setInputValueWithVerification(input, value, retryCount + 1); } else { debugLog('Massimo numero di tentativi raggiunto!', 'error'); return false; } } debugLog(`${input.name} impostato correttamente`, 'success'); return true; } // Funzione per programmare il ricaricamento della pagina function scheduleReload() { const reloadTime = (Math.random() * (CONFIG.MAX_RELOAD_TIME - CONFIG.MIN_RELOAD_TIME) + CONFIG.MIN_RELOAD_TIME) * 60 * 1000; const nextReloadTime = new Date(Date.now() + reloadTime); const timeString = nextReloadTime.toLocaleTimeString('it-IT', { hour: '2-digit', minute: '2-digit' }); const nextReloadElement = document.getElementById('nextReloadTime'); if (nextReloadElement) { nextReloadElement.textContent = `Ricarico alle: ${timeString}`; } debugLog(`Prossimo ricaricamento alle: ${timeString}`, 'info'); setTimeout(() => { debugLog('Esecuzione del ricaricamento...', 'info'); window.location.reload(); }, reloadTime); } // Avvia lo script debugLog('=== Script inizializzato ===', 'info'); injectStyles(); createUI(); handleScavenging(); })();