飞向未来增强辅助

飞向未来游戏增强辅助

// ==UserScript==
// @name         飞向未来增强辅助
// @namespace    http*://*.tiancai9.click
// @version      3.3
// @description  飞向未来游戏增强辅助
// @author       Oneszhang 丸子
// @match        http*://*.tiancai9.click
// @grant        none
// @license      GPL-3.0
// ==/UserScript==

(function () {
    'use strict';

    const DISABLE_LIST_KEY = 'disableList'; // 本地存储键
    const FISHING_SWITCH_KEY = 'fishingProtection'; // 统一使用 fishingProtection 作为存储键

    // 从 localStorage 加载禁用列表
    let disableList = JSON.parse(localStorage.getItem(DISABLE_LIST_KEY)) || [
        '草药园',
        '医疗站',
        '畜牧场',
        '采集小屋',
        '军营',
        '打猎小屋',
        '农田',
    ];

    // 从 localStorage 加载钓鱼防断线设置
    let fishingProtection = JSON.parse(localStorage.getItem(FISHING_SWITCH_KEY)) || false;

    // 保存禁用列表到 localStorage
    function saveDisableList() {
        localStorage.setItem(DISABLE_LIST_KEY, JSON.stringify(disableList));
    }

    // 保存钓鱼防断线设置到 localStorage
    function saveFishingProtection() {
        localStorage.setItem(FISHING_SWITCH_KEY, JSON.stringify(fishingProtection));
    }

    // ========== 菜单初始化 ==========
    const menuContainer = document.createElement('div');
    menuContainer.style.position = 'fixed';
    menuContainer.style.bottom = '20px';
    menuContainer.style.right = '20px';
    menuContainer.style.padding = '10px';
    menuContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
    menuContainer.style.color = '#fff';
    menuContainer.style.borderRadius = '5px';
    menuContainer.style.zIndex = '1000';
    menuContainer.style.cursor = 'move';
    menuContainer.style.width = '300px';
    menuContainer.style.overflowY = 'auto';
    menuContainer.style.maxHeight = '500px';
    document.body.appendChild(menuContainer);

    // ========== 日志功能区 ==========
    const logSection = document.createElement('div');
    const logTitle = document.createElement('h4');
    logTitle.innerText = '日志';
    logTitle.style.marginBottom = '10px';
    logTitle.style.color = '#fff';
    // logSection.appendChild(logTitle);

    const logContainer = document.createElement('div');
    logContainer.style.backgroundColor = '#333';
    logContainer.style.padding = '5px';
    logContainer.style.borderRadius = '5px';
    logContainer.style.height = '150px';
    logContainer.style.overflowY = 'auto';
    logContainer.style.color = '#fff';
    logContainer.style.fontSize = '12px';
    logSection.appendChild(logContainer);

    function addLog(message) {
        const timestamp = new Date().toLocaleTimeString();
        const logEntry = document.createElement('div');
        logEntry.innerText = `[${timestamp}] ${message}`;
        logContainer.appendChild(logEntry);

        // 限制日志数量为 100 条
        while (logContainer.children.length > 100) {
            logContainer.removeChild(logContainer.firstChild);
        }

        logContainer.scrollTop = logContainer.scrollHeight; // 滚动到底部
    }

    window.addLog = addLog;

    menuContainer.appendChild(logSection);


    // ========== 通用功能区 ==========
    const clickSection = document.createElement('div');
    const clickTitle = document.createElement('h4');
    clickTitle.innerText = '通用功能';
    clickTitle.style.marginBottom = '10px';
    clickTitle.style.color = '#fff';
    // clickSection.appendChild(clickTitle);

    // 通用点击按钮生成
    function createClickButton(text, color, target) {
        const button = document.createElement('button');
        button.innerText = text;
        button.style.padding = '5px 10px';
        button.style.backgroundColor = color;
        button.style.color = 'white';
        button.style.border = 'none';
        button.style.borderRadius = '3px';
        button.style.cursor = 'pointer';
        button.style.margin = '5px 5px 5px 0';
        button.addEventListener('click', () => clickTarget(target));
        clickSection.appendChild(button);
    }

    createClickButton('砍树', '#4CAF50', '大树');
    // createClickButton('农田', '#2196F3', '农田');
    // createClickButton('居所', '#FFD700', '居所');
    // createClickButton('仓库', '#FF5122', '仓库');
    createClickButton('建筑五列', '#FF5722', '建筑五列');
    createClickButton('自动钓鱼', '#009688', '自动钓鱼');
    menuContainer.appendChild(clickSection);

    // ========== Auto Fishing 功能 ==========
    //钓鱼防断线
    const fishingSwitchContainer = document.createElement('div');
    const fishingSwitchLabel = document.createElement('label');
    const fishingSwitch = document.createElement('input');
    fishingSwitch.type = 'checkbox';
    fishingSwitch.checked = fishingProtection; // 使用统一的变量
    fishingSwitchLabel.appendChild(fishingSwitch);
    fishingSwitchLabel.appendChild(document.createTextNode(' 钓鱼防断线开关'));
    fishingSwitchContainer.appendChild(fishingSwitchLabel);
    clickSection.appendChild(fishingSwitchContainer);

    fishingSwitch.addEventListener('change', () => {
        fishingProtection = fishingSwitch.checked; // 更新变量
        localStorage.setItem(FISHING_SWITCH_KEY, JSON.stringify(fishingProtection)); // 使用统一的存储键
        if (fishingProtection) {
            addLog('钓鱼防断线开关已开启');
            initialize();
        } else {
            addLog('钓鱼防断线开关已关闭');
            stopAutoFishing();
        }
    });

    //自动钓鱼
    let autoFishing = false; // 标记是否正在自动钓鱼
    let autoFishingInterval = null; // 存储定时器ID
    const MAX_CONSECUTIVE_ZERO = 3; // 最大连续0%进度次数
    let consecutiveZeroCount = 0; // 当前连续0%进度次数

    async function autoFishingProcess() {
        const holdButton = Array.from(document.querySelectorAll('button')).find(btn => btn.innerText.includes('按住我'));
        const progressText = () => document.querySelector('div.el-progress__text > span');

        if (!holdButton) {
            addLog('未找到“按住我”按钮,没鱼竿啊老铁!');
            stopAutoFishing();
            return;
        }

        try {
            while (autoFishing) {
                // 模拟长按(mousedown)
                holdButton.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
                addLog('抛竿!钓鱼ing~');

                // 轮询检查进度
                let progress = 0;
                consecutiveZeroCount = 0; // 重置计数器
                while (autoFishing && progress < 100) {
                    await new Promise(resolve => setTimeout(resolve, 500)); // 每500ms检查一次
                    const progressElement = progressText();
                    if (progressElement) {
                        progress = parseInt(progressElement.innerText);
                        addLog(`当前进度: ${progress}%`);

                        if (progress === 0 || progress === 100) {
                            consecutiveZeroCount += 1;
                            addLog(`鱼口监控: ${consecutiveZeroCount}`);
                            if (consecutiveZeroCount >= MAX_CONSECUTIVE_ZERO) {
                                addLog('检测到爆杆,重新尝试钓鱼');
                                break; // 跳出内层循环,重新开始钓鱼
                            }
                        } else {
                            // 如果进度不是0,重置计数器
                            consecutiveZeroCount = 0;
                        }
                    } else {
                        addLog('未找到钓鱼进度条元素');
                        break;
                    }
                }

                if (progress >= 100) {
                    // 释放长按(mouseup)
                    holdButton.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
                    addLog('鱼来!!!!');

                    // 等待一段时间再进行下一次钓鱼(根据游戏的冷却时间调整)
                    await new Promise(resolve => setTimeout(resolve, 2000)); // 等待2秒
                } else if (consecutiveZeroCount >= MAX_CONSECUTIVE_ZERO) {
                    // 释放长按(mouseup)
                    holdButton.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
                    addLog('钓呲了,重新尝试钓鱼');

                    // 等待一段时间再重新尝试
                    await new Promise(resolve => setTimeout(resolve, 1000)); // 等待1秒
                } else {
                    // 如果在过程中被停止或其他原因
                    holdButton.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
                    addLog('自动钓鱼已停止或遇到问题');

                    if (fishingProtection) {
                        // 等待一段时间再重新尝试
                        await new Promise(resolve => setTimeout(resolve, 1000)); // 等待1秒
                    }
                }
            }
        } catch (error) {
            addLog(`自动钓鱼过程中出错: ${error}`);
            stopAutoFishing();
        }
    }

    function startAutoFishing() {
        if (autoFishing) {
            addLog('自动钓鱼已在运行中');
            return;
        }
        autoFishing = true;
        addLog('启动自动钓鱼');
        autoFishingProcess();
    }

    function stopAutoFishing() {
        if (!autoFishing) {
            addLog('自动钓鱼未在运行');
            return;
        }
        autoFishing = false;
        addLog('停止自动钓鱼');

        // 钓鱼防断开启才执行
        if (fishingProtection) {
            setTimeout(() => {
                addLog('重新启动自动钓鱼');
                startAutoFishing();
            }, 5000); // 5000毫秒 = 5秒
        }
    }

    async function clickTarget(text) {
        if (text === '建筑五列') {
            const styleElement = document.createElement('style');
            styleElement.innerHTML = `
                .building-box .building {
                    width: calc(20% - 0.35rem) !important;
                }
            `;
            document.head.appendChild(styleElement);
            addLog('已应用建筑五列样式');
            return;
        }

        if (text === '自动钓鱼') {
            if (autoFishing) {
                stopAutoFishing();
            } else {
                startAutoFishing();
            }
            return;
        }

        const targetSpans = Array.from(document.querySelectorAll('div')).filter(span => span.innerText.includes(text));
        if (targetSpans.length === 0) {
            addLog(`未找到包含 "${text}" 的元素`);
            return;
        }

        addLog(`开始撸 "${text}" `);
        for (let i = 0; i < 30; i++) { // 可调整点击次数
            targetSpans.forEach(span => span.click());
            await new Promise(resolve => setTimeout(resolve, 50)); // 50ms 延迟
        }
        addLog(`完成撸 "${text}" `);
    }

    // ========== 禁用列表管理功能区 ==========
    const disableSection = document.createElement('div');
    const disableTitle = document.createElement('h4');
    disableTitle.innerText = '管理禁用列表';
    disableTitle.style.marginBottom = '10px';
    disableTitle.style.color = '#fff';
    // disableSection.appendChild(disableTitle);

    function toggleDisableBuildings() {
        const elements = Array.from(document.querySelectorAll('[data-name]'));
        let hidden = false;

        disableList.forEach(dataName => {
            elements.forEach(el => {
                if (el.getAttribute('data-name') === dataName) {
                    if (el.style.pointerEvents === 'none') {
                        el.style.pointerEvents = '';
                        el.style.opacity = '';
                    } else {
                        el.style.pointerEvents = 'none';
                        el.style.opacity = '0.5';
                        hidden = true;
                    }
                }
            });
        });

        addLog(
            hidden
                ? `已隐藏禁用列表中的建筑: ${disableList.join(', ')}`
                : `已恢复禁用列表中的建筑: ${disableList.join(', ')}`
        );
    }

    const toggleButton = document.createElement('button');
    toggleButton.innerText = '禁用/开启无用建筑';
    toggleButton.style.marginBottom = '10px';
    toggleButton.style.backgroundColor = '#FF9800';
    toggleButton.style.color = 'white';
    toggleButton.style.border = 'none';
    toggleButton.style.borderRadius = '3px';
    toggleButton.style.padding = '5px 10px';
    toggleButton.style.cursor = 'pointer';
    toggleButton.addEventListener('click', toggleDisableBuildings);
    disableSection.appendChild(toggleButton);

    menuContainer.appendChild(disableSection);

    const inputContainer = document.createElement('div');
    inputContainer.style.display = 'flex';
    inputContainer.style.marginBottom = '10px';

    const inputField = document.createElement('input');
    inputField.type = 'text';
    inputField.style.cursor = 'text !important';
    inputField.placeholder = '添加到禁用列表';
    inputField.style.flex = '1';
    inputField.style.color = '#000';
    inputField.style.padding = '5px';
    inputField.style.marginRight = '5px';
    inputField.style.borderRadius = '3px';
    inputField.style.border = '1px solid #ccc';
    inputContainer.appendChild(inputField);

    const addButton = document.createElement('button');
    addButton.innerText = '添加';
    addButton.style.backgroundColor = '#4CAF50';
    addButton.style.color = 'white';
    addButton.style.border = 'none';
    addButton.style.borderRadius = '3px';
    addButton.style.padding = '5px 10px';
    addButton.style.cursor = 'pointer';
    addButton.addEventListener('click', () => {
        const value = inputField.value.trim();
        if (value && !disableList.includes(value)) {
            disableList.push(value);
            inputField.value = '';
            refreshDisableList();
            saveDisableList();
            addLog(`添加到禁用列表: ${value}`);
        }
    });
    inputContainer.appendChild(addButton);

    disableSection.appendChild(inputContainer);

    const disableListContainer = document.createElement('div');
    disableListContainer.style.marginBottom = '10px';
    disableSection.appendChild(disableListContainer);

    function refreshDisableList() {
        disableListContainer.innerHTML = '';
        disableList.forEach((item, index) => {
            const listItem = document.createElement('div');
            listItem.style.display = 'flex';
            listItem.style.justifyContent = 'space-between';
            listItem.style.alignItems = 'center';
            listItem.style.marginBottom = '5px';

            const text = document.createElement('span');
            text.innerText = item;
            listItem.appendChild(text);

            const deleteButton = document.createElement('button');
            deleteButton.innerText = '删除';
            deleteButton.style.backgroundColor = '#FF5722';
            deleteButton.style.color = 'white';
            deleteButton.style.border = 'none';
            deleteButton.style.borderRadius = '3px';
            deleteButton.style.padding = '2px 5px';
            deleteButton.style.cursor = 'pointer';
            deleteButton.addEventListener('click', () => {
                disableList.splice(index, 1);
                refreshDisableList();
                saveDisableList();
                addLog(`从禁用列表移除: ${item}`);
            });
            listItem.appendChild(deleteButton);

            disableListContainer.appendChild(listItem);
        });
    }

    refreshDisableList();

    // ========== 拖动功能 ==========
    let offsetX, offsetY;
    menuContainer.addEventListener('mousedown', (e) => {
        // 仅在点击菜单的顶部(比如标题区域)时才开始拖动
        if (e.target === menuContainer || e.target.tagName.toLowerCase() === 'h4') {
            offsetX = e.clientX - menuContainer.getBoundingClientRect().left;
            offsetY = e.clientY - menuContainer.getBoundingClientRect().top;

            menuContainer.style.cursor = 'grabbing';
            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', onMouseUp);
        }
    });

    function onMouseMove(e) {
        menuContainer.style.left = `${e.clientX - offsetX}px`;
        menuContainer.style.top = `${e.clientY - offsetY}px`;
        menuContainer.style.bottom = '';
        menuContainer.style.right = '';
    }

    function onMouseUp() {
        menuContainer.style.cursor = 'move';
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
    }

    // ========== 折叠功能区初始化 ==========
    function createCollapsibleSection(titleText, sectionContent) {
        const section = document.createElement('div');
        const header = document.createElement('div');
        const content = document.createElement('div');

        // Header样式和内容
        header.innerText = titleText;
        header.style.cursor = 'pointer';
        header.style.padding = '5px 10px';
        header.style.backgroundColor = '#444';
        header.style.color = '#fff';
        header.style.borderRadius = '3px';
        header.style.marginBottom = '5px';

        // Content样式
        content.style.overflow = 'hidden';
        content.style.transition = 'max-height 0.3s ease';
        content.style.maxHeight = '0px';
        content.style.padding = '0 10px';
        content.style.backgroundColor = '#333';
        content.style.color = '#fff';
        content.style.borderRadius = '3px';

        // 绑定点击事件
        header.addEventListener('click', () => {
            if (content.style.maxHeight === '0px') {
                content.style.maxHeight = content.scrollHeight + 'px';
            } else {
                content.style.maxHeight = '0px';
            }
        });

        // 组装
        content.appendChild(sectionContent);
        section.appendChild(header);
        section.appendChild(content);

        return section;
    }

    // ========== 日志功能区折叠 ==========
    const logContent = document.createElement('div');
    logContent.appendChild(logSection);
    const collapsibleLogSection = createCollapsibleSection('日志', logContent);

    // ========== 通用功能区折叠 ==========
    const clickContent = document.createElement('div');
    clickContent.appendChild(clickSection);
    const collapsibleClickSection = createCollapsibleSection('通用功能', clickContent);

    // ========== 禁用列表功能区折叠 ==========
    const disableContent = document.createElement('div');
    disableContent.appendChild(disableSection);
    const collapsibleDisableSection = createCollapsibleSection('管理禁用列表', disableContent);

    // ========== 添加折叠后的功能区到菜单 ==========
    menuContainer.innerHTML = ''; // 清空初始内容
    menuContainer.appendChild(collapsibleLogSection);
    menuContainer.appendChild(collapsibleClickSection);
    menuContainer.appendChild(collapsibleDisableSection);

    // 在脚本加载时自动启动钓鱼
    function initAutoFishing() {
        addLog('脚本加载完成,自动启动钓鱼');
        startAutoFishing(); // 调用自动钓鱼功能
    }

    // 每10分钟刷新页面
    function autoRefreshPage() {
        if (fishingProtection) { // 只有在钓鱼防断开启时才执行刷新
            setInterval(() => {
                addLog('10分钟到,正在刷新页面...');
                window.location.reload();
            }, 10 * 60 * 1000); // 10分钟(单位:毫秒)
        }
    }

    // 初始化功能
    function initialize() {
        if (fishingProtection) { // 只有在钓鱼防断开启时才执行
            initAutoFishing(); // 启动自动钓鱼
            autoRefreshPage(); // 启动定时刷新
        }
    }

    // 启动脚本功能
    initialize();
})();