Greasy Fork is available in English.
A mod that handles monke bot's chats with a cool typing animation.
当前为
// ==UserScript==
// @name Monkey Chat Handler (Typing Style)
// @namespace http://tampermonkey.net/
// @version 3.0
// @license MIT
// @description A mod that handles monke bot's chats with a cool typing animation.
// @author You & AI Assistant
// @match https://bonk.io/gameframe-release.html
// @icon https://www.google.com/s2/favicons?sz=64&domain=bonk.io
// @grant GM_addStyle
// ==/UserScript==
GM_addStyle(`
.cool-chat-message {
border-left: 3px solid #4CAF50;
padding: 5px 8px;
margin: 4px 0;
word-wrap: break-word;
}
.cool-chat-message a {
color: #87CEEB;
text-decoration: none;
font-weight: bold;
transition: color 0.2s ease, text-decoration 0.2s ease;
}
.cool-chat-message a:hover {
color: #98FB98;
text-decoration: underline;
}
`);
let autoCanv = function() {
Object.defineProperty(this, 'chatBox1', {
get: function() { return document.getElementById('newbonklobby_chat_content'); }
});
Object.defineProperty(this, 'chatBox2', {
get: function() { return document.getElementById('ingamechatcontent'); }
});
};
let canv = new autoCanv();
function linkify(text) {
const urlRegex = /(https?:\/\/[^\s]+)/g;
return text.replace(urlRegex, url => `<a href="${url}" target="_blank" rel="noopener noreferrer">${url}</a>`);
}
async function displayInChat(msg, color = '#228B22', inner = true, size) {
const TYPING_SPEED_MS = 30;
const chatBox1 = canv.chatBox1;
const chatBox2 = canv.chatBox2;
if (!chatBox1 && !chatBox2) {
console.error("No chatbox elements found!");
return;
}
const scrollToBottom = () => {
if (chatBox1) chatBox1.scrollTop = chatBox1.scrollHeight;
if (chatBox2) chatBox2.scrollTop = chatBox2.scrollHeight;
};
const finalHtml = inner ? linkify(msg) : linkify(msg.replace(/</g, "<").replace(/>/g, ">"));
const tempDiv = document.createElement('div');
tempDiv.innerHTML = finalHtml;
const plainText = tempDiv.textContent || "";
const createMessageElements = () => {
const messageContainer = document.createElement('div');
messageContainer.className = 'cool-chat-message';
const typingSpan = document.createElement('span');
typingSpan.style.color = color;
if (size) {
typingSpan.style.fontSize = size + 'px';
}
messageContainer.appendChild(typingSpan);
return { messageContainer, typingSpan };
};
const elements1 = chatBox1 ? createMessageElements() : null;
const elements2 = chatBox2 ? createMessageElements() : null;
if (elements1) chatBox1.appendChild(elements1.messageContainer);
if (elements2) chatBox2.appendChild(elements2.messageContainer);
scrollToBottom();
for (let i = 0; i < plainText.length; i++) {
const char = plainText[i];
if (elements1) elements1.typingSpan.textContent += char;
if (elements2) elements2.typingSpan.textContent += char;
scrollToBottom();
await new Promise(resolve => setTimeout(resolve, TYPING_SPEED_MS));
}
if (elements1) elements1.typingSpan.innerHTML = finalHtml;
if (elements2) elements2.typingSpan.innerHTML = finalHtml;
}
let autoName = function() {
Object.defineProperty(this, 'name', {
get: function() {
return document.getElementById("pretty_top_name")?.textContent;
}
});
};
let name = new autoName();
let monkTypes = {
handleJoining: {
run: function(data) {
if (data[0].to == name.name) {
pack(`4,{"initiator":"monke","type":"returnMessage","confirmed":"yes","from":"${name.name}"}`);
}
},
variables: ['data'],
},
chatMessage: {
run: function(data) {
if (data[0].to == name.name) {
const message = data[0].message;
displayInChat(message);
}
},
variables: ['data'],
},
};
let monkVariableTypes = {
data: {
description: 'returns the data from the monk command',
returned: function(data) {
return data;
}
}
};
function handleMonk(data) {
let runner = monkTypes[data.type];
if (!runner) return;
runner.run(runner.variables.map(variable => monkVariableTypes[variable].returned(data)));
}
let oldsend = WebSocket.prototype.send;
let code = function(xx) {
if (xx == "5") {
window.bonkws = this;
let old_onmsg = this.onmessage;
this.onmessage = function(yy) {
if (yy.data.startsWith("42[")) {
try {
let data = JSON.parse(yy.data.slice(2));
if (data[0] == 7 && data[2].initiator == 'monke') {
handleMonk(data[2]);
}
} catch (e) {}
}
return old_onmsg.call(this, yy);
};
}
return oldsend.call(this, xx);
};
function fixOverwriteBitch() {
WebSocket.prototype.send = code;
}
fixOverwriteBitch();
async function pack(input) {
if (window.bonkws && window.bonkws.readyState === 1) {
await window.bonkws.send("42[" + input + "]");
} else {
console.error("Bonk WebSocket not ready to send message.");
}
}