zenyBoost2

个人辅助

Dette scriptet burde ikke installeres direkte. Det er et bibliotek for andre script å inkludere med det nye metadirektivet // @require https://update.greasyfork.org/scripts/511562/1822902/zenyBoost2.js

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==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 };
}
*/