9战

9战1

// ==UserScript==
// @name         9战
// @namespace    http://tampermonkey.net/
// @version      2025-03-30
// @description  9战1
// @author       You
// @match        https://www.milkywayidle.com/game*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=milkywayidle.com
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';



    class AutoFramework {
        static #isPaused = true;
    static #controlBar;
    static #func = null;

    // 设置自动化函数
    static setFunc(f) {
        this.#func = f;
    }

    // 初始化控制栏
    static initControlBar() {
        this.#controlBar = document.createElement('div');
        this.#controlBar.id = 'autoFrameworkControlBar';
        this.#controlBar.style = `
        position: fixed;
        top: 0;
        left: 50%;
        transform: translateX(-50%);
        padding: 10px 20px; /* 增加横向内边距 */
        background: rgba(0,0,0,0.7);
        color: white;
        border-radius: 8px; /* 添加圆角 */
        box-shadow: 0 2px 6px rgba(0,0,0,0.3); /* 添加阴影 */
        z-index: 99999;
    `;

        const input = document.createElement('input');
        input.id = 'input-9-name'
        input.value = '沼泽星球'

        const btn = document.createElement('button');
        btn.textContent = '开启9战';
        btn.style = `
                padding: 8px 16px;
                font-size: 16px;
                background: #f44336;
                color: white;
                border: none;
                cursor: pointer;
                border-radius: 4px;
            `;
        btn.addEventListener('click', () => this.togglePause());
        this.#controlBar.appendChild(input);
        this.#controlBar.appendChild(btn);
        document.body.appendChild(this.#controlBar);
    }

    static togglePause() {
        this.#isPaused = !this.#isPaused;
        const btn = this.#controlBar.querySelector('button');
        btn.textContent = this.#isPaused ? '开启' : '暂停';
        btn.style.backgroundColor = this.#isPaused ? '#f44336' : '#4CAF50';
    }

    static isPaused() {
        return this.#isPaused;
    }

    static async run() {
        while (true) {
            if (!this.#isPaused && this.#func) {
                try {
                    await this.#func();
                } catch (error) {
                    console.error('执行出错:', error);
                }
            }
            await new Promise(resolve => setTimeout(resolve, 100));
        }
    }

    static findElementsByText(text, options = {}) {
        const {
            exact = false, // 是否精确匹配
            selector = '*', // 初始选择器(缩小搜索范围)
            visible = true // 是否仅可见元素
        } = options;

        const elements = document.querySelectorAll(selector);
        return Array.from(elements).filter(element => {
            if (visible && !this.isVisible(element)) return false;
            const content = element.textContent.trim();
            if (exact) return content === text;
            else return content.includes(text);
        });
    }

    static findElementByText(text, options) {
        const elements = this.findElementsByText(text, options);
        return elements.length > 0 ? elements[0] : null;
    }

    static clickElement(element) {
        if (element) {
            const event = new MouseEvent('click', {
                view: window,
                bubbles: true,
                cancelable: true
            });
            element.dispatchEvent(event);
        }
    }

    static async waitForElement(selector, timeout = 5000) {
        return new Promise((resolve, reject) => {
            const interval = setInterval(() => {
                const element = document.querySelector(selector);
                if (element) {
                    clearInterval(interval);
                    resolve(element);
                } else if (timeout <= 0) {
                    clearInterval(interval);
                    reject('元素未找到');
                }
                timeout -= 100;
            }, 100);
        });
    }

    static async waitForText(text, options = {}) {
        if (this.isPaused()) return Promise.reject('脚本已暂停');
        const { timeout = 5000, ...findOptions } = options;
        let timeout1 = timeout
        return new Promise((resolve, reject) => {
            const interval = setInterval(() => {
                const element = this.findElementByText(text, findOptions);
                if (element) {
                    clearInterval(interval);
                    resolve(element);
                } else if (timeout1 <= 0) {
                    clearInterval(interval);
                    reject(`文本 "${text}" 未找到`);
                }
                timeout1 -= 100;
            }, 100);
        });
    }

    static isVisible(element) {
        return element.offsetWidth > 0 && element.offsetHeight > 0;
    }

    static async clickByText(text, options = {}) {
        if (this.isPaused()) return;
        try {
            const element = await this.waitForText(text, options);
            this.clickElement(element);
        } catch (error) {
            console.error(`点击失败: ${error}`);
        }
    }

    static async getTextByText(text, options = {}) {
        try {
            const element = await this.waitForText(text, options);
            return element.textContent.trim();
        } catch (error) {
            console.error(`获取文本失败: ${error}`);
            return null;
        }
    }

    static findElementsByAttr(attrName, attrValue, options = {}) {
        const {
            exact = true, // 是否精确匹配(false为包含匹配)
            selector = '*', // 初始选择器
            visible = true // 是否仅可见元素
        } = options;
        const elements = document.querySelectorAll(selector);

        return Array.from(elements).filter(element => {
            if (visible && !this.isVisible(element)) return false;
            const attr = element.getAttribute(attrName);
            if (!attr) return false;

            if (exact) {
                return attr === attrValue;
            } else {
                return attr.includes(attrValue);
            }
        });
    }

    static findElementByAttr(attrName, attrValue, options) {
        const elements = this.findElementsByAttr(attrName, attrValue, options);
        return elements.length > 0 ? elements[0] : null;
    }

    static async waitForAttr(attrName, attrValue, options = {}) {
        if (this.isPaused()) return Promise.reject('脚本已暂停');
        const { timeout = 5000, ...findOptions } = options;
        let timeout1 = timeout
        return new Promise((resolve, reject) => {
            const interval = setInterval(() => {
                const element = this.findElementByAttr(attrName, attrValue, findOptions);
                if (element) {
                    clearInterval(interval);
                    resolve(element);
                } else if (timeout1 <= 0) {
                    clearInterval(interval);
                    reject(`属性匹配失败: ${attrName}=${attrValue}`);
                }
                timeout1 -= 100;
            }, 100);
        });
    }

    static async clickByAttr(attrName, attrValue, options = {}) {
        if (this.isPaused()) return;
        try {
            const element = await this.waitForAttr(attrName, attrValue, options);
            this.clickElement(element);
        } catch (error) {
            console.error(`属性点击失败: ${error}`);
        }
    }


    static reactInputTriggerHack(inputElem, value) {
        let lastValue = inputElem.value;
        inputElem.value = value;
        let event = new Event("input", { bubbles: true });
        event.simulated = true;
        let tracker = inputElem._valueTracker;
        if (tracker) {
            tracker.setValue(lastValue);
        }
        inputElem.dispatchEvent(event);
    }

    // 新增:根据class设置输入框值(支持React)
    static async setInputValueByClass(className, value, options = {}) {
        if (this.isPaused()) return;
        try {
            const element = await this.waitForAttr('class', className, {
                selector: 'input', // 仅限input元素
                exact: false,
                // 包含匹配
                ...options
            });
            if (!element) throw new Error(`未找到class为${className}的input元素`);

            this.reactInputTriggerHack(element, value);
            console.log(`设置输入值成功: ${className} -> ${value}`);
        } catch (error) {
            console.error('设置输入值失败:', error);
        }
    }
}

 async function actions() {
    const input = document.querySelector('#input-9-name').value
    if(!input){
        return
    }
    try {
        await AutoFramework.clickByText('战斗区域', {
            selector: 'button',
            timeout: 3000,
            exact: false //模糊  true 精确
        });

        await AutoFramework.clickByText(input, {
            selector: 'button',
            timeout: 3000,
            exact: false
        });

        await AutoFramework.clickByAttr('href', 'swamp_planet', {
            selector: 'use',
            exact: false,
            timeout: 3000,
            visible:false
        });

        await AutoFramework.setInputValueByClass('Input_input__2-t98', 9, {
            timeout: 3000
        });
        await AutoFramework.clickByText('添加到队列', {
            selector: 'button',
            timeout: 3000,
            exact: false
        });

    } catch (error) {
        console.error('自动化失败:', error);
    }
}

// 启动脚本
(async () => {
    AutoFramework.initControlBar();
    AutoFramework.setFunc(actions);
    AutoFramework.run();
})();
})();