Greasy Fork

Greasy Fork is available in English.

DRRR助手(drrr-helper) 2024新春版

Dollars聊天室辅助脚本

当前为 2024-02-11 提交的版本,查看 最新版本

// ==UserScript==
// @name        DRRR助手(drrr-helper) 2024新春版
// @description Dollars聊天室辅助脚本
// @namespace   Violentmonkey Scripts
// @match       https://drrr.com/room/*
// @license     MIT
// @version     9.0.1
// @author      QQ:121610059
// @update      2024-02-11 14:05:03
// @supportURL  http://greasyfork.icu/zh-CN/scripts/414535
// ==/UserScript==

(function () {
    'use strict';

    //  注入器地址
    const injectorSrc = '//43.142.80.6/drrr/drrr-help-injector.js';

    //  清空控制台信息
    console.clear();

    // 打印帮助信息
    console.log('%cDRRR HELPER API帮助信息 author qq:121610059', 'color: #ff6600; font-size: 16px; font-weight: bold;');
    console.log('%cDRRR_HELPER_API.addEventListener(eventName, callback) - 添加事件监听器方法', 'color: #336699;');
    console.log('%cDRRR_HELPER_API.showTip(message, type, title, time) - 显示提示信息方法', 'color: #336699;');
    console.log('%cDRRR_HELPER_API.insertLocalMessage(message) - 将消息插入到页面方法', 'color: #336699;');
    console.log('%cDRRR_HELPER_API.triggerEvent(eventName, data) - 触发事件方法', 'color: #336699;');
    console.log('%cDRRR_HELPER_API.sendMessage(data) - 发送消息方法', 'color: #336699;');
    console.log('%cmessage({message, from})%c - 本文信息事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cnew-host({user})%c - 更换房主事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cleave({user})%c - 离开事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cjoin({user})%c - 加入事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%ckick({to})%c - 踢出事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cban({to})%c - 禁入事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cmusicStart(music)%c - 开始播放事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cmusicPause(music)%c - 暂停播放事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cmusicEnd((music))%c - 播放结束事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cmusicStop(music)%c - 停止播放事件', 'color: #336699; font-weight: bold;', 'color: #336699;');
    console.log('%cmusicError(errCode)%c - 播放错误事件', 'color: #336699; font-weight: bold;', 'color: #336699;');

    //  进入房间房间失败
    if (document.querySelector('.container')) {
        alert('进入房间失败,请尝试其他房间。');
        return;
    }

    // 创建一个立即执行函数表达式,用于创建全局API,并将其绑定到 window 对象上
    const DRRR_HELPER_API = (() => {
        // 存储事件监听器的对象
        const listeners = {};

        // 添加事件监听器的方法
        const addEventListener = (eventName, callback) => {
            // 如果该事件类型不存在,创建一个空数组
            if (!listeners[eventName]) {
                listeners[eventName] = [];
            }
            // 将回调函数添加到对应事件类型的数组中
            listeners[eventName].push(callback);
        }

        // 触发事件的方法
        const triggerEvent = (eventName, data) => {
            // 获取该事件类型的回调函数数组
            const eventListeners = listeners[eventName];
            // 如果存在回调函数数组,依次执行每个回调函数并传递数据
            if (eventListeners) {
                eventListeners.forEach(callback => callback(data));
            }
        }

        // 提示信息
        const showTip = (message, type = '', title = '提示信息', time = 3000) => {
            unsafeWindow.swal(title, message, type);
            setTimeout(() => unsafeWindow.swal.close(), time);
        }

        // 发送消息方法
        const sendMessage = (data) => {
            // 检查消息内容是否是对象
            if (typeof data !== 'object' || data === null) {
                console.error('发送的消息内容不是一个有效的对象');
                return;
            }

            // 发送 POST 请求
            $.ajax({
                type: "POST",
                url: "?ajax=1",
                data: data,
                success: function(response) {
                    if (response === '') {
                        console.log('发送消息成功');
                        data.message && DRRR_HELPER_API.insertLocalMessage(data.message);
                    } else {
                        console.error('发送请求成功,但响应不正确');
                    }
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    console.error('发送消息失败:', errorThrown);
                }
            });
        }

        // 插入消息到页面
        const insertLocalMessage = (message) => {
            // 忽略me消息
            if (message.startsWith('/me')) return;

            // 插入本地消息
            const icon = profile.icon;
            const div = `
            <dl class="talk ${icon}">
                <dt class="dropdown user">
                    <div class="avatar avatar-${icon}"></div>
                    <div class="name" data-toggle="dropdown">
                        <span class="select-text">${name}</span>
                    </div>
                    <ul class="dropdown-menu" role="menu"></ul>
                </dt>
                <dd class="bounce">
                    <div class="bubble">
                        <div class="tail-wrap center" style="background-size: 65px">
                            <div class="tail-mask"></div>
                        </div>
                        <p class="body select-text">${message.replace(/\n/g, '<br>')}</p>
                    </div>
                </dd>
            </dl>`;

            // 延迟1.5秒插入本地消息
            setTimeout(function() {
                talks.insertAdjacentHTML("afterbegin", div)
            }, 1000)
        }

        // 将方法暴露在 window 对象上的 DRRR_HELPER_EVENT 属性下
        return unsafeWindow.DRRR_HELPER_API = {
            addEventListener,
            triggerEvent,
            showTip,
            sendMessage,
            insertLocalMessage
        };
    })();

    // 拦截最新消息
    $(document).ajaxSuccess(function(event, xhr, settings) {
        // 检查是否是发送更新请求
        if (!settings.url.includes('update')) return;

        // 检查是否有响应数据和聊天记录
        const talks = xhr.responseJSON.talks || [];
        if (talks.length === 0) return;

        // 遍历聊天记录并触发事件
        talks.forEach(function(data) {
            // 如果是自己发送的消息则忽略
            if (data.is_me) return;

            // 构造事件数据对象
            const eventData = {};
            if (data.message) eventData.message = data.message;
            if (data.from) eventData.from = data.from;
            if (data.user) eventData.user = data.user;
            if (data.music) eventData.music = data.music;
            if (data.to) eventData.to = data.to;

            // 触发事件
            DRRR_HELPER_API.triggerEvent(data.type, eventData);
        });
    });


    //  Hook音乐播放事件
    unsafeWindow.MusicItem = function() {
        function e(n) {
            var r = this;
            _classCallCheck(this, e),
                this.music = n,
                this.name = DRRRClientBehavior.literalMusicTitle(n),
                this.url = n.playURL,
                this.schedule = null;
            var o = function() {
                DRRR_HELPER_API.triggerEvent("musicEnd", r.music);
                r._unschedule_progress_update(100),
                visualizerEnabled && visualizer.stop(),
                    Player.isPausing = !0,
                    $(document).trigger("music-end", r)
            }
                , i = function() {
                DRRR_HELPER_API.triggerEvent("musicPause", r.music);
                r._unschedule_progress_update(100 * r.percent())
            }
                , a = function() {
                DRRR_HELPER_API.triggerEvent("musicStart", r.music);
                r._schedule_progress_update()
            }
                , s = function() {
                DRRR_HELPER_API.triggerEvent("musicStop", r.music);
                r._unschedule_progress_update()
            };
            "apple_music" == n.source ? this.howl = new AppleMusicBackend(n,{
                autoplay: !1,
                onend: o,
                onpause: i,
                onplay: a,
                onstop: s
            }) : this.howl = new Howl({
                autoplay: !1,
                src: [this.url],
                html5: !0,
                volume: visualizerEnabled ? 1 : Player.volume,
                onload: function() {
                    visualizerEnabled && visualizer.play(r._sounds[0]._node)
                },
                onend: o,
                onpause: i,
                onplay: a,
                onstop: s,
                onloaderror: function(e, n) {
                    DRRR_HELPER_API.triggerEvent("musicError", n);
                    if (r._unschedule_progress_update(),
                    "不支持该音频格式" != n && ("不支持所选音频源的编解码器。" != n || -1 === r.url.indexOf(visualizerUrlPrefix))) {
                        switch (n = n || "Unknown") {
                            case 1:
                                n = "获取过程被用户中止";
                                break;
                            case 2:
                                n = "下载时发生错误";
                                break;
                            case 3:
                                n = "解码时发生错误";
                                break;
                            case 4:
                                n = "URL不正确或不支持音频"
                        }
                        visualizerEnabled && visualizer.stop(),
                            swal(t("Music: "), t("音频无法加载: {1}", r.name) + "\n\n" + t("错误信息: {1}", n), "warning");
                            setTimeout(() => swal.close(), 2000);
                    }
                },
                onplayerror: function() {
                    r.howl.once("unlock", function() {
                        r.howl.play()
                    })
                }
            })
        }
        return _createClass(e, [{
            key: "volume",
            value: function(e) {
                this.howl.volume(e)
            }
        }, {
            key: "_schedule_progress_update",
            value: function() {
                var e = this;
                $(document).trigger("music-start", this),
                    $(document).trigger("music-update-percent", 100 * this.percent()),
                    this.schedule = setInterval(function() {
                        $(document).trigger("music-update-percent", 100 * e.percent())
                    }, 950)
            }
        }, {
            key: "_unschedule_progress_update",
            value: function() {
                var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 0;
                $(document).trigger("music-stop"),
                    clearInterval(this.schedule),
                !1 !== e && $(document).trigger("music-update-percent", e)
            }
        }, {
            key: "now",
            value: function() {
                return this.howl.seek()
            }
        }, {
            key: "setTime",
            value: function(e) {
                var t = this
                    , n = new Date;
                0 == this.duration() ? this.howl.once("play", function() {
                    var r = (new Date - n) / 1e3;
                    t.howl.seek(e + r)
                }) : e <= this.duration() ? this.howl.seek(e) : this.howl.stop()
            }
        }, {
            key: "duration",
            value: function() {
                return this.howl.duration()
            }
        }, {
            key: "percent",
            value: function() {
                return this.now() / this.duration()
            }
        }, {
            key: "play",
            value: function() {
                $(document).trigger("music-play", this),
                    Player.nowPlaying = this,
                this instanceof Howl && this.stopOthers(),
                    this.howl.play(),
                    Player.isPausing = !1,
                visualizerEnabled && visualizer.resume()
            }
        }, {
            key: "stopOthers",
            value: function() {
                var e = this;
                Player.playList.forEach(function(t) {
                    t !== e && null != t && null != t.howl && t.stop()
                })
            }
        }, {
            key: "pause",
            value: function() {
                this.howl.pause(),
                visualizerEnabled && visualizer.pause(),
                    Player.isPausing = !0
            }
        }, {
            key: "stop",
            value: function() {
                Player.isPausing = !0,
                    this.howl.stop()
            }
        }, {
            key: "unload",
            value: function() {
                clearInterval(this.schedule),
                    this.howl.unload()
            }
        }, {
            key: "previewOnly",
            get: function() {
                return "apple_music" == this.music.source && this.howl.previewOnly
            }
        }, {
            key: "time",
            get: function() {
                return this.now()
            }
        }, {
            key: "music_object",
            get: function() {
                return this.music
            }
        }]),
            e
    }();

    //  插入drrr-helper注入器
    document.head.appendChild(document.createElement('script')).src = injectorSrc + '?v=' + Date.now();
})();