ZhChat增强脚本

增强功能:鼠标中键oldnick(已消抖)、自定义邀请、过滤rule,自动更新(提醒)、lookup、lookuplast(脚本)、/zhelp(更新显示命令帮助)

目前为 2023-04-01 提交的版本。查看 最新版本

// ==UserScript==
// @name         ZhChat增强脚本
// @namespace    http://tampermonkey.net/
// @version      3.2.9
// @description  增强功能:鼠标中键oldnick(已消抖)、自定义邀请、过滤rule,自动更新(提醒)、lookup、lookuplast(脚本)、/zhelp(更新显示命令帮助)
// @author       UbisoComes (GreenDebug)
// @match        https://chat.zhangsoft.cf/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=zhangsoft.cf
// @license      MIT
// @run-at       document-end
// @grant none


// ==/UserScript==
window._script_version = {
    ver: '3.2.9',
    update_note: `更新内容:鼠标中键oldnick(已消抖)、自定义邀请、过滤rule、自动更新(提醒)、/lookup功能(脚本)、/lookuplast (脚本)、/zhelp(更新显示命令帮助)、/addshortcmd /delshortcmd(快捷命令)
    优化:
    1.修复\`hook\`的问题
    2.优化判断逻辑,防止 多判、漏判的问题
    3.修复版本号显示时机
    4.修复缓存问题,防止更新提醒失效
    5.修复\`lookup\`的问题
    6.修复\`addshortcmd\`命令的hook
    7.修复\`fastcmd\`报错修改为空数组`
};
(function () {

    /**
     * 储存
     */
    const local = {
        set: (key, value) => localStorage.setItem(key, value),
        remove: (key) => localStorage.removeItem(key),
        get: (key) => {
            let res = localStorage.getItem(key);
            return res != null ? res : undefined;

        },
        exist: (key) => localStorage.getItem(key) != undefined,

    };
    const json = JSON;
    /**
     * 提示
     */
    var is_trip_update = false, is_show_ver = false;

    const doc = window.document;
    const $_ = (q) => doc.querySelectorAll(q);
    const $ = (d) => doc.querySelector(d);
    /**
     * 翻译
     */
    var tr = {
        nick: "用户名", trip: "识别码", utype: "用户类型",
        hash: "hash", level: "等级", userid: "用户id",
        channel: "频道", client: "客户端", isme: "是我吗"
    };
    /**
     * 等级翻译
     */
    var leveltr = { "user": "普通用户", "trusted": "信任用户", "mod": "管理员", "channelOwner": "房主" };
    function info(t) {
        COMMANDS.info({ cmd: 'info', text: t });
    }
    function warn(e) {
        COMMANDS.warn({ cmd: 'warn', text: e });
    }

    /**
     * 方便lookup、lookuplast
     */
    window.zhcUsers = [];
    /**
     * 最后离开的用户
     */
    window.lastLeave = false;
    /**
     * 数组去重
     * @param {Array} _array
     * @returns
     */
    function trimSpace(_array) {
        var array = _array;
        for (var i = 0; i < array.length; i++) {
            //这里为过滤的值
            if (array[i] == " " || array[i] == null || typeof (array[i]) == "undefined" || array[i] == '  ' || array[i] == '') {
                array.splice(i, 1);
                i = i - 1;
            }
        }

        return array;
    }
    /**
     * 解除控制台限制
     * @returns
     */
    window.fuckconsole = function () {
        var iframeid = parseInt(Math.random() * 1000);
        pushMessage({ cmd: 'chat', text: `<iframe style='display:none;' id="${iframeid}"></iframe>` }, null, true);
        return document.getElementById(iframeid).contentWindow.console;

    };
    window.msg = (e) => send({ cmd: 'chat', text: e, head: localStorageGet('head') || '' });
    window._welcome = () => {
        //直接扣client.js里面的 (
        var hiyo = 'hi y'
        var max = Math.round(Math.random() * 20);

        for (var i = 0; i < max; i++) { // @ee 你想累死我啊
            hiyo += 'o'; // ee:(被打
        }

        const welcomes = `${hiyo}|awa!|uwu!|来了老弟~`.split('|');
        let txt = welcomes[Math.round(Math.random() * (welcomes.length - 1))];
        return txt;
    };
    /**
     * 格式化用户信息
     * @param {String} user
     * @returns
     */
    function UserStr(user) {
        //替换key
        let new_user = Object.keys(user).reduce((newData, key) => {
            let newKey = tr[key] || key;
            newData[newKey] = '`' +
                (s => {
                    //如果是true or false
                    if (typeof (s) == 'boolean') {
                        s = ({ 'true': '是', 'false': '否' })[s.toString()];
                    }
                    //如果包含mod等级字眼
                    if (Object.keys(leveltr).includes(s)) {
                        s = leveltr[s];
                    }
                    if (s == '' || s == undefined || s == null)
                        s = '空';
                    return s;
                })(user[key]) + '`';

            return newData;
        }, {});
        return JSON.stringify(new_user, null, 2).replaceAll('"', '').replaceAll('{', '').replaceAll('}', '');//直接格式化替换json
    }
    /**
     * enum
     */
    const Enum = {
        skip: (arr, i) => {
            let array = [];
            for (let index = i; index < arr.length; index++) {
                array.push(arr[index]);
            }
            return array;
        }
    };
    var is_oldnick_ing = false;
    /**
     * 快捷命令
     */
    window.fastcmd = [];

    function isInfastcmd(ee) {
        return fastcmd.find(c => c.name == ee) != undefined;
    }
    function getfastcmdValue(ee) {
        return fastcmd.find(c => c.name == ee);
    }
    function savefastcmd() {
        try {
            local.set('fastcmd', json.stringify(fastcmd));
        }
        catch {
            local.set('fastcmd', json.stringify([]));
        }
    }
    function loadfastcmd() {
        try {
            fastcmd = json.parse(local.get('fastcmd')) || [];
        }
        catch {
            fastcmd = [];
        }
    }
    function addfastcmd(ee, value) {
        if (!isInfastcmd(ee)) {
            if (isInfastcmd(value))
                return { success: false, msg: `不允许添加命令的值为:\`${value}\`,强制添加将导致递归` };
            fastcmd.push({ name: ee, val: value });
            savefastcmd();
            return { success: true, msg: '添加成功' };
        }
        else return { success: false, msg: `添加失败,快捷命令:\`${ee}\` 已存在` };

    }
    function removefastcmd(ee) {
        if (isInfastcmd(ee)) {
            fastcmd.splice(fastcmd.findIndex(s => s.name == ee), 1);
            savefastcmd();
            return { success: true, msg: '移除成功' };
        } else return { success: false, msg: `快捷命令:\`${ee}\` 不存在` };

    }
    window._isincmd = isInfastcmd;
    /**
     * 脚本命令
     */
    window.Script_Command = {
        zhelp: {
            help: '帮助',
            func: (e) => {

                let keys = Object.keys(Script_Command);

                if (e.length <= 0) info(`|命令列表:|\n|--|\n|${keys.join(',')}|\n要查看指定命令的帮助信息,请发送:\`/zhelp <command>\``);
                else {
                    let cmd = keys.find(k => k == e.join(''));
                    if (cmd != undefined) info(`## ${cmd} 命令的帮助:\n|名称:|${cmd}|||\n|--|--|--|--|\n|帮助:|${Script_Command[cmd].help}|||\n|用法:|${Script_Command[cmd].use || '无'}|||`);
                    else warn('`help` 找不到命令');
                }
            },
            use: '/zhelp <command> 或 /zhelp'
        },
        lookup: {
            help: '查看某位用户',
            func: (e) => {
                let nick = e.join();
                let user = zhcUsers.find(u => u.nick == nick);
                if (user != undefined) info(`# ${user.nick} 的信息:\r\n` + UserStr(user));
                else warn('`lookup` 找不到用户');
            },
            use: '/lookup <呢称>'
        },
        lookuplast: {
            help: '查看最后离开的用户信息',
            func: (e) => {
                if (lastLeave != undefined && lastLeave != false) {
                    info('# 最后离开用户的信息:\r\n' + UserStr(lastLeave));
                } else warn('最后离开的用户无记录');
            },
            use: '/lookuplast'
        },
        ver: {
            help: '显示当前`zhc增强脚本`的版本号和更新内容',
            func: (e) => {
                info(`当前版本号:${_script_version.ver}
                更新内容:${_script_version.update_note}`);
            }, use: '/ver'
        },

        welcome: {
            help: '显示一条一条欢迎信息',
            func: (e) => msg(_welcome()),
            use: '/welcome'
        },
        addshortcmd: {
            help: '添加一条快捷命令',
            use: '/addshortcmd <短的新命令> <命令>',
            func: (e) => {
                if (e.length < 2) return warn('缺少命令参数,请使用`/zhelp addshortcmd` 查看帮助');
                let key = e[0];
                let val = e[1];
                let res = addfastcmd(key, val);
                (res.success ? info : warn)(res.msg);
            }
        },
        delshortcmd: {
            help: '移除一条快捷命令',
            use: '/delshortcmd <短的命令>',
            func: (e) => {
                if (e.length < 1) return warn('缺少命令参数,请使用`/zhelp delshortcmd` 查看帮助');
                let res = removefastcmd(e[0]);
                (res.success ? info : warn)(res.msg);
            }
        }
    };
    /**
     * 侧边栏ui
     */
    const SideBarUI = {

        add: (element) => {
            let side = $('#sidebar-content');
            side.insertBefore(element, side.children[1]);
        },
        remove: (filther) => {
            let side = $('#sidebar-content');
            for (let i in side.children) {
                let item = side.children[i];
                if (filther(item)) side.removeChild(item);
            }
        }
    };

    /**
     * 判断命令
     * @param {String} c
     * @returns
     */
    function isCommand(c) {
        var keys = Object.keys(Script_Command);

        for (let p in keys) {

            let item = keys[p];

            if (item == c) return { success: true, obj: (e) => Script_Command[item].func(trimSpace(e)) };
            if (isInfastcmd(c)) {
                let val = getfastcmdValue(c).val;
                return { success: true, obj: keys.includes(val) ? Script_Command[val].func : (e) => msg(`/${val}${e.length <= 0 ? '' : ' ' + e.join(' ')}`) };
            }

        }

        return { success: false };
    }
    /**
     * 处理脚本的命令
     * @param {String} text
     */
    function handleScriptCommand(e) {
        if (e.cmd != "chat") return false;
        if (!e.text.startsWith('/')) return false;
        let t = e.text.slice(1).split(' ');
        let f = (Enum.skip(t, 1));
        let res = isCommand(t[0]);
        if (res.success) {
            res.obj(f);
            return true;
        }

        return false;
    }
    /**
     * 比较版本号
     * @param {String} ver1
     * @param {String} ver2
     * @returns {Number}
     */
    function compareVersion(ver1, ver2) {
        const v1 = ver1.split('.').map(Number);
        const v2 = ver2.split('.').map(Number);
        const len = Math.max(v1.length, v2.length);

        for (let i = 0; i < len; i++) {
            const num1 = v1[i] || 0;
            const num2 = v2[i] || 0;

            if (num1 < num2) {
                return -1;
            } else if (num1 > num2) {
                return 1;
            }
        }

        return 0;
    }
    /**
     * 检测更新
     *
     */
    function update_tip() {
        //注意:此脚本用于更新,里面只包含版本号(其他的代码是无用的,为了让greasyfork不删除脚本
        //脚本路径:https://gf.qytechs.cn/zh-CN/scripts/462606-%E7%9F%A5%E4%B9%8E-%E7%99%BE%E5%BA%A6%E5%8E%BB%E9%99%A4cookie

        if (!is_trip_update) { is_trip_update = true; } else return;
        var script = document.createElement("script");
        script.src =
            "https://gf.qytechs.cn/scripts/462606-%E7%9F%A5%E4%B9%8E-%E7%99%BE%E5%BA%A6%E5%8E%BB%E9%99%A4cookie" +
            "/code/%E7%9F%A5%E4%B9%8E%E3%80%81%E7%99%BE%E5%BA%A6%E5%8E%BB%E9%99%A4cookie.user.js?cache=" + parseInt(Math.random() * 114514);
        script.onload = () => {
            if (compareVersion(_script_version.ver, gf_script_version.last_ver) < 0) {
                info(`当前zhc增强脚本版本有更新! 请及时更新。
    当前版本: ${_script_version.ver}   新版本: ${gf_script_version.last_ver}
    新版本更新内容:${gf_script_version.last_note || '无'}`);
            }
        };
        document.head.appendChild(script);
    }
    /**
     * 鼠标中键oldnick
     */
    function nick_oldnick() {

        $('#sidebar-content').addEventListener('mousedown', (e) => {
            if (e.button === 1) { // 检测是否为鼠标中键触发的事件
                e.preventDefault();
            }
            [...$('#users').children].map(s => s.children[0]).forEach(q =>
                q.addEventListener('mousedown', (e) => {

                    if (e.button == 1 && !is_oldnick_ing) {
                        send({ cmd: 'oldnick', nick: q.textContent });
                        is_oldnick_ing = true;
                    }

                    e.preventDefault();
                }));
        });
    }
    function version(p = false) {
        if (!is_show_ver) { is_show_ver = true; } else return;//判断是否提醒过一次了
        COMMANDS.info({
            cmd: 'info', text: `zhchat增强脚本已启动,版本:v${_script_version.ver}
       ${_script_version.update_note}`
        });

    }
    function initUI() {
        nick_oldnick();//鼠标中键oldnick

    }
    function ChatLoaded() {
        version();//版本
        try {
            update_tip();//更新提示
        } catch { }

    }
    function init() {
        /************** 初始化ui **************/
        try {
            initUI();//初始化ui
            loadfastcmd();//从储存中加载fastcmd列表
            window._console = fuckconsole();//解除控制台限制
            window._info = info;
            window._warn = warn;
        }
        catch { }
        /**********************************/
        /************** 版本号显示、rule拦截 ****************/
        setTimeout(() => {
            let _info = COMMANDS.info;
            COMMANDS.info = (e) => {
                e.nick = '*';
                if (e.text.indexOf("曾用名") != -1) {
                    is_oldnick_ing = false;
                }
                if (e.type == "invite" && e.text.includes('\\rule')) {

                    e.text = e.text.replace(/\\rule/g, "【rule】")
                    _info({ cmd: 'info', text: 'rule已被拦截' })
                }

                _info(e);
            };


        }, 1000);

        /************** lookup、lookuplast ****************/
        setTimeout(() => {
            let _onlineSet = COMMANDS['onlineSet'],
                _onlineAdd = COMMANDS['onlineAdd'],
                _onlineRemove = COMMANDS['onlineRemove'],
                _changeNick = COMMANDS['changeNick'];

            COMMANDS['onlineSet'] = (e) => {
                _onlineSet(e);
                ChatLoaded();
                zhcUsers = e.users || [];
            };
            COMMANDS['onlineAdd'] = (e) => {
                _onlineAdd(e);
                delete e.cmd;
                zhcUsers.push(e);
            };
            COMMANDS['onlineRemove'] = (e) => {
                _onlineRemove(e);
                delete e.cmd;
                lastLeave = zhcUsers.find(u => u.nick == e.nick);
                zhcUsers = zhcUsers.filter(u => u.nick != e.nick);
            };
            COMMANDS['changeNick'] = (e) => {
                _changeNick(e);
                zhcUsers.map(s => {
                    if (s.nick == e.nick) {
                        s.nick = e.text;
                    }
                    return s;
                });

            };
        }, 1000);
        /************** 自定义邀请 ****************/
        setTimeout(() => {
            userInvite = function (nick) {
                var gotoChannel = prompt("设置一个去的频道(按取消随机)");
                if (gotoChannel != undefined && gotoChannel.indexOf("\\rule") != -1)
                    return pushMessage({ nick: "!", text: "你干嘛,哈哈哎哟" });

                send(gotoChannel ? { cmd: 'invite', nick: nick, to: gotoChannel } : { cmd: 'invite', nick: nick });

            }

        }, 1000);
        /************** 捕获脚本命令 ****************/
        setTimeout(() => {
            var _send = send;
            send = (e) => {
                if (!handleScriptCommand(e)) _send(e);
            };

        }, 1000);
        /******************************************/

    }
    init();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址