autoclickerscript

🧩 Syntax:
// ==UserScript==
// @name          TW Auto-Action (Hotkey & Externe Trigger)
// @namespace     TribalWars
// @version       3.35 // Version auf 3.35 aktualisiert - Statusleiste nun direkt neben den Buttons
// @description   Klickt den ersten FarmGod Button (A oder B) in zufälligem Intervall. Start/Stop per Tastenkombination (Standard: Shift+Strg+E) oder durch Aufruf von window.toggleTribalAutoAction(). Einstellungs-Button auf der Farm-Seite.
// @author        Idee PhilJor93 Generiert mit Google Gemini-KI
// @match         https://*.die-staemme.de/game.php?*
// @grant         none
// ==/UserScript==

(function() {
    'use strict';

    // *** AGGRESSIVER SCHUTZ VOR MEHRFACHAUSFÜHRUNG ***
    if (window.TW_AUTO_ENTER_INITIALIZED_MARKER === true) {
        return;
    }
    window.TW_AUTO_ENTER_INITIALIZED_MARKER = true;

    const SCRIPT_VERSION = '3.35'; // Die aktuelle Version des Skripts

    // Speichert den ursprünglichen Titel des Dokuments
    const originalDocumentTitle = document.title;

    // --- Sound-Profile Definitionen ---
    // Hier können weitere Sounds hinzugefügt oder bestehende angepasst werden
    const soundProfiles = {
        'default': { name: 'Standard (Hell)', frequency: 660, type: 'sine', duration: 0.8, volume: 0.5 },
        'alarm': { name: 'Alarm (Kurz & Hoch)', frequency: 880, type: 'triangle', duration: 0.4, volume: 0.6 },
        'chime': { name: 'Glocke (Tief & Langsam)', frequency: 440, type: 'sine', duration: 1.2, volume: 0.4 },
        'beep': { name: 'Beep (Standard-Signal)', frequency: 750, type: 'square', duration: 0.2, volume: 0.7 },
        'high_alert': { name: 'Hoher Alarm', frequency: 1000, type: 'sawtooth', duration: 0.3, volume: 0.7 },
        'soft_chime': { name: 'Sanfte Glocke', frequency: 523.25, type: 'sine', duration: 0.6, volume: 0.4 }, // C5
        'deep_thump': { name: 'Tiefer Puls', frequency: 120, type: 'square', duration: 0.5, volume: 0.8 },
        'quick_blip': { name: 'Kurzer Blip', frequency: 1500, type: 'sine', duration: 0.1, volume: 0.6 }
    };

    // --- Standardeinstellungen ---
    const defaultSettings = {
        minInterval: 200,
        maxInterval: 500,
        toggleKeyCode: 'KeyE', // Standard: 'E'
        toggleKeyChar: 'E', // Zeichen für die Anzeige im UI
        requiredCtrl: true,
        requiredAlt: false,
        requiredShift: true,
        pauseOnBotProtection: true, // Einstellung: Bei Botschutz pausieren
        soundEnabled: true, // Botschutz-Ton aktiviert
        selectedSound: 'default' // Standard: 'default' Sound
    };
    let currentSettings = {}; // Wird aus localStorage geladen

    // --- Funktionen zum Laden und Speichern der Einstellungen ---
    function loadSettings() {
        const savedSettings = localStorage.getItem('tw_auto_action_settings');
        if (savedSettings) {
            try {
                const parsed = JSON.parse(savedSettings);
                currentSettings = { ...defaultSettings, ...parsed };
                // Sicherstellen, dass toggleKeyChar aus keyCode abgeleitet wird, falls es fehlt
                if (!currentSettings.toggleKeyChar && currentSettings.toggleKeyCode) {
                    currentSettings.toggleKeyChar = currentSettings.toggleKeyCode.replace('Key', '').replace('Digit', '');
                    if (currentSettings.toggleKeyCode === 'Space') currentSettings.toggleKeyChar = ' ';
                } else if (currentSettings.toggleKeyChar && !currentSettings.toggleKeyCode) { // Fallback, falls Char da, aber Code fehlt
                    currentSettings.toggleKeyCode = getKeyCodeFromChar(currentSettings.toggleKeyChar);
                }
                // Sicherstellen, dass der ausgewählte Sound existiert, sonst auf 'default' zurückfallen
                if (!soundProfiles[currentSettings.selectedSound]) {
                    currentSettings.selectedSound = 'default';
                }
            } catch (e) {
                console.error("Auto-Action: Fehler beim Laden der Einstellungen, verwende Standardeinstellungen:", e);
                currentSettings = { ...defaultSettings };
            }
        } else {
            currentSettings = { ...defaultSettings };
        }
    }

    function saveSettings() {
        localStorage.setItem('tw_auto_action_settings', JSON.stringify(currentSettings));
    }

    // --- Hilfsfunktion zum Umwandeln von Zeichen in event.code ---
    function getKeyCodeFromChar(char) {
        if (!char) return null;
        char = char.toUpperCase();
        if (char.length === 1 && char.match(/[A-Z]/)) {
            return 'Key' + char;
        }
        if (char === ' ') return 'Space';
        if (char.length === 1 && char.match(/[0-9]/)) {
            return 'Digit' + char;
        }
        return null;
    }


    // --- Skript-Variablen ---
    let autoActionActive = false;
    let autoActionIntervalId = null;
    let botProtectionDetected = false;
    let noFarmButtonsDetected = false;
    let initialReadyMessageShown = false; // Flag für die initiale Nachricht

    // --- Hilfsfunktion zum Generieren eines zufälligen Intervalls ---
    function getRandomInterval(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    // --- AudioContext und Sound-Funktionen ---
    let audioCtx = null; // Globale Referenz für AudioContext

    // Funktion zum Erzeugen und Abspielen eines Oszillators mit Profil-Parametern
    function createAndPlayOscillator(profile) {
        if (!audioCtx || audioCtx.state === 'closed') {
            console.warn('TW Auto-Action: AudioContext nicht bereit für die Wiedergabe des Oszillators.');
            return;
        }
        try {
            const oscillator = audioCtx.createOscillator();
            const gainNode = audioCtx.createGain();

            oscillator.connect(gainNode);
            gainNode.connect(audioCtx.destination);

            oscillator.type = profile.type;
            oscillator.frequency.setValueAtTime(profile.frequency, audioCtx.currentTime);
            gainNode.gain.setValueAtTime(profile.volume, audioCtx.currentTime);

            oscillator.start();
            gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + profile.duration);
            oscillator.stop(audioCtx.currentTime + profile.duration);
            console.log(`TW Auto-Action: Oszillator-Ton '${profile.name}' gestartet.`);
        } catch (e) {
            console.error("TW Auto-Action: FEHLER beim Erzeugen oder Starten des Oszillators.", e);
        }
    }

    // Funktion zum Triggern des Botschutz-Tons (respektiert Einstellung)
    function triggerAntiBotSound() {
        console.log('TW Auto-Action: Trigger Botschutz-Ton (geprüft nach Einstellung)...');
        if (!currentSettings.soundEnabled) {
            console.log('TW Auto-Action: Botschutz-Ton ist in den Einstellungen deaktiviert. Überspringe Wiedergabe.');
            return;
        }

        try {
            if (!audioCtx || audioCtx.state === 'closed') {
                audioCtx = new (window.AudioContext || window.webkitAudioContext)();
                console.log('TW Auto-Action: AudioContext initialisiert (durch Botschutz-Trigger). Zustand:', audioCtx.state);
            }

            const actuallyPlaySound = () => {
                 const profile = soundProfiles[currentSettings.selectedSound] || soundProfiles['default'];
                 console.log('TW Auto-Action: Botschutz-Ton wird abgespielt.');
                 createAndPlayOscillator(profile);
            };

            if (audioCtx.state === 'suspended') {
                console.log('TW Auto-Action: AudioContext ist ausgesetzt (durch Botschutz-Trigger), versuche Fortsetzung...');
                audioCtx.resume().then(() => {
                    console.log('TW Auto-Action: AudioContext erfolgreich fortgesetzt (durch Botschutz-Trigger).');
                    actuallyPlaySound();
                }).catch(e => {
                    console.error("TW Auto-Action: FEHLER beim Fortsetzen des AudioContext (durch Botschutz-Trigger).", e);
                });
            } else if (audioCtx.state === 'running') {
                console.log('TW Auto-Action: AudioContext läuft bereits (durch Botschutz-Trigger).');
                actuallyPlaySound();
            } else {
                console.warn('TW Auto-Action: AudioContext ist in unerwartetem Zustand (durch Botschutz-Trigger):', audioCtx.state);
            }
        } catch (e) {
            console.error("TW Auto-Action: KRITISCHER FEHLER beim Initialisieren oder Abspielen des Anti-Bot-Sounds (durch Botschutz-Trigger).", e);
        }
    }

    // Funktion für den Aktivierungs-Test-Ton (spielt den aktuell ausgewählten Ton, entsperrt Context)
    function playActivationTestTone() {
        console.log('TW Auto-Action: Test-Ton durch Aktivierungs-Button angefordert...');
        try {
            if (!audioCtx || audioCtx.state === 'closed') {
                audioCtx = new (window.AudioContext || window.webkitAudioContext)();
                console.log('TW Auto-Action: AudioContext initialisiert (durch Aktivierungs-Button). Zustand:', audioCtx.state);
            }

            // Verwende das aktuell ausgewählte Sound-Profil für den Testton
            const profileToPlay = soundProfiles[currentSettings.selectedSound] || soundProfiles['default'];

            if (audioCtx.state === 'suspended') {
                console.log('TW Auto-Action: AudioContext ist ausgesetzt (durch Aktivierungs-Button), versuche Fortsetzung...');
                audioCtx.resume().then(() => {
                    console.log('TW Auto-Action: AudioContext erfolgreich fortgesetzt (durch Aktivierungs-Button), spiele Test-Ton ab.');
                    createAndPlayOscillator(profileToPlay);
                }).catch(e => {
                    console.error("TW Auto-Action: FEHLER beim Fortsetzen des AudioContext (durch Aktivierungs-Button).", e);
                });
            } else if (audioCtx.state === 'running') {
                console.log('TW Auto-Action: AudioContext läuft bereits (durch Aktivierungs-Button), spiele Test-Ton ab.');
                createAndPlayOscillator(profileToPlay);
            } else {
                console.warn('TW Auto-Action: AudioContext ist in unerwartetem Zustand (durch Aktivierungs-Button):', audioCtx.state);
            }
        } catch (e) {
            console.error("TW Auto-Action: KRITISCHER FEHLER beim Initialisieren oder Abspielen des Test-Tons (durch Aktivierungs-Button).", e);
        }
    }

    // Funktion zum Abspielen des ausgewählten Sounds aus den Einstellungen (für Vorschau)
    function playSelectedSoundPreview() {
        const selectedKey = $('#setting_selected_sound').val();
        const profile = soundProfiles[selectedKey] || soundProfiles['default']; // Fallback auf Standard

        console.log(`TW Auto-Action: Spiele Vorschau-Ton: ${profile.name}`);

        try {
            if (!audioCtx || audioCtx.state === 'closed') {
                audioCtx = new (window.AudioContext || window.webkitAudioContext)();
                console.log('TW Auto-Action: AudioContext initialisiert (für Vorschau). Zustand:', audioCtx.state);
            }

            if (audioCtx.state === 'suspended') {
                console.log('TW Auto-Action: AudioContext ist ausgesetzt (für Vorschau), versuche Fortsetzung...');
                audioCtx.resume().then(() => {
                    console.log('TW Auto-Action: AudioContext erfolgreich fortgesetzt (für Vorschau).');
                    createAndPlayOscillator(profile);
                }).catch(e => {
                    console.error("TW Auto-Action: FEHLER beim Fortsetzen des AudioContext (für Vorschau).", e);
                });
            } else if (audioCtx.state === 'running') {
                console.log('TW Auto-Action: AudioContext läuft bereits (für Vorschau).');
                createAndPlayOscillator(profile);
            } else {
                console.warn('TW Auto-Action: AudioContext ist in unerwartetem Zustand (für Vorschau):', audioCtx.state);
            }
        } catch (e) {
            console.error("TW Auto-Action: KRITISCHER FEHLER beim Initialisieren oder Abspielen des Vorschau-Tons.", e);
        }
    }


    // --- Botschutz-Erkennung ---
    function checkAntiBotProtection() {
        const botProtectionSelectors = [
            'div#botprotection_quest',
            'div[data-id="bot_protection"]',
            '#popup_box_bot_protection',
            'div#tooltip:contains("Bot-Schutz")',
            '#bot_protect_dialog',
            '.popup_box_container:contains("Sicherheitsabfrage")',
            '.popup_box_container:contains("Bot-Schutz")',
            'div[data-bot-check="true"]',
            'img[src*="captcha"]',
            'input[name="captcha_code"]',
            '.modem-window:contains("Sicherheitsprüfung")',
            '#recaptcha-challenge',
            '#bot_captcha_div',
            'div.error:contains("Bitte bestätigen Sie, dass Sie kein Bot sind.")',
        ];

        let isBotProtectionVisible = false;
        for (const selector of botProtectionSelectors) {
            const element = $(selector);
            if (element.length > 0 && element.is(':visible') && element.css('display') !== 'none' && element.css('visibility') !== 'hidden' && element.attr('disabled') !== 'disabled') {
                isBotProtectionVisible = true;
                break;
            }
        }

        if (isBotProtectionVisible) {
            if (!botProtectionDetected) {
                botProtectionDetected = true;
                triggerAntiBotSound(); // Ruft triggerAntiBotSound() auf, die die soundEnabled-Einstellung prüft
                if (autoActionActive && currentSettings.pauseOnBotProtection) {
                    clearInterval(autoActionIntervalId);
                    autoActionIntervalId = null;
                    autoActionActive = false;
                    if (typeof UI !== 'undefined' && typeof UI.ErrorMessage === 'function') {
                        UI.ErrorMessage('Botschutz-Abfrage erkannt! Auto-Action wurde gestoppt!', 5000);
                    }
                    console.warn('TW Auto-Action: Botschutz-Abfrage erkannt. Skript gestoppt.');
                } else if (typeof UI !== 'undefined' && typeof UI.ErrorMessage === 'function') {
                    UI.ErrorMessage('Botschutz-Abfrage erkannt! Auto-Action ist nicht aktiv oder pausiert nicht automatisch.', 5000);
                }
                updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
            }
            return true;
        } else {
            if (botProtectionDetected) {
                botProtectionDetected = false;
                if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                    UI.InfoMessage('Botschutz-Abfrage nicht mehr sichtbar. Auto-Action kann bei Bedarf wieder gestartet werden.', 3000);
                }
                updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
            }
            return false;
        }
    }


    // --- Funktion zum Simulieren des Button-Klicks ---
    function simulateButtonClick() {
        if (typeof game_data !== 'undefined' && game_data.screen === 'am_farm') {
            if (checkAntiBotProtection()) {
                return;
            }

            const farmButton = $(FARM_BUTTON_SELECTOR).first();

            if (farmButton.length > 0 && farmButton.is(':visible') && !farmButton.is(':disabled')) {
                if (noFarmButtonsDetected) {
                    noFarmButtonsDetected = false;
                    updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
                }
                farmButton.trigger('click');
            } else {
                if (!noFarmButtonsDetected) {
                    noFarmButtonsDetected = true;
                    if (autoActionActive) {
                        clearInterval(autoActionIntervalId);
                        autoActionIntervalId = null;
                        autoActionActive = false;
                        if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                            UI.InfoMessage('Keine Farm-Buttons gefunden oder sichtbar. Auto-Action gestoppt!', 3000);
                        }
                        console.log('TW Auto-Action: Keine Farm-Buttons gefunden oder sichtbar. Skript gestoppt.');
                    } else {
                         if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                            UI.InfoMessage('Keine Farm-Buttons gefunden oder sichtbar.', 3000);
                        }
                    }
                    updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
                }
            }
        } else {
            if (autoActionActive) {
                clearInterval(autoActionIntervalId);
                autoActionIntervalId = null;
                autoActionActive = false;
                if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                    UI.InfoMessage('Auto-Action automatisch gestoppt (nicht auf Farm-Seite).', 3000);
                }
                noFarmButtonsDetected = false;
                botProtectionDetected = false;
                updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
            }
        }
    }

    // --- Event Listener für Tastendrücke ---
    document.addEventListener('keydown', (event) => {
        const isHotkeyCombination =
            event.code === currentSettings.toggleKeyCode &&
            event.ctrlKey === currentSettings.requiredCtrl &&
            event.altKey === currentSettings.requiredAlt &&
            event.shiftKey === currentSettings.requiredShift;

        if (isHotkeyCombination) {
            event.preventDefault();

            window.toggleTribalAutoAction();
        }
    });

    // --- Globale Toggle Funktion für Auto-Action ---
    window.toggleTribalAutoAction = function() {
        if (autoActionActive) {
            clearInterval(autoActionIntervalId);
            autoActionIntervalId = null;
            autoActionActive = false;
            if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                UI.InfoMessage('Auto-Action gestoppt.', 2000);
            }
            noFarmButtonsDetected = false;
            botProtectionDetected = false;
        } else {
            // Beim Starten des Skripts durch Nutzerinteraktion: Versuche AudioContext zu aktivieren
            if (!audioCtx) {
                audioCtx = new (window.AudioContext || window.webkitAudioContext)();
            }
            if (audioCtx && audioCtx.state === 'suspended') {
                audioCtx.resume().then(() => {
                    console.log('TW Auto-Action: AudioContext beim Starten fortgesetzt durch Benutzerinteraktion.');
                }).catch(e => {
                    console.warn('TW Auto-Action: Fehler beim Fortsetzen des AudioContext beim Starten durch Benutzerinteraktion.', e);
                });
            }

            if (checkAntiBotProtection()) {
                // Wenn Botschutz direkt beim Start erkannt wird, wird der Status bereits in checkAntiBotProtection() aktualisiert
                return;
            }

            const farmButtonCheck = $(FARM_BUTTON_SELECTOR).first();
            if (farmButtonCheck.length === 0 || !farmButtonCheck.is(':visible') || farmButtonCheck.is(':disabled')) {
                if (typeof UI !== 'undefined' && typeof UI.ErrorMessage === 'function') {
                    UI.ErrorMessage('Kann Auto-Action nicht starten: Keine Farm-Buttons gefunden oder sie sind nicht sichtbar/aktiv.', 4000);
                }
                noFarmButtonsDetected = true;
                updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
                return;
            }

            autoActionActive = true;
            if (autoActionIntervalId) clearInterval(autoActionIntervalId);

            const initialInterval = getRandomInterval(currentSettings.minInterval, currentSettings.maxInterval);
            autoActionIntervalId = setInterval(() => {
                simulateButtonClick();
                clearInterval(autoActionIntervalId);
                if (autoActionActive) {
                    autoActionIntervalId = setInterval(simulateButtonClick, getRandomInterval(currentSettings.minInterval, currentSettings.maxInterval));
                }
            }, initialInterval);

            if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                let hotkeyDisplay = currentSettings.toggleKeyChar;
                if (currentSettings.requiredCtrl) hotkeyDisplay = 'Strg + ' + hotkeyDisplay;
                if (currentSettings.requiredAlt) hotkeyDisplay = 'Alt + ' + hotkeyDisplay;
                if (currentSettings.requiredShift) hotkeyDisplay = 'Shift + ' + hotkeyDisplay;
                hotkeyDisplay = hotkeyDisplay.replace(/\s\+\s$/, '');

                UI.InfoMessage('Auto-Action gestartet! (Hotkey: ' + hotkeyDisplay + ' zum Stoppen)', 3000);
            }
            noFarmButtonsDetected = false;
        }
        updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
    };

    // --- PRÄZISER SELEKTOR FÜR BELIEBIGEN FARMGOD BUTTON ---
    const FARM_BUTTON_SELECTOR = 'a.farmGod_icon';

    let customDialogElement = null;

    // --- Einstellungsdialog ---
    function openSettingsDialog() {
        if (customDialogElement) {
            customDialogElement.remove();
            customDialogElement = null;
        }

        const dialogContentHtml = `
            <div id="tw_auto_action_settings_dialog_content" style="padding: 15px; background-color: #f7f3e6; border: 1px solid #804000; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.5); max-width: 400px; margin: 20px; position: relative;">
                <h3>Auto-Action Einstellungen (v${SCRIPT_VERSION})</h3>
                <style>
                    #tw_auto_action_settings_dialog_content table { width: 100%; border-collapse: collapse; margin-top: 10px; }
                    #tw_auto_action_settings_dialog_content th, #tw_auto_action_settings_dialog_content td { padding: 5px; border: 1px solid #ddd; text-align: left; }
                    #tw_auto_action_settings_dialog_content input[type="text"],
                    #tw_auto_action_settings_dialog_content input[type="number"] {
                        width: calc(100% - 12px);
                        padding: 5px;
                        box-sizing: border-box;
                        border: 1px solid #c2c2c2;
                        border-radius: 3px;
                    }
                    #tw_auto_action_settings_dialog_content input[type="checkbox"] { margin-right: 5px; }
                    #tw_auto_action_settings_dialog_content .btn {
                        margin-top: 15px;
                        margin-right: 10px;
                        padding: 8px 15px;
                        cursor: pointer;
                        font-weight: bold;
                        border: 1px solid #804000;
                        border-radius: 3px;
                        background-color: #f0e2b6; /* Einheitliche Farbe */
                        color: #5b3617; /* Dunkler Text für Dialog-Buttons */
                    }
                    #tw_auto_action_settings_dialog_content .btn-red {
                        background-color: #d1b790; /* Einheitliche Farbe */
                        border-color: #6d3300;
                        color: #3b1e0a; /* Dunkler Text für Dialog-Buttons */
                    }
                    #tw_auto_action_settings_dialog_content h3 {
                        color: #804000;
                        margin-top: 0;
                        border-bottom: 1px solid #804000;
                        padding-bottom: 5px;
                    }
                    #tw_auto_action_settings_dialog_content label {
                        display: inline-flex;
                        align-items: center;
                        margin-bottom: 5px;
                    }
                    #tw_auto_action_settings_dialog_content select {
                        width: calc(100% - 80px); /* Angepasst für Button */
                        padding: 5px;
                        box-sizing: border-box;
                        border: 1px solid #c2c2c2;
                        border-radius: 3px;
                        display: inline-block;
                        vertical-align: middle;
                    }
                    #tw_auto_action_settings_dialog_content #tw_auto_action_preview_sound {
                        width: auto;
                        padding: 5px 10px;
                        margin-left: 5px;
                        margin-top: 0; /* Wichtig, damit es in der Reihe bleibt */
                        display: inline-block;
                        vertical-align: middle;
                    }
                </style>
                <table class="vis">
                    <tr>
                        <th>Hotkey (Taste)</th>
                        <td><input type="text" id="setting_toggle_key_char" maxlength="1" value="${currentSettings.toggleKeyChar}" style="width: 30px; text-align: center;"></td>
                    </tr>
                    <tr>
                        <th>Benötigte Tasten</th>
                        <td>
                            <label><input type="checkbox" id="setting_required_ctrl" ${currentSettings.requiredCtrl ? 'checked' : ''}> Strg</label><br>
                            <label><input type="checkbox" id="setting_required_alt" ${currentSettings.requiredAlt ? 'checked' : ''}> Alt</label><br>
                            <label><input type="checkbox" id="setting_required_shift" ${currentSettings.requiredShift ? 'checked' : ''}> Shift</label>
                        </td>
                    </tr>
                    <tr>
                        <th>Min. Abstand (ms)</th>
                        <td><input type="number" id="setting_min_interval" min="50" max="10000" value="${currentSettings.minInterval}"></td>
                    </tr>
                    <tr>
                        <th>Max. Abstand (ms)</th>
                        <td><input type="number" id="setting_max_interval" min="50" max="10000" value="${currentSettings.maxInterval}"></td>
                    </tr>
                    <tr>
                        <th>Botschutz pausieren</th>
                        <td><input type="checkbox" id="setting_pause_on_bot_protection" ${currentSettings.pauseOnBotProtection ? 'checked' : ''}> Bei Botschutz-Abfrage pausieren</td>
                    </tr>
                    <tr>
                        <th>Botschutz-Ton</th>
                        <td>
                            <label><input type="checkbox" id="setting_sound_enabled" ${currentSettings.soundEnabled ? 'checked' : ''}> Ton abspielen</label><br>
                            <select id="setting_selected_sound">
                                ${Object.keys(soundProfiles).map(key => `
                                    <option value="${key}" ${currentSettings.selectedSound === key ? 'selected' : ''}>${soundProfiles[key].name}</option>
                                `).join('')}
                            </select>
                            <button id="tw_auto_action_preview_sound" class="btn">Hören</button>
                        </td>
                    </tr>
                </table>
                <button id="tw_auto_action_save_settings" class="btn">Speichern</button>
                <button id="tw_auto_action_close_settings" class="btn btn-red">Schließen</button>
            </div>
        `;

        customDialogElement = $(`
            <div id="tw_auto_action_custom_dialog_overlay" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.7); z-index: 100000; display: flex; justify-content: center; align-items: center; overflow-y: auto;">
                ${dialogContentHtml}
            </div>
        `);

        $('body').append(customDialogElement);


        $('#tw_auto_action_save_settings').on('click', () => {
            const newToggleKeyChar = $('#setting_toggle_key_char').val().toUpperCase();
            const newToggleKeyCode = getKeyCodeFromChar(newToggleKeyChar);

            if (!newToggleKeyCode) {
                if (typeof UI !== 'undefined' && typeof UI.ErrorMessage === 'function') {
                    UI.ErrorMessage("Ungültige Hotkey-Taste. Verwende A-Z, 0-9 oder Leerzeichen.", 3000);
                }
                return;
            }

            let newMinInterval = parseInt($('#setting_min_interval').val(), 10);
            let newMaxInterval = parseInt($('#setting_max_interval', 10).val());

            if (isNaN(newMinInterval) || newMinInterval < 50) newMinInterval = 50;
            if (isNaN(newMaxInterval) || newMaxInterval < newMinInterval) newMaxInterval = newMinInterval + 100;

            currentSettings.toggleKeyChar = newToggleKeyChar;
            currentSettings.toggleKeyCode = newToggleKeyCode;
            currentSettings.requiredCtrl = $('#setting_required_ctrl').is(':checked');
            currentSettings.requiredAlt = $('#setting_required_alt').is(':checked');
            currentSettings.requiredShift = $('#setting_required_shift').is(':checked');
            currentSettings.minInterval = newMinInterval;
            currentSettings.maxInterval = newMaxInterval;
            currentSettings.pauseOnBotProtection = $('#setting_pause_on_bot_protection').is(':checked');
            currentSettings.soundEnabled = $('#setting_sound_enabled').is(':checked');
            currentSettings.selectedSound = $('#setting_selected_sound').val(); // Ausgewählten Sound speichern

            saveSettings();
            customDialogElement.remove();
        customDialogElement = null;
            if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                UI.InfoMessage('Einstellungen gespeichert!', 2000);
            }

            // Beim Speichern der Einstellungen könnte der Zustand des Skripts geändert werden, daher aktualisieren
            if (autoActionActive) {
                clearInterval(autoActionIntervalId);
                autoActionIntervalId = null;
                autoActionActive = false;
                if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                    UI.InfoMessage('Skript pausiert. Starte per Hotkey oder extern zum Neustart mit neuen Einstellungen.', 3000);
                }
            }
            updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
        });

        $('#tw_auto_action_close_settings').on('click', () => {
            customDialogElement.remove();
            customDialogElement = null;
        });

        // Klick-Handler für den "Hören"-Button im Einstellungsdialog
        $('#tw_auto_action_preview_sound').on('click', (e) => {
            e.preventDefault();
            playSelectedSoundPreview();
        });
    }

    // --- Einstellungs-Button auf der Farm-Seite hinzufügen ---
    let settingsButtonRef = null;
    let activateSoundButtonRef = null;
    let toggleButtonRef = null;
    let statusBarRef = null; // Referenz auf die Statusleiste
    let mainContainerRef = null; // Neue Referenz für den Haupt-Container


    // Funktion zum Aktualisieren des UI-Status (Button-Text, Farbe und NEU: Tab-Titel & Statusleiste)
    function updateUIStatus() {
        let currentTabTitle = originalDocumentTitle; // Startet mit dem Originaltitel
        let currentStatusText = 'TW Auto-Action ist bereit.'; // Standardtext für die Statusleiste
        let statusBarBgColor = '#ffc107'; // Standard: Gelb für Inaktiv/Bereit/Keine Buttons

        // Farben für Buttons - nun feste Werte
        const defaultButtonBg = '#f0e2b6';
        const defaultButtonBorder = '#804000';
        const defaultButtonText = '#ffffff'; // Feste weiße Schrift

        // Update Settings Button (feste Farben)
        if (settingsButtonRef) {
            settingsButtonRef.css({
                'background-color': defaultButtonBg,
                'color': defaultButtonText,
                'border-color': defaultButtonBorder
            });
        }

        // Update Activate Sound Button (feste Farben, Text kann sich ändern)
        if (activateSoundButtonRef) {
            activateSoundButtonRef.css({
                'background-color': defaultButtonBg,
                'color': defaultButtonText,
                'border-color': defaultButtonBorder
            });
            // Der Text "Ton Aktiv" wird nur beim Klick gesetzt und bleibt dann so
        }

        // Update Toggle Button (feste Farben, Text ändert sich zwischen Start/Stopp)
        if (toggleButtonRef) {
            toggleButtonRef.text(autoActionActive ? 'Auto-Action Stopp' : 'Auto-Action Start');
            toggleButtonRef.css({
                'background-color': defaultButtonBg,
                'color': defaultButtonText,
                'border-color': defaultButtonBorder
            });
        }

        // --- Logik für die Statusleiste (Farbe und Text) ---
        if (botProtectionDetected) {
            statusBarBgColor = '#dc3545'; // Rot
            currentTabTitle = `[BOTSCHUTZ PAUSE] TW Auto-Action | ${originalDocumentTitle}`;
            currentStatusText = '[BOTSCHUTZ] Auto-Action pausiert!';
        } else if (autoActionActive) {
            statusBarBgColor = '#28a745'; // Grün
            currentTabTitle = `[AKTIV] TW Auto-Action | ${originalDocumentTitle}`;
            currentStatusText = '[AKTIV] Auto-Action läuft...';
        } else if (noFarmButtonsDetected) {
            statusBarBgColor = '#ffc107'; // Gelb
            currentTabTitle = `[KEINE BUTTONS] TW Auto-Action | ${originalDocumentTitle}`;
            currentStatusText = '[KEINE BUTTONS] Auto-Action gestoppt.';
        } else { // Inaktiv oder Bereit (Initialzustand)
            statusBarBgColor = '#ffc107'; // Gelb
            currentStatusText = 'Auto-Action ist inaktiv.';
            // Der Tab-Titel bleibt hier original, da keine besondere Statusinfo benötigt wird
        }


        // Update Tab Title
        document.title = currentTabTitle;

        // Update Status Bar
        if (statusBarRef) {
            statusBarRef.text(currentStatusText);
            statusBarRef.css({
                'background-color': statusBarBgColor,
                'color': '#ffffff' // Feste weiße Schrift für die Statusleiste
            });
        }
    }

    function addAmFarmSettingsButton() {
        if (typeof game_data === 'undefined' || game_data.screen !== 'am_farm') {
            return;
        }

        // Versuche, den Einfügepunkt zu finden: die erste Überschrift im content_value div
        const targetHeading = $('#content_value').find('h3:contains("Farm-Assistent"), h2:contains("Account Manager"), h4.screen-title:contains("Account-Manager")').first();

        if (targetHeading.length === 0) {
            console.warn("TW Auto-Action: Konnte keine passende Überschrift für 'Account-Manager' finden, um Buttons einzufügen. Buttons werden nicht angezeigt.");
            return;
        }

        // Grundlegende Styles für alle Buttons (keine feste Positionierung mehr)
        const buttonBaseStyle = `
            white-space: nowrap;
            display: inline-block;
            padding: 8px 15px;
            cursor: pointer;
            font-weight: bold;
            border-radius: 3px;
            color: #ffffff; /* Feste weiße Schrift */
            background-color: #f0e2b6; /* Feste neutrale Hintergrundfarbe */
            border: 1px solid #804000; /* Feste neutrale Rahmenfarbe */
        `;

        // HTML für die Buttons (Reihenfolge hier ist wichtig für flexbox justify-content: flex-start)
        // Visuell: Start/Stopp (links) -- Ton Aktivieren (Mitte) -- Einstellungen (rechts)
        const toggleButtonHtml = `<a href="#" id="tw_auto_action_toggle_button" class="btn" style="${buttonBaseStyle}">Auto-Action Start/Stopp</a>`;
        const activateSoundButtonHtml = `<a href="#" id="tw_auto_action_activate_sound_button" class="btn" style="${buttonBaseStyle}">Ton Aktivieren</a>`;
        const settingsButtonHtml = `<a href="#" id="tw_auto_action_settings_button" class="btn" style="${buttonBaseStyle}">Auto-Action Einstellungen</a>`;

        // Statusleiste HTML - JETZT ALS NORMALES FLEX-ITEM, OHNE ABSOLUTE POSITIONIERUNG
        const statusBarHtml = `
            <div id="tw_auto_action_status_bar" style="
                background-color: rgba(0,0,0,0.7);
                color: white;
                padding: 5px 10px;
                border-radius: 3px;
                font-size: 12px;
                text-align: left;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
                box-sizing: border-box; /* Wichtig für korrekte Breitenberechnung mit Padding/Border */
                flex-grow: 1; /* Lässt die Statusleiste den restlichen Platz ausfüllen */
                min-width: 50px; /* Verhindert zu starkes Schrumpfen */
            ">
                TW Auto-Action ist bereit.
            </div>
        `;

        // Haupt-Container für Buttons und Statusleiste
        // buttons_row enthält nun alle Elemente nebeneinander
        const mainContainerHtml = `
            <div id="tw_auto_action_main_container" style="margin-bottom: 15px; margin-top: 5px; width: 100%; box-sizing: border-box;">
                <div id="tw_auto_action_buttons_row" style="display: flex; justify-content: flex-start; gap: 10px; align-items: center; margin-bottom: 10px;">
                    ${toggleButtonHtml}
                    ${activateSoundButtonHtml}
                    ${settingsButtonHtml}
                    ${statusBarHtml} </div>
            </div>
        `;

        // Gesamten Container vor der gefundenen Überschrift einfügen
        mainContainerRef = $(mainContainerHtml);
        targetHeading.before(mainContainerRef);

        // Referenzen zu den eingefügten Elementen holen
        toggleButtonRef = mainContainerRef.find('#tw_auto_action_toggle_button');
        activateSoundButtonRef = mainContainerRef.find('#tw_auto_action_activate_sound_button');
        settingsButtonRef = mainContainerRef.find('#tw_auto_action_settings_button');
        statusBarRef = mainContainerRef.find('#tw_auto_action_status_bar');

        // Event-Listener zuweisen
        if (settingsButtonRef.length > 0) {
            settingsButtonRef.on('click', (e) => {
                e.preventDefault();
                openSettingsDialog();
            });
        }

        if (activateSoundButtonRef.length > 0) {
            activateSoundButtonRef.on('click', (e) => {
                e.preventDefault();
                playActivationTestTone();
                activateSoundButtonRef.text('Ton Aktiv');
                if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                    UI.InfoMessage('Ton aktiviert! Er bleibt aktiv, bis die Seite komplett neu geladen wird.', 3000);
                }
                updateUIStatus();
            });
        }

        if (toggleButtonRef.length > 0) {
            toggleButtonRef.on('click', (e) => {
                e.preventDefault();
                window.toggleTribalAutoAction();
            });
        }

        updateUIStatus(); // Initiales Update des Status für alle Elemente
    }

    // --- Skript-Initialisierung ---
    loadSettings();

    $(document).ready(function() {
        addAmFarmSettingsButton();

        // Zeige die initiale "Bereit"-Nachricht nur einmal an
        if (!initialReadyMessageShown) {
            setTimeout(() => {
                if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                    let hotkeyDisplay = currentSettings.toggleKeyChar;
                    if (currentSettings.requiredCtrl) hotkeyDisplay = 'Strg + ' + hotkeyDisplay;
                    if (currentSettings.requiredAlt) hotkeyDisplay = 'Alt + ' + hotkeyDisplay;
                    if (currentSettings.requiredShift) hotkeyDisplay = 'Shift + ' + hotkeyDisplay;
                    hotkeyDisplay = hotkeyDisplay.replace(/\s\+\s$/, '');

                    UI.InfoMessage('TW Auto-Action (v' + SCRIPT_VERSION + ') ist bereit. Starte per Hotkey: ' + hotkeyDisplay + ' oder über den "Start/Stopp"-Button.', 3000);
                }
                initialReadyMessageShown = true;
            }, 1000);
        }


        const observerConfig = { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] };

        const observer = new MutationObserver((mutationsList, observer) => {
            // Nur aktualisieren, wenn potenziell relevante Änderungen passieren und das Skript aktiv oder in einem speziellen Zustand ist
            if (autoActionActive || botProtectionDetected || noFarmButtonsDetected || !initialReadyMessageShown) { // Auch aktualisieren, wenn die Initialnachricht noch nicht gezeigt wurde (also der Startzustand)
                const relevantChange = mutationsList.some(mutation =>
                    mutation.type === 'childList' ||
                    (mutation.type === 'attributes' && (mutation.attributeName === 'style' || mutation.attributeName === 'class'))
                );

                if (relevantChange) {
                    // Überprüfe Botschutz, da dies den Skriptstatus ändern kann
                    const botProtectionFound = checkAntiBotProtection();

                    if (!botProtectionFound && typeof game_data !== 'undefined' && game_data.screen === 'am_farm') {
                        // Überprüfe Farm-Buttons nur, wenn kein Botschutz aktiv ist und auf der Farm-Seite
                        const farmButton = $(FARM_BUTTON_SELECTOR).first();
                        if (farmButton.length === 0 || !farmButton.is(':visible') || farmButton.is(':disabled')) {
                            if (autoActionActive) {
                                clearInterval(autoActionIntervalId);
                                autoActionIntervalId = null;
                                autoActionActive = false;
                                if (typeof UI !== 'undefined' && typeof UI.InfoMessage === 'function') {
                                    UI.InfoMessage('Keine Farm-Buttons mehr gefunden/sichtbar. Auto-Action gestoppt!', 3000);
                                }
                            }
                            if (!noFarmButtonsDetected) {
                                noFarmButtonsDetected = true;
                                updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
                            }
                        } else {
                            if (noFarmButtonsDetected) {
                                noFarmButtonsDetected = false;
                                updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
                            }
                        }
                    } else if (!botProtectionFound) {
                        // Wenn der Botschutz nicht gefunden wurde und das Skript nicht auf der Farm-Seite ist,
                        // und keine Buttons erkannt wurden, stellen Sie sicher, dass diese Zustände zurückgesetzt werden.
                        if (noFarmButtonsDetected || botProtectionDetected) {
                            noFarmButtonsDetected = false;
                            botProtectionDetected = false;
                            updateUIStatus(); // Aktualisiert auch den Tab-Titel und Buttons
                        }
                    }
                }
            }
        });

        observer.observe(document.body, observerConfig);

        // Initialprüfung beim Laden der Seite
        checkAntiBotProtection();
        if (typeof game_data !== 'undefined' && game_data.screen === 'am_farm') {
            const farmButton = $(FARM_BUTTON_SELECTOR).first();
            if (farmButton.length === 0 || !farmButton.is(':visible') || farmButton.is(':disabled')) {
                noFarmButtonsDetected = true;
            }
        }
        updateUIStatus(); // Stellt sicher, dass der Titel initial korrekt gesetzt wird und die Buttons den korrekten Zustand haben
    });

})();
djmusicimprover

djmusicimprover

Member