Auto Builder Enhanced v3

Automatically builds buildings with advanced settings and resource monitoring

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Auto Builder Enhanced v3
// @namespace    http://tampermonkey.net/
// @version      1
// @description  Automatically builds buildings with advanced settings and resource monitoring
// @match        https://*.tribalwars.net/game.php?village=*&screen=main*
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Configuration
    const DEBUG = true;
    const STORAGE_KEY = 'tribalWarsBuilderConfig';

    // Get Village ID
    function getVillageId() {
        const match = window.location.href.match(/village=([^&]*)/);
        return match ? match[1] : null;
    }

    const villageId = getVillageId();
    if (!villageId) {
        console.error('Village ID not found in URL.');
        return;
    }

    let nextCheckTimer = null;
    let countdownInterval = null;

    // Get current resource stock
    function getResourceStock(resource) {
        const resourceElement = document.getElementById(resource);
        return resourceElement ? parseInt(resourceElement.innerText.replace(/\D/g, ''), 10) || 0 : 0;
    }

    // Get total resource (stock + incoming)
    function getTotalResource(resource) {
        const stock = getResourceStock(resource);
        
        // Get incoming resources from market status bar
        const marketTableRows = document.querySelectorAll("#market_status_bar table.vis tbody tr")[1];
        let incoming = 0;

        if (marketTableRows) {
            const resourceElement = marketTableRows.children[0].querySelector(`.icon.header.${resource}`);
            if (resourceElement) {
                const fullText = resourceElement.parentElement.textContent;
                incoming = parseInt(fullText.replace(/\D/g, ""), 10) || 0;
            }
        }

        return stock + incoming;
    }

    // Get required resources for a building
    function getRequiredResources(buildingName) {
        try {
            const row = document.querySelector(`#main_buildrow_${buildingName}`);
            if (!row) return null;

            const buildButton = row.querySelector(`a.btn-build[id*="_${buildingName}_"]`);
            if (!buildButton) return null;

            const costElements = row.querySelectorAll('span.icon.header');
            const costs = {
                wood: 0,
                stone: 0,
                iron: 0
            };

            costElements.forEach(elem => {
                const parentText = elem.parentElement.textContent;
                const cost = parseInt(parentText.replace(/\D/g, ''), 10) || 0;
                
                if (elem.classList.contains('wood')) {
                    costs.wood = cost;
                } else if (elem.classList.contains('stone')) {
                    costs.stone = cost;
                } else if (elem.classList.contains('iron')) {
                    costs.iron = cost;
                }
            });

            debugLog(`Required resources for ${buildingName}:`, costs);
            return costs;
        } catch (error) {
            debugLog(`Error getting required resources for ${buildingName}:`, error);
            return null;
        }
    }

    // Check if we have enough resources to build
    function hasEnoughResources(buildingName) {
        const required = getRequiredResources(buildingName);
        if (!required) return false;

        const wood = getResourceStock('wood');
        const stone = getResourceStock('stone');
        const iron = getResourceStock('iron');

        const hasEnough = wood >= required.wood && 
                         stone >= required.stone && 
                         iron >= required.iron;

        debugLog('Resource availability check:', {
            building: buildingName,
            current: { wood, stone, iron },
            required: required,
            hasEnough: hasEnough
        });

        return hasEnough;
    }

    // Check if all required resources meet minimum threshold
    function checkResourceThreshold(config) {
        const wood = getTotalResource('wood');
        const stone = getTotalResource('stone');
        const iron = getTotalResource('iron');

        debugLog('Resource Check:', {
            wood: wood,
            stone: stone,
            iron: iron,
            threshold: config.minResourceThreshold
        });

        return wood >= config.minResourceThreshold && 
               stone >= config.minResourceThreshold && 
               iron >= config.minResourceThreshold;
    }

    // Extract available buildings from the table
    function getAvailableBuildings() {
        debugLog('Starting getAvailableBuildings function');
        const buildings = [];
        const buildingRows = document.querySelectorAll('#buildings tbody tr[id^="main_buildrow_"]');
        debugLog(`Found ${buildingRows.length} building rows`);

        buildingRows.forEach((row, index) => {
            const buildingCell = row.querySelector('td:first-child');
            if (!buildingCell) return;

            const buildingId = row.id.replace('main_buildrow_', '');
            if (!buildingId) return;

            const links = buildingCell.querySelectorAll('a');
            const nameLink = links[1];
            if (!nameLink) return;

            const inactiveCell = row.querySelector('td.inactive');
            if (inactiveCell && inactiveCell.textContent.includes('vollständig ausgebaut')) {
                return;
            }

            const levelSpan = buildingCell.querySelector('span[style="font-size: 0.9em"]');
            const currentLevel = levelSpan ? levelSpan.textContent.trim() : 'unknown';
            const buildingName = nameLink.textContent.trim();

            buildings.push({
                id: buildingId,
                name: buildingName,
                currentLevel: currentLevel
            });
        });

        debugLog('Completed getAvailableBuildings. Found buildings:', buildings);
        return buildings;
    }

    // Load saved configuration
    function loadConfig() {
        const defaultConfig = {
            enabledBuildings: [],
            useCostReduction: true,
            buildingPriority: [],
            useLongBuildReduction: true,
            longBuildThreshold: 2,
            buildSequence: [],
            minResourceThreshold: 50000,
            checkInterval: 5,
            autoRun: false
        };

        try {
            const savedConfig = localStorage.getItem(`${STORAGE_KEY}_${villageId}`);
            return savedConfig ? {...defaultConfig, ...JSON.parse(savedConfig)} : defaultConfig;
        } catch (error) {
            debugLog('Error loading config:', error);
            return defaultConfig;
        }
    }

    // Save configuration
    function saveConfig(config) {
        try {
            localStorage.setItem(`${STORAGE_KEY}_${villageId}`, JSON.stringify(config));
            debugLog('Config saved:', config);
        } catch (error) {
            debugLog('Error saving config:', error);
        }
    }

    // Create countdown timer UI
    function createCountdownUI() {
        const container = document.createElement('div');
        container.id = 'builder-countdown-container';
        container.style.cssText = `
            position: fixed;
            bottom: 20px;
            left: 10px;
            background: #222;
            color: #fff;
            padding: 15px;
            border-radius: 8px;
            z-index: 1000;
            box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.3);
            font-family: Arial, sans-serif;
            min-width: 200px;
        `;

        const title = document.createElement('div');
        title.style.cssText = 'font-size: 14px; font-weight: bold; margin-bottom: 8px; text-align: center; border-bottom: 1px solid #444; padding-bottom: 5px;';
        title.textContent = 'Auto Builder Status';

        const statusDiv = document.createElement('div');
        statusDiv.id = 'builder-status';
        statusDiv.style.cssText = 'font-size: 12px; margin-bottom: 5px; color: #aaa;';
        statusDiv.textContent = 'Status: Stopped';

        const timerDiv = document.createElement('div');
        timerDiv.id = 'builder-timer';
        timerDiv.style.cssText = 'font-size: 16px; font-weight: bold; text-align: center; color: #4CAF50;';
        timerDiv.textContent = '--:--';

        const resourceDiv = document.createElement('div');
        resourceDiv.id = 'builder-resources';
        resourceDiv.style.cssText = 'font-size: 11px; margin-top: 8px; padding-top: 5px; border-top: 1px solid #444; color: #999;';
        resourceDiv.innerHTML = `
            <div>Wood: <span id="wood-count">0</span></div>
            <div>Stone: <span id="stone-count">0</span></div>
            <div>Iron: <span id="iron-count">0</span></div>
        `;

        const toggleButton = document.createElement('button');
        toggleButton.id = 'builder-toggle-btn';
        toggleButton.style.cssText = `
            width: 100%;
            padding: 8px;
            margin-top: 10px;
            background-color: #28a745;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 13px;
            font-weight: bold;
            transition: background-color 0.3s ease;
        `;
        toggleButton.textContent = 'Start Auto Build';
        
        toggleButton.addEventListener('click', toggleAutoBuilder);
        toggleButton.addEventListener('mouseenter', function() {
            this.style.backgroundColor = this.textContent === 'Start Auto Build' ? '#218838' : '#c82333';
        });
        toggleButton.addEventListener('mouseleave', function() {
            this.style.backgroundColor = this.textContent === 'Start Auto Build' ? '#28a745' : '#dc3545';
        });

        container.appendChild(title);
        container.appendChild(statusDiv);
        container.appendChild(timerDiv);
        container.appendChild(resourceDiv);
        container.appendChild(toggleButton);

        document.body.appendChild(container);

        updateResourceDisplay();
        setInterval(updateResourceDisplay, 5000);
    }

    // Update resource display
    function updateResourceDisplay() {
        const woodElement = document.getElementById('wood-count');
        const stoneElement = document.getElementById('stone-count');
        const ironElement = document.getElementById('iron-count');

        if (woodElement) woodElement.textContent = getTotalResource('wood').toLocaleString();
        if (stoneElement) stoneElement.textContent = getTotalResource('stone').toLocaleString();
        if (ironElement) ironElement.textContent = getTotalResource('iron').toLocaleString();
    }

    // Update countdown display
    function updateCountdownDisplay(seconds) {
        const timerElement = document.getElementById('builder-timer');
        if (!timerElement) return;

        const minutes = Math.floor(seconds / 60);
        const secs = seconds % 60;
        timerElement.textContent = `${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
    }

    // Update status display
    function updateStatusDisplay(status, color = '#aaa') {
        const statusElement = document.getElementById('builder-status');
        if (statusElement) {
            statusElement.textContent = `Status: ${status}`;
            statusElement.style.color = color;
        }
    }

    // Toggle auto builder
    function toggleAutoBuilder() {
        const config = loadConfig();
        const button = document.getElementById('builder-toggle-btn');
        
        if (config.autoRun) {
            config.autoRun = false;
            saveConfig(config);
            
            if (nextCheckTimer) {
                clearTimeout(nextCheckTimer);
                nextCheckTimer = null;
            }
            if (countdownInterval) {
                clearInterval(countdownInterval);
                countdownInterval = null;
            }
            
            button.textContent = 'Start Auto Build';
            button.style.backgroundColor = '#28a745';
            updateStatusDisplay('Stopped', '#999');
            updateCountdownDisplay(0);
        } else {
            config.autoRun = true;
            saveConfig(config);
            
            button.textContent = 'Stop Auto Build';
            button.style.backgroundColor = '#dc3545';
            updateStatusDisplay('Running', '#4CAF50');
            
            scheduleNextCheck(config);
        }
    }

    // Schedule next check
    function scheduleNextCheck(config) {
        const intervalMs = config.checkInterval * 60 * 1000;
        let remainingSeconds = config.checkInterval * 60;

        updateCountdownDisplay(remainingSeconds);
        
        if (countdownInterval) clearInterval(countdownInterval);
        if (nextCheckTimer) clearTimeout(nextCheckTimer);

        countdownInterval = setInterval(() => {
            remainingSeconds--;
            updateCountdownDisplay(remainingSeconds);
            
            if (remainingSeconds <= 0) {
                clearInterval(countdownInterval);
                countdownInterval = null;
            }
        }, 1000);

        nextCheckTimer = setTimeout(() => {
            debugLog('Timer triggered, reloading page...');
            window.location.reload();
        }, intervalMs);

        debugLog(`Next check scheduled in ${config.checkInterval} minutes`);
    }

    // Create UI
    function createUI() {
        debugLog('Starting UI creation');
        const config = loadConfig();
        const buildings = getAvailableBuildings();

        const uiContainer = document.createElement('div');
        uiContainer.style.cssText = 'background: #f4e4bc; padding: 15px; margin: 10px 0; border: 1px solid #603000; font-size: 12px;';

        const titleSection = document.createElement('div');
        titleSection.style.marginBottom = '20px';

        const title = document.createElement('h3');
        title.textContent = 'Auto Builder Enhanced v2.1';
        title.style.cssText = 'margin: 0 0 5px 0; font-size: 14px; font-weight: bold;';
        titleSection.appendChild(title);

        const subtitle = document.createElement('div');
        subtitle.textContent = 'Configure building sequence and automation settings';
        subtitle.style.cssText = 'color: #666; font-style: italic;';
        titleSection.appendChild(subtitle);

        uiContainer.appendChild(titleSection);

        const settingsSection = document.createElement('div');
        settingsSection.style.cssText = 'background: #fff3d9; padding: 10px; border: 1px solid #c1a264; margin-bottom: 15px;';

        const costReductionDiv = document.createElement('div');
        costReductionDiv.style.marginBottom = '10px';

        const costReductionCheckbox = document.createElement('input');
        costReductionCheckbox.type = 'checkbox';
        costReductionCheckbox.id = 'autoBuildCostReduction';
        costReductionCheckbox.checked = config.useCostReduction !== false;

        const costReductionLabel = document.createElement('label');
        costReductionLabel.htmlFor = 'autoBuildCostReduction';
        costReductionLabel.textContent = ' Use -20% cost reduction when available';
        costReductionLabel.style.cursor = 'pointer';

        costReductionDiv.appendChild(costReductionCheckbox);
        costReductionDiv.appendChild(costReductionLabel);
        settingsSection.appendChild(costReductionDiv);

        const longBuildDiv = document.createElement('div');
        longBuildDiv.style.marginBottom = '10px';

        const longBuildCheckbox = document.createElement('input');
        longBuildCheckbox.type = 'checkbox';
        longBuildCheckbox.id = 'autoBuildLongReduction';
        longBuildCheckbox.checked = config.useLongBuildReduction !== false;

        const longBuildLabel = document.createElement('label');
        longBuildLabel.htmlFor = 'autoBuildLongReduction';
        longBuildLabel.textContent = ' Auto-reduce builds longer than ';
        longBuildLabel.style.cursor = 'pointer';

        const longBuildThreshold = document.createElement('input');
        longBuildThreshold.type = 'number';
        longBuildThreshold.min = '0.5';
        longBuildThreshold.step = '0.5';
        longBuildThreshold.value = config.longBuildThreshold || 2;
        longBuildThreshold.style.cssText = 'width: 60px; padding: 2px; margin: 0 5px; background-color: #fff; border: 1px solid #c1a264;';

        const hoursLabel = document.createElement('span');
        hoursLabel.textContent = ' hours';

        longBuildDiv.appendChild(longBuildCheckbox);
        longBuildDiv.appendChild(longBuildLabel);
        longBuildDiv.appendChild(longBuildThreshold);
        longBuildDiv.appendChild(hoursLabel);

        settingsSection.appendChild(longBuildDiv);

        const resourceThresholdDiv = document.createElement('div');
        resourceThresholdDiv.style.marginBottom = '10px';

        const resourceThresholdLabel = document.createElement('label');
        resourceThresholdLabel.textContent = 'Min resource before building: ';
        resourceThresholdLabel.style.marginRight = '5px';

        const resourceThresholdInput = document.createElement('input');
        resourceThresholdInput.type = 'number';
        resourceThresholdInput.id = 'minResourceThreshold';
        resourceThresholdInput.min = '0';
        resourceThresholdInput.step = '1000';
        resourceThresholdInput.value = config.minResourceThreshold || 50000;
        resourceThresholdInput.style.cssText = 'width: 100px; padding: 2px; background-color: #fff; border: 1px solid #c1a264;';

        resourceThresholdDiv.appendChild(resourceThresholdLabel);
        resourceThresholdDiv.appendChild(resourceThresholdInput);
        settingsSection.appendChild(resourceThresholdDiv);

        const intervalDiv = document.createElement('div');
        intervalDiv.style.marginBottom = '5px';

        const intervalLabel = document.createElement('label');
        intervalLabel.textContent = 'Check interval: ';
        intervalLabel.style.marginRight = '5px';

        const intervalInput = document.createElement('input');
        intervalInput.type = 'number';
        intervalInput.id = 'checkInterval';
        intervalInput.min = '1';
        intervalInput.step = '1';
        intervalInput.value = config.checkInterval || 5;
        intervalInput.style.cssText = 'width: 60px; padding: 2px; margin: 0 5px; background-color: #fff; border: 1px solid #c1a264;';

        const minutesLabel = document.createElement('span');
        minutesLabel.textContent = ' minutes';

        intervalDiv.appendChild(intervalLabel);
        intervalDiv.appendChild(intervalInput);
        intervalDiv.appendChild(minutesLabel);

        settingsSection.appendChild(intervalDiv);
        uiContainer.appendChild(settingsSection);

        const sequenceSection = document.createElement('div');

        const sequenceHeader = document.createElement('div');
        sequenceHeader.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;';

        const sequenceTitle = document.createElement('div');
        sequenceTitle.textContent = 'Building Sequence';
        sequenceTitle.style.cssText = 'font-weight: bold;';
        sequenceHeader.appendChild(sequenceTitle);

        const clearButton = document.createElement('button');
        clearButton.textContent = 'Clear All';
        clearButton.className = 'btn btn-default';
        clearButton.onclick = () => {
            sequenceList.innerHTML = '';
            const emptyText = document.createElement('div');
            emptyText.textContent = 'No buildings in sequence';
            emptyText.style.cssText = 'color: #666; font-style: italic; text-align: center;';
            sequenceList.appendChild(emptyText);
            UI.SuccessMessage('Sequence cleared');
        };
        sequenceHeader.appendChild(clearButton);

        sequenceSection.appendChild(sequenceHeader);

        const sequenceList = document.createElement('div');
        sequenceList.id = 'buildSequenceList';
        sequenceList.style.cssText = 'border: 1px solid #c1a264; padding: 10px; margin-bottom: 10px; min-height: 50px; background: #fff3d9;';

        function initializeSequenceList() {
            if (!config.buildSequence || config.buildSequence.length === 0) {
                const emptyText = document.createElement('div');
                emptyText.textContent = 'No buildings in sequence';
                emptyText.style.cssText = 'color: #666; font-style: italic; text-align: center;';
                sequenceList.appendChild(emptyText);
            } else {
                config.buildSequence.forEach(item => {
                    addSequenceItem(item.building, item.targetLevel);
                });
            }
        }

        sequenceSection.appendChild(sequenceList);

        const addControls = document.createElement('div');
        addControls.style.cssText = 'display: flex; gap: 10px; align-items: center; background: #fff3d9; padding: 10px; border: 1px solid #c1a264;';

        const buildingSelect = document.createElement('select');
        buildingSelect.style.cssText = 'flex: 1; padding: 2px; background-color: #fff; border: 1px solid #c1a264;';

        const defaultOption = document.createElement('option');
        defaultOption.value = '';
        defaultOption.textContent = '-- Select Building --';
        defaultOption.disabled = true;
        defaultOption.selected = true;
        buildingSelect.appendChild(defaultOption);

        buildings.forEach(building => {
            const option = document.createElement('option');
            option.value = building.id;
            option.textContent = `${building.name} (${building.currentLevel})`;
            buildingSelect.appendChild(option);
        });

        const untilLevelInput = document.createElement('input');
        untilLevelInput.type = 'number';
        untilLevelInput.min = '1';
        untilLevelInput.style.cssText = 'width: 80px; padding: 2px; background-color: #fff; border: 1px solid #c1a264;';
        untilLevelInput.placeholder = 'Target lvl';

        const addButton = document.createElement('button');
        addButton.textContent = 'Add to Sequence';
        addButton.className = 'btn';
        addButton.onclick = () => {
            if (!buildingSelect.value) {
                UI.ErrorMessage('Please select a building');
                return;
            }

            const buildingId = buildingSelect.value;
            const building = buildings.find(b => b.id === buildingId);
            const currentLevel = parseInt(building.currentLevel.replace(/[^\d]/g, '')) || 0;
            const targetLevel = parseInt(untilLevelInput.value);

            if (!targetLevel) {
                UI.ErrorMessage('Please enter a target level');
                return;
            }

            if (targetLevel <= currentLevel) {
                UI.ErrorMessage('Target level must be higher than current level');
                return;
            }

            const emptyText = sequenceList.querySelector('div[style*="text-align: center"]');
            if (emptyText) {
                sequenceList.innerHTML = '';
            }

            addSequenceItem(buildingId, targetLevel);
            untilLevelInput.value = '';
            buildingSelect.value = '';
        };

        addControls.appendChild(buildingSelect);
        addControls.appendChild(untilLevelInput);
        addControls.appendChild(addButton);
        sequenceSection.appendChild(addControls);

        function addSequenceItem(buildingId, targetLevel) {
            const building = buildings.find(b => b.id === buildingId);
            if (!building) return;

            const item = document.createElement('div');
            item.className = 'sequence-item';
            item.style.cssText = 'display: flex; gap: 10px; margin-bottom: 5px; align-items: center; background: #fff; padding: 5px; border: 1px solid #c1a264;';

            const text = document.createElement('span');
            text.style.flex = '1';
            text.textContent = `${building.name} to level ${targetLevel}`;

            const buttonsDiv = document.createElement('div');
            buttonsDiv.style.cssText = 'display: flex; gap: 5px;';

            const moveUpBtn = document.createElement('button');
            moveUpBtn.innerHTML = '&#9650;';
            moveUpBtn.className = 'btn';
            moveUpBtn.style.padding = '0 5px';
            moveUpBtn.onclick = () => {
                const prev = item.previousElementSibling;
                if (prev) sequenceList.insertBefore(item, prev);
            };

            const moveDownBtn = document.createElement('button');
            moveDownBtn.innerHTML = '&#9660;';
            moveDownBtn.className = 'btn';
            moveDownBtn.style.padding = '0 5px';
            moveDownBtn.onclick = () => {
                const next = item.nextElementSibling;
                if (next) sequenceList.insertBefore(next, item);
            };

            const removeBtn = document.createElement('button');
            removeBtn.innerHTML = '&#10005;';
            removeBtn.className = 'btn';
            removeBtn.style.padding = '0 5px';
            removeBtn.style.color = '#ff0000';
            removeBtn.onclick = () => {
                item.remove();
                if (sequenceList.children.length === 0) {
                    const emptyText = document.createElement('div');
                    emptyText.textContent = 'No buildings in sequence';
                    emptyText.style.cssText = 'color: #666; font-style: italic; text-align: center;';
                    sequenceList.appendChild(emptyText);
                }
            };

            buttonsDiv.appendChild(moveUpBtn);
            buttonsDiv.appendChild(moveDownBtn);
            buttonsDiv.appendChild(removeBtn);

            item.appendChild(text);
            item.appendChild(buttonsDiv);
            sequenceList.appendChild(item);
        }

        uiContainer.appendChild(sequenceSection);

        const saveButton = document.createElement('button');
        saveButton.textContent = 'Save Settings';
        saveButton.className = 'btn';
        saveButton.style.marginTop = '10px';
        saveButton.onclick = () => {
            const sequence = [];
            const items = sequenceList.querySelectorAll('.sequence-item');

            items.forEach(item => {
                const text = item.querySelector('span').textContent;
                const [buildingName, levelText] = text.split(' to level ');
                const building = buildings.find(b => b.name === buildingName);

                if (building) {
                    const targetLevel = parseInt(levelText);
                    sequence.push({
                        building: building.id,
                        targetLevel: targetLevel
                    });
                }
            });

            const newConfig = {
                useCostReduction: costReductionCheckbox.checked,
                useLongBuildReduction: longBuildCheckbox.checked,
                longBuildThreshold: parseFloat(longBuildThreshold.value) || 2,
                minResourceThreshold: parseInt(resourceThresholdInput.value) || 50000,
                checkInterval: parseInt(intervalInput.value) || 5,
                buildSequence: sequence,
                autoRun: config.autoRun
            };

            saveConfig(newConfig);
            UI.SuccessMessage(`Settings saved! Sequence contains ${sequence.length} buildings.`);
        };

        uiContainer.appendChild(saveButton);

        const buildingsTable = document.getElementById('buildings');
        if (buildingsTable && buildingsTable.parentElement) {
            buildingsTable.parentElement.insertBefore(uiContainer, buildingsTable);
        }

        initializeSequenceList();
        debugLog('UI creation completed');
    }

    function debugLog(message, data = null) {
        if (!DEBUG) return;
        const timestamp = new Date().toLocaleTimeString();
        if (data) {
            console.log(`[${timestamp}] ${message}`, data);
        } else {
            console.log(`[${timestamp}] ${message}`);
        }
    }

    function getBuildingLevel(buildingName) {
        debugLog(`Getting level for ${buildingName}`);
        try {
            const row = document.querySelector(`#main_buildrow_${buildingName}`);
            if (!row) return null;

            const buildButton = row.querySelector(`a.btn-build[id*="_${buildingName}_"]`);
            if (!buildButton) return null;

            const nextLevel = parseInt(buildButton.getAttribute('data-level-next'));
            if (isNaN(nextLevel)) return null;

            const currentLevel = nextLevel - 1;
            debugLog(`${buildingName} current level:`, currentLevel);
            return currentLevel;
        } catch (error) {
            debugLog(`Error getting level for ${buildingName}:`, error);
            return null;
        }
    }

    function canBuildResource(buildingName, config) {
        try {
            const row = document.querySelector(`#main_buildrow_${buildingName}`);
            if (!row) return false;

            const buttonSelector = config.useCostReduction ?
                  `#main_buildlink_${buildingName}_cheap` :
                  `a.btn-build[id*="_${buildingName}_"]`;

            const buildButton = row.querySelector(buttonSelector);
            if (!buildButton) return false;

            // Check if button is disabled
            const isDisabled = buildButton.classList.contains('btn-bcr-disabled') ||
                              buildButton.classList.contains('inactive');
            
            // Check if button has valid href
            const hasValidHref = buildButton.getAttribute('href') && 
                                buildButton.getAttribute('href') !== '#';

            // CRITICAL: Check if we actually have enough resources
            const hasResources = hasEnoughResources(buildingName);

            const canBuild = hasValidHref && !isDisabled && hasResources;
            
            debugLog(`Can build ${buildingName}:`, {
                hasValidHref,
                isDisabled,
                hasResources,
                canBuild
            });

            return canBuild;
        } catch (error) {
            debugLog(`Error checking if ${buildingName} can be built:`, error);
            return false;
        }
    }

    function applyBuildTimeReduction() {
        try {
            const reductionButtons = document.querySelectorAll('a.order_feature.btn.btn-btr');
            if (!reductionButtons || reductionButtons.length === 0) return false;

            const lastButton = reductionButtons[reductionButtons.length - 1];
            lastButton.click();
            debugLog('Clicked build time reduction button');
            return true;
        } catch (error) {
            debugLog('Error applying build time reduction:', error);
            return false;
        }
    }

    function isConstructionInProgress() {
        const buildorder = document.querySelector('#buildorder_4');
        return buildorder !== null;
    }

    function reduceLongBuilds(config) {
        try {
            if (!config.useLongBuildReduction) return false;

            const threshold = config.longBuildThreshold || 2;
            const buildRows = document.querySelectorAll('#buildorder_1, #buildorder_2');

            for (const row of buildRows) {
                const durationCell = row.querySelector('td.nowrap.lit-item');
                if (!durationCell) continue;

                const timeSpan = durationCell.querySelector('span');
                if (!timeSpan) continue;

                const durationText = timeSpan.textContent.trim();
                if (!durationText) continue;

                const [hours, minutes, seconds] = durationText.split(':').map(Number);
                const totalHours = hours + minutes/60 + seconds/3600;

                if (totalHours > threshold) {
                    const reductionButton = row.querySelector('a.order_feature.btn.btn-btr:not(.btn-instant)');
                    if (reductionButton) {
                        debugLog('Found long build, clicking reduction button');
                        reductionButton.click();
                        return true;
                    }
                }
            }

            return false;
        } catch (error) {
            debugLog('Error in reduceLongBuilds:', error);
            return false;
        }
    }

    function buildResource(buildingName, config) {
        debugLog(`Attempting to build ${buildingName}`);

        try {
            // DOUBLE CHECK: Verify resources one more time before building
            if (!hasEnoughResources(buildingName)) {
                debugLog(`Insufficient resources to build ${buildingName}, aborting`);
                updateStatusDisplay('Not enough resources', '#FF6B6B');
                return false;
            }

            const row = document.querySelector(`#main_buildrow_${buildingName}`);
            if (!row) return false;

            const buttonSelector = config.useCostReduction ?
                  `#main_buildlink_${buildingName}_cheap` :
                  `a.btn-build[id*="_${buildingName}_"]`;

            const buildButton = row.querySelector(buttonSelector);
            if (!buildButton) return false;

            // Final check: button must not be disabled
            if (buildButton.classList.contains('btn-bcr-disabled') || 
                buildButton.classList.contains('inactive')) {
                debugLog(`Build button is disabled for ${buildingName}, aborting`);
                updateStatusDisplay('Button disabled', '#FF6B6B');
                return false;
            }

            const buildUrl = buildButton.getAttribute('href');
            if (!buildUrl || buildUrl === '#') {
                debugLog(`Invalid build URL for ${buildingName}, aborting`);
                return false;
            }

            debugLog(`Building ${buildingName} with URL: ${buildUrl}`);
            updateStatusDisplay('Building...', '#FFA500');

            window.location.href = buildUrl;

            if (config.useCostReduction) {
                document.addEventListener('DOMContentLoaded', function() {
                    setTimeout(() => {
                        applyBuildTimeReduction();
                        setTimeout(() => {
                            window.location.reload();
                        }, 500);
                    }, 500);
                }, { once: true });
            } else {
                document.addEventListener('DOMContentLoaded', function() {
                    setTimeout(() => {
                        window.location.reload();
                    }, 500);
                }, { once: true });
            }

            return true;
        } catch (error) {
            debugLog(`Error building ${buildingName}:`, error);
            return false;
        }
    }

    function checkAndBuild() {
        debugLog('Starting building check cycle...');
        
        const config = loadConfig();
        
        reduceLongBuilds(config);

        if (!config.autoRun) {
            debugLog('Auto-run is disabled, skipping build check');
            return;
        }

        try {
            if (isConstructionInProgress()) {
                debugLog('Construction already in progress, scheduling next check');
                updateStatusDisplay('Building in progress', '#FFA500');
                scheduleNextCheck(config);
                return;
            }

            if (!config.buildSequence || config.buildSequence.length === 0) {
                debugLog('No building sequence configured, scheduling next check');
                updateStatusDisplay('No sequence configured', '#FF6B6B');
                scheduleNextCheck(config);
                return;
            }

            if (!checkResourceThreshold(config)) {
                debugLog('Resource threshold not met, scheduling next check');
                updateStatusDisplay('Waiting for resources', '#FFD700');
                scheduleNextCheck(config);
                return;
            }

            const currentSequenceItem = config.buildSequence[0];
            const building = currentSequenceItem.building;
            const currentLevel = getBuildingLevel(building);

            debugLog('Checking sequence item:', {
                building,
                currentLevel,
                targetLevel: currentSequenceItem.targetLevel
            });

            if (currentLevel >= currentSequenceItem.targetLevel) {
                config.buildSequence.shift();
                saveConfig(config);
                debugLog('Building reached target level, removing from sequence');
                updateStatusDisplay('Target reached, reloading', '#4CAF50');

                setTimeout(() => {
                    debugLog('Reloading page after target reached');
                    window.location.reload();
                }, 2000);
                return;
            }

            if (canBuildResource(building, config)) {
                debugLog('Building available for construction, attempting to build');
                if (buildResource(building, config)) {
                    debugLog('Building command sent successfully');
                } else {
                    updateStatusDisplay('Build failed, retrying', '#FF6B6B');
                    scheduleNextCheck(config);
                }
            } else {
                debugLog('Cannot build current sequence item yet, scheduling next check');
                updateStatusDisplay('Cannot build yet', '#FFD700');
                scheduleNextCheck(config);
            }

        } catch (error) {
            debugLog('Error in checkAndBuild:', error);
            updateStatusDisplay('Error occurred, retrying', '#FF6B6B');
            scheduleNextCheck(config);
        }
    }

    function init() {
        createUI();
        createCountdownUI();
        
        const config = loadConfig();
        
        debugLog('Script initialized');
        debugLog('Config:', config);
        
        const button = document.getElementById('builder-toggle-btn');
        if (config.autoRun) {
            if (button) {
                button.textContent = 'Stop Auto Build';
                button.style.backgroundColor = '#dc3545';
            }
            updateStatusDisplay('Running', '#4CAF50');
            checkAndBuild();
        } else {
            if (button) {
                button.textContent = 'Start Auto Build';
                button.style.backgroundColor = '#28a745';
            }
            updateStatusDisplay('Stopped', '#999');
        }
        
        debugLog('Script setup completed');
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();