// ==UserScript==
// @name 摸鱼派聊天室
// @namespace https://lemon-cxh.github.io/
// @version 1.5
// @description 摸鱼派聊天室,防撤回、抢红包、自动清屏、一言、机器人聊天、自动+1、悬浮查看图片
// @author Lemon
// @match https://pwl.icu/cr
// @icon https://www.google.com/s2/favicons?domain=pwl.icu
// @connect https://v1.hitokoto.cn
// @connect http://api.qingyunke.com
// @run-at document-start
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @license MIT
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
const OPEN_PACKET_URL = 'https://pwl.icu/chat-room/red-packet/open';
const HISTORY_MESSAGE_URL = 'https://pwl.icu/chat-room/more';
const HITOKOTO_URL = 'https://v1.hitokoto.cn/?c=e&c=f&c=j';
const AI_ELEMENT_ID = 'aiCheckbox';
var aiEnable = false;
const PLUS_ONE_ID = 'pulsOne';
var plusOneEnable = true;
var previousMessage = '';
var previousPlusOneMessage = '';
var redPacketAlertEnable = false;
var clearChatRoomElement;
const MESSAGE_MAX = 30;
var messageCount = 0;
unsafeWindow.redPacketMap = new Map();
function webSocketHook() {
unsafeWindow.WebSocket = new Proxy(unsafeWindow.WebSocket, {
construct(target, args) {
let obj = new target(...args);
return new Proxy(obj, proxyHandler);
}
})
};
function requestSend() {
XMLHttpRequest.prototype.mySend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(data) {
this.addEventListener('load', function() {
if (this.responseURL === OPEN_PACKET_URL) {
showMoney(this.response);
if (!redPacketAlertEnable) {
unsafeWindow.Util.closeAlert();
}
return;
}
if (-1 !== this.responseURL.indexOf(HISTORY_MESSAGE_URL)) {
queryRedPacketOnHistory(this.response);
return;
}
}, false);
this.mySend.apply(this, arguments);
}
}
function addMenu() {
addImgMouseover();
document.onreadystatechange = function(){
if(document.readyState == 'complete'){
let e = document.getElementById('redPacketBtn').parentNode.children[3];
clearChatRoomElement = e.children[0];
// AI聊天机器人
let ai = document.createElement("button");
ai.setAttribute('style', 'margin-right: 6px');
ai.innerHTML = '机器人';
e.insertBefore(ai, e.firstChild);
document.getElementById(AI_ELEMENT_ID).addEventListener( 'change', function() {
aiEnable = this.checked;
});
// 自动加一
let plusOne = document.createElement("button");
plusOne.setAttribute('style', 'margin-right: 6px');
plusOne.innerHTML = '+1';
e.insertBefore(plusOne, e.firstChild);
plusOne = document.getElementById(PLUS_ONE_ID);
plusOne.checked = true;
plusOne.addEventListener( 'change', function() {
plusOneEnable = this.checked;
});
// 红包提示
let redPacketAlert = document.createElement("button");
redPacketAlert.setAttribute('style', 'margin-right: 6px');
redPacketAlert.innerHTML = '红包详情';
e.insertBefore(redPacketAlert, e.firstChild);
redPacketAlert = document.getElementById('redPacketAlertCheck');
redPacketAlert.addEventListener( 'change', function() {
redPacketAlertEnable = this.checked;
});
// 一言
e = document.getElementById('breezemoonInput').parentNode;
let hitokoto = document.createElement("button");
hitokoto.innerHTML = '一言';
hitokoto.setAttribute('class', 'green');
e.insertBefore(hitokoto, e.lastChild.nextSibling);
hitokoto.onclick = () => sendHitokoto();
}
}
}
let proxyHandler = {
get(target, property) {
let value = target[property]
if ((typeof value) === 'function') {
value = value.bind(target)
}
return value
},
set(target, property, value) {
if (property === 'onmessage') {
let realOnMessage = value;
value = function(event) {
analyzeMessage(event, realOnMessage);
}
}
target[property] = value
return value
}
};
// 解析消息
function analyzeMessage(event, realOnMessage) {
var o = JSON.parse(event.data);
switch (o.type) {
case 'redPacketStatus':
delayOpenRedPacket(o);
realOnMessage(event);
break;
case 'revoke':
preventRevoke(o.oId);
return;
case 'msg':
messageCount++;
if (isRedPacketMessage(o.content)) {
delayOpenRedPacket(o);
} else {
chat(o);
}
realOnMessage(event);
clearChatRoom();
break;
default:
realOnMessage(event);
}
};
// 查询历史记录是否有红包
function queryRedPacketOnHistory(data) {
console.log('查询历史记录中是否有未领取红包');
let o = JSON.parse(data);
if (!o.data) {
return;
}
o.data.forEach(e => {
if (isRedPacketMessage(e.content) && notOpenRedPacket(e.content)) {
openRedPacket(e.oId);
console.log('历史消息中有未领取红包');
}
})
}
// 是否是红包信息
function isRedPacketMessage(s) {
return -1 !== s.indexOf('"msgType":"redPacket"');
}
// 是否还有未打开的红包
function notOpenRedPacket(content) {
let o = JSON.parse(content);
return o.got < o.count && o.who.every(e => unsafeWindow.Label.currentUserName != e.userName);
}
function delayOpenRedPacket(oId) {
if (unsafeWindow.ChatRoom) {
setTimeout(() => {
openRedPacket(oId);
}, 3000 + Math.round(Math.random() * 100));
}
}
// 弹窗提示抢红包信息
function showMoney(data) {
let o = JSON.parse(data);
let usesrMoney = -1;
o.who.forEach(e => {
console.log(e.userName + ' 抢到了:' + e.userMoney + '积分');
if (e.userName === unsafeWindow.Label.currentUserName) {
usesrMoney = e.userMoney;
}
});
console.log('____________________')
usesrMoney > -1 ? notice('抢到了:' + usesrMoney + '积分') : notice('很遗憾没有抢到红包');
}
// 清屏
function clearChatRoom() {
if (messageCount > MESSAGE_MAX) {
clearChatRoomElement.click();
messageCount = 0;
}
}
// 防撤回
function preventRevoke(oId) {
let source = document.getElementById('chatroom' + oId);
if (!source) {
return;
}
let href = source.firstElementChild.getAttribute('href');
let child = document.createElement("div");
child.setAttribute('style', 'color: rgb(50 50 50);margin-bottom: 10px;text-align: center;');
child.innerHTML = '' + href.substring(8) + '想要撤回消息';
source.parentNode.insertBefore(child, source);
messageCount -= 20;
}
function addImgMouseover() {
var chatRoom = document.getElementById('chats');
var observe = new MutationObserver(function (mutations,observe) {
let chats = document.getElementById('chats').querySelectorAll('.chats__item');
chats.forEach(chat => {
let content = chat.querySelector('.vditor-reset');
let imgs = content.querySelectorAll('img');
imgs.forEach(e => {
if ('emoji' !== e.getAttribute('class')) {
imgMouseover(e, 'img_' + chat.getAttribute('id'), chat);
}
})
})
});
observe.observe(chatRoom,{ childList: true});
}
function imgMouseover(e, id, chatroom) {
e.onmouseover = () => {
let imgCard = document.getElementById(id);
if (imgCard) {
imgCard.style.display = 'block';
return;
}
imgCard = document.createElement("div");
imgCard.setAttribute('id', id);
imgCard.setAttribute('style', 'position: absolute;left: 50%;transform: translate(-50%, -50%);z-index: 999;');
let s = e.outerHTML;
imgCard.innerHTML = s.slice(0, 4) + ' style="max-width: 600px;max-height: 500px"' + s.slice(4);
chatroom.appendChild(imgCard);
}
e.onmouseout = () => {
let imgCard = document.getElementById(id);
if (imgCard) {
imgCard.style.display = 'none';
}
}
}
// 判断消息内容
function chat(o) {
if (plusOneEnable) {
if (previousMessage === o.md && previousMessage !== previousPlusOneMessage) {
sendMessage(o.md);
previousPlusOneMessage = o.md;
}
previousMessage = o.md;
return;
}
if (!aiEnable || o.userName === unsafeWindow.Label.currentUserName || -1 === o.md.indexOf('@' + unsafeWindow.Label.currentUserName)) {
return;
}
let msg = o.md.replace('@' + unsafeWindow.Label.currentUserName);
aiApi(o.userName, msg);
}
// 机器人回复
function aiApi(userName, msg) {
GM_xmlhttpRequest({
method: "GET",
url: 'http://api.qingyunke.com/api.php?key=free&appid=0&msg=' + encodeURI(msg),
onload: function(response){
let o = JSON.parse(response.response);
sendMessage('@' + userName + ' ' + o.content);
},
onerror: function(response){
console.log("请求失败");
}
});
}
// 发送一言
function sendHitokoto() {
GM_xmlhttpRequest({
method: "GET",
url: HITOKOTO_URL,
onload: function(response){
if (response.status === 200) {
let o = JSON.parse(response.response);
document.getElementById('breezemoonInput').value = o.hitokoto;
document.getElementById('breezemoonPostBtn').click();
}
},
onerror: function(response){
console.log("请求失败");
}
});
}
function sendMessage(s) {
unsafeWindow.ChatRoom.editor.setValue(s);
unsafeWindow.ChatRoom.send();
}
function notice(message) {
unsafeWindow.Util.notice("success", 1500, message);
}
function openRedPacket(oId) {
unsafeWindow.ChatRoom.unpackRedPacket(oId);
}
webSocketHook();
requestSend();
addMenu();
})();