Greasy Fork is available in English.
Adds antispam to bonk.io chat.
当前为
// ==UserScript==
// @name Bonk.io Spam Filter
// @namespace http://tampermonkey.net/
// @version 1.69
// @description Adds antispam to bonk.io chat.
// @author Silly One
// @match https://*.bonk.io/*
// @match https://*.bonkisback.io/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const fixData = {}, chatLog = [], replacedChatLog = [];
const antispam = text => text.replace(/(.)\1{3,}/g, (m, p1) => p1 + '[' + m.length + 'x] ')
.replace(/((?:\b\w+\b\W?)+)\s?(?:\1\s?){2,}/g, (m, p1) => p1 + '[' + (m.match(new RegExp(p1, 'g')) || []).length + 'x] ');
const invertColor = hex => '#' + [255, 255, 255].map((v, i) => (v - parseInt(hex.slice(1 + i * 2, 3 + i * 2), 16)).toString(16).padStart(2, '0')).join('');
const downloadData = () => {
const timestamp = new Date().toISOString().slice(0, 19).replace(/[-:T]/g, '');
const blob = new Blob([JSON.stringify({ fix: fixData, chat: chatLog, replacedChat: replacedChatLog }, null, 2)], { type: 'text/plain' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = `SFData_${timestamp}.txt`;
a.click();
URL.revokeObjectURL(a.href);
const chatContent = document.getElementById('newbonklobby_chat_content');
chatContent.innerHTML += `<div>Data was downloaded as SFData_${timestamp}.txt</div><div>If you have any data please send the SFData file here: https://discord.gg/v6NE6wcccb</div>`;
};
const addFeedbackButtons = msg => {
const buttons = ['[Help]', '[Fix]', '[Get]'].map((text, i) => {
const btn = document.createElement('span');
btn.innerHTML = text;
btn.className = 'feedback-button hidden';
btn.onclick = [
() => msg.parentNode.appendChild(document.createElement('div')).innerHTML = 'Fix is used to specify what needs to be fixed. Get is downloading the data to your device and gives a link to a server where you can send the data.',
() => fixData[msg.innerText] = (fixData[msg.innerText] || 0) + 1,
() => { downloadData(); buttons.forEach(btn => btn.classList.add('hidden')); }
][i];
return btn;
});
buttons.forEach(btn => msg.parentNode.insertBefore(btn, msg.nextSibling));
msg.parentNode.addEventListener('mouseover', () => buttons.forEach(btn => btn.classList.remove('hidden')));
msg.parentNode.addEventListener('mouseout', () => buttons.forEach(btn => btn.classList.add('hidden')));
};
const processMessages = mutationsList => {
mutationsList.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.classList && node.classList.contains('newbonklobby_chat_msg_txt')) {
chatLog.push(node.innerHTML);
const replacedText = antispam(node.innerHTML);
replacedChatLog.push(replacedText);
node.innerHTML = replacedText;
node.style.color = invertColor(window.getComputedStyle(node.parentNode).backgroundColor);
addFeedbackButtons(node);
}
});
});
};
new MutationObserver(processMessages).observe(document.body, { childList: true, subtree: true });
document.querySelectorAll('.newbonklobby_chat_msg_txt').forEach(msg => {
chatLog.push(msg.innerHTML);
const replacedText = antispam(msg.innerHTML);
replacedChatLog.push(replacedText);
msg.innerHTML = replacedText;
msg.style.color = invertColor(window.getComputedStyle(msg.parentNode).backgroundColor);
addFeedbackButtons(msg);
});
})();
document.head.appendChild(Object.assign(document.createElement('style'), {
innerHTML: `
.hidden { display: none; }
.feedback-button { color: blue; cursor: pointer; text-decoration: underline; margin-left: 5px; opacity: 0.9; }
`}));