// ==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 https://greasyfork.org/zh-CN/scripts/414535
// @downloadURL none
// ==/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 = `
-
${name}
-
${message.replace(/\n/g, '
')}
`;
// 延迟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();
})();