zenyBoost2

个人辅助

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.org/scripts/511562/1822902/zenyBoost2.js

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         zenyBoost2
// @namespace    http://tampermonkey.net/
// @namespace  https://coderschool.cn
// @version      0.2
// @description  个人辅助
// @author       yuexiaojun
// @icon         https://www.google.com/s2/favicons?sz=64&domain=huaban.com
// @include      *
// @grant        unsafeWindow
// @grant        GM_setClipboard
// @grant        GM_download
// @grant        GM_addStyle
// @grant        GM_notification

// @connect 192.168.1.2
// @connect 192.168.1.2:8093

// ==/UserScript==

let log = console.log;
let noLog = function(args){};


//字符串增强
String.prototype.format = function(...args) {
    if (args.length == 1 && typeof args[0] == 'object') {
    	let k = '', v = ''
    	return this.replace(/{[A-Za-z]+}/g, (it, i) => {
    		k = it.slice(1, -1)
    		v = args[0][k]
    		return typeof v != 'undefined' ? v : '';
    	})
    }
    return this.replace(/{(\d+)}/g, (it, i) => {
        return typeof args[i] != 'undefined' ? args[i] : '';
    });
};



//打开新窗口
function openNewWindowWithText(s) {
    // 打开一个新的窗口
    const newWindow = window.open('', '_blank', 'width=400,height=300');

    // 检查窗口是否成功打开
    if (newWindow) {
        // 向窗口的文档写入内容
        newWindow.document.write(s);
        newWindow.document.title = 'My New Window';

        // 关闭文档流,确保所有资源被正确加载
        newWindow.document.close();
        return newWindow;
    } else {
        // 如果窗口没有成功打开(可能由于浏览器阻止弹窗)
        alert('Window could not be opened. Please check your popup settings.');
    }
}

// 将 GM_xmlhttpRequest 封装成返回 Promise 的函数,该 Promise 解析为布尔值
function checkUrl(url) {
    return new Promise((resolve) => {
        GM_xmlhttpRequest({
            method: "GET",
            url: url,
            onload: function(response) {
                if (response.status >= 200 && response.status < 300) {
                    console.log("URL is accessible:", url);
                    resolve(true);  // 成功访问,返回 true
                } else {
                    console.log("URL is not accessible:", url, "Status code:", response.status);
                    resolve(false);  // 状态码不是 2xx,返回 false
                }
            },
            onerror: function() {
                console.log("Error accessing URL:", url);
                resolve(false);  // 有错误发生,返回 false
            }
        });
    });
}


async function atHome(){
	return await checkUrl("http://192.168.1.2:8093/");
}


/**
 * DOM节点定位器 - 可复用的节点查找库
 *
 * 支持三种使用方式:
 * 1. 简洁操作符: '^^>0>div:1'  (推荐,最简洁)
 * 2. 路径字符串: 'parent/parent/child:0/find:div:1'
 * 3. 链式调用: .parent().parent().child(0).find('div', 1)
 */

class DOMLocator {
    /**
     * 调试模式开关
     * 设置为 true 启用调试日志输出
     */
    static debugMode = false;

    /**
     * 设置调试模式
     * @param {boolean} enabled - 是否启用调试
     */
    static setDebug(enabled) {
        this.debugMode = enabled;
        if (enabled) {
            console.log('%c[DOMLocator] 调试模式已启用', 'color: #0066cc; font-weight: bold');
        }
    }

    /**
     * 使用简洁操作符定位节点
     * @param {HTMLElement} startNode - 起始节点
     * @param {string} pattern - 定位模式,例如: '^^>0>div:1'
     * @param {boolean} debug - 是否输出调试信息(可选,默认使用全局设置)
     * @returns {HTMLElement|null} 目标节点
     *
     * 操作符说明:
     * ^ - 父节点 (parent)
     * > - 子节点索引 (child at index)
     * >tag:idx - 特定标签的第idx个子节点 (find specific tag)
     * < - 上一个兄弟节点 (previous sibling)
     * <tag:idx - 向上找第N个特定标签的兄弟节点
     *
     * 示例:
     * '^^' - 父节点的父节点
     * '>0' - 第一个子节点
     * '>div:1' - 第2个div子节点
     * '<' - 上一个兄弟节点
     * '<div:1' - 向上第2个div兄弟节点
     * '^^<<>0' - 父节点 -> 父节点 -> 上一个兄弟 -> 第1个子节点
     */
    static locate(startNode, pattern, debug = this.debugMode) {
        if (!startNode || !pattern) return null;

        const operations = this._parseOperatorPattern(pattern);
        return this._execute(startNode, operations, debug);
    }

    /**
     * 使用路径字符串定位节点
     * @param {HTMLElement} startNode - 起始节点
     * @param {string} path - 路径,例如: 'parent/parent/child:0/find:div:1'
     * @param {boolean} debug - 是否输出调试信息(可选,默认使用全局设置)
     * @returns {HTMLElement|null} 目标节点
     */
    static locateByPath(startNode, path, debug = this.debugMode) {
        if (!startNode || !path) return null;

        const operations = this._parsePath(path);
        return this._execute(startNode, operations, debug);
    }

    /**
     * 创建链式调用构建器
     * @param {HTMLElement} startNode - 起始节点
     * @returns {LocatorBuilder} 链式调用构建器
     */
    static chain(startNode) {
        return new LocatorBuilder(startNode);
    }

    /**
     * 解析简洁操作符模式
     * @private
     */
    static _parseOperatorPattern(pattern) {
        const operations = [];

        // 正则匹配: ^(父节点) | <(上一个兄弟) | >(子节点) | >tag:idx(特定标签) | <tag:idx(特定标签兄弟)
        const regex = /(\^+)|(<+)|(>(\w+)?(?::(\d+))?)/g;

        let match;
        while ((match = regex.exec(pattern)) !== null) {
            if (match[1]) {
                // 父节点操作符 ^^^^
                operations.push({
                    type: 'parent',
                    count: match[1].length
                });
            } else if (match[2]) {
                // 上一个兄弟节点操作符 <<<
                operations.push({
                    type: 'previous',
                    count: match[2].length
                });
            } else if (match[3]) {
                // 子节点操作符 >0 或 >div:1
                const tag = match[4]; // 标签名 (可选)
                const index = match[5] ? parseInt(match[5]) : 0; // 索引

                if (tag) {
                    operations.push({
                        type: 'find',
                        tag: tag,
                        index: index
                    });
                } else {
                    operations.push({
                        type: 'child',
                        index: index
                    });
                }
            }
        }

        return operations;
    }

    /**
     * 解析路径字符串
     * @private
     */
    static _parsePath(path) {
        const operations = [];
        const parts = path.split('/').filter(p => p);

        for (const part of parts) {
            const [type, ...args] = part.split(':');

            switch (type) {
                case 'parent':
                    operations.push({ type: 'parent', count: args[0] ? parseInt(args[0]) : 1 });
                    break;
                case 'child':
                    operations.push({ type: 'child', index: args[0] ? parseInt(args[0]) : 0 });
                    break;
                case 'previous':
                    operations.push({ type: 'previous', count: args[0] ? parseInt(args[0]) : 1 });
                    break;
                case 'find':
                    operations.push({ type: 'find', tag: args[0], index: args[1] ? parseInt(args[1]) : 0 });
                    break;
            }
        }

        return operations;
    }

    /**
     * 执行操作序列
     * @private
     */
    static _execute(startNode, operations, debug = false) {
        let currentNode = startNode;

        if (debug) {
            console.group('%c[DOMLocator] 开始执行定位', 'color: #0066cc; font-weight: bold');
            console.log('起始节点:', currentNode);
            console.log('操作序列:', operations);
        }

        for (let i = 0; i < operations.length; i++) {
            const op = operations[i];
            let opName = '';
            let opDesc = '';

            try {
                switch (op.type) {
                    case 'parent':
                        opName = '↑ parent';
                        opDesc = `向上 ${op.count} 层`;
                        if (debug) {
                            console.log(`%c[步骤 ${i + 1}] ${opName}`, 'color: #666', opDesc);
                        }
                        for (let j = 0; j < op.count; j++) {
                            if (currentNode && currentNode.parentElement) {
                                currentNode = currentNode.parentElement;
                                if (debug && j < op.count - 1) {
                                    console.log(`  → 中间节点:`, currentNode);
                                }
                            } else {
                                if (debug) {
                                    console.error(`❌ 失败: 找不到父节点 (第 ${j + 1}/${op.count} 层)`);
                                }
                                console.groupEnd();
                                return null;
                            }
                        }
                        break;

                    case 'previous':
                        opName = '← previous';
                        opDesc = `向前 ${op.count} 个兄弟节点`;
                        if (debug) {
                            console.log(`%c[步骤 ${i + 1}] ${opName}`, 'color: #666', opDesc);
                        }
                        for (let j = 0; j < op.count; j++) {
                            if (currentNode && currentNode.previousElementSibling) {
                                currentNode = currentNode.previousElementSibling;
                                if (debug && j < op.count - 1) {
                                    console.log(`  → 中间节点:`, currentNode);
                                }
                            } else {
                                if (debug) {
                                    console.error(`❌ 失败: 找不到前面的兄弟节点 (第 ${j + 1}/${op.count} 个)`);
                                }
                                console.groupEnd();
                                return null;
                            }
                        }
                        break;

                    case 'child':
                        opName = '↓ child';
                        opDesc = `向下找第 ${op.index + 1} 个子节点`;
                        if (debug) {
                            console.log(`%c[步骤 ${i + 1}] ${opName}`, 'color: #666', opDesc);
                            console.log('  可用子节点:', currentNode?.children?.length || 0);
                        }
                        if (currentNode && currentNode.children && currentNode.children[op.index]) {
                            currentNode = currentNode.children[op.index];
                        } else {
                            if (debug) {
                                console.error(`❌ 失败: 找不到第 ${op.index + 1} 个子节点`);
                            }
                            console.groupEnd();
                            return null;
                        }
                        break;

                    case 'find':
                        opName = '↓ find';
                        opDesc = `向下找第 ${op.index + 1}个 <${op.tag}>`;
                        if (debug) {
                            console.log(`%c[步骤 ${i + 1}] ${opName}`, 'color: #666', opDesc);
                        }
                        const matchingChildren = Array.from(currentNode.children || [])
                            .filter(el => el.tagName.toLowerCase() === op.tag.toLowerCase());
                        if (debug) {
                            console.log(`  找到 ${matchingChildren.length} 个 <${op.tag}> 子节点`);
                        }
                        if (matchingChildren[op.index]) {
                            currentNode = matchingChildren[op.index];
                        } else {
                            if (debug) {
                                console.error(`❌ 失败: 找不到第 ${op.index + 1} 个 <${op.tag}> 子节点`);
                            }
                            console.groupEnd();
                            return null;
                        }
                        break;
                }

                if (debug) {
                    console.log(`%c  → 当前节点:`, 'color: #009933', currentNode);
                    console.log(`     标签: ${currentNode?.tagName}, 类名: "${currentNode?.className}"`);
                }
            } catch (e) {
                if (debug) {
                    console.error(`❌ 操作失败:`, e);
                }
                console.error('DOM定位失败:', e);
                console.groupEnd();
                return null;
            }
        }

        if (debug) {
            console.log('%c✅ 定位成功!', 'color: #009933; font-weight: bold; font-size: 14px');
            console.log('最终节点:', currentNode);
            console.groupEnd();
        }

        return currentNode;
    }
}

/**
 * 链式调用构建器
 */
class LocatorBuilder {
    constructor(startNode) {
        this.currentNode = startNode;
        this.operations = [];
        this.debug = DOMLocator.debugMode;
    }

    /**
     * 设置调试模式
     * @param {boolean} enabled - 是否启用调试
     * @returns {LocatorBuilder} 返回自身,支持链式调用
     */
    setDebug(enabled) {
        this.debug = enabled;
        return this;
    }

    /**
     * 向上查找父节点
     * @param {number} count - 父节点层级,默认1
     */
    parent(count = 1) {
        this.operations.push({ type: 'parent', count });
        return this;
    }

    /**
     * 向前查找上一个兄弟节点
     * @param {number} count - 向前数几个兄弟节点,默认1
     */
    previous(count = 1) {
        this.operations.push({ type: 'previous', count });
        return this;
    }

    /**
     * 向下查找第N个子节点
     * @param {number} index - 子节点索引,从0开始
     */
    child(index) {
        this.operations.push({ type: 'child', index });
        return this;
    }

    /**
     * 查找第N个特定标签的子节点
     * @param {string} tag - 标签名
     * @param {number} index - 该标签子节点的索引,从0开始
     */
    find(tag, index = 0) {
        this.operations.push({ type: 'find', tag, index });
        return this;
    }

    /**
     * 执行查找并返回结果
     * @param {boolean} debug - 是否输出调试信息(可选,默认使用实例设置)
     * @returns {HTMLElement|null}
     */
    exec(debug = this.debug) {
        return DOMLocator._execute(this.currentNode, this.operations, debug);
    }

    /**
     * 转换为简洁操作符字符串
     * @returns {string}
     */
    toOperatorPattern() {
        return this.operations.map(op => {
            switch (op.type) {
                case 'parent': return '^'.repeat(op.count);
                case 'previous': return '<'.repeat(op.count);
                case 'child': return `>${op.index}`;
                case 'find': return `>${op.tag}:${op.index}`;
            }
        }).join('');
    }

    /**
     * 转换为路径字符串
     * @returns {string}
     */
    toPath() {
        return this.operations.map(op => {
            switch (op.type) {
                case 'parent': return `parent:${op.count}`;
                case 'previous': return `previous:${op.count}`;
                case 'child': return `child:${op.index}`;
                case 'find': return `find:${op.tag}:${op.index}`;
            }
        }).join('/');
    }
}

// 导出(适配不同环境)
/*
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { DOMLocator, LocatorBuilder };
}
*/