// ==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 // @downloadURL none // ==/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 += `
Data was downloaded as SFData_${timestamp}.txt
If you have any data please send the SFData file here: https://discord.gg/v6NE6wcccb
`; }; 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; } `}));