Rie's Mod

Simple mod made by khayrie

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         Rie's Mod
// @version      5.2
// @description  Simple mod made by khayrie
// @author       khayrie
// @match        https://bonk.io/*
// @match        https://bonkisback.io/*
// @match        https://multiplayer.gg/physics/*
// @grant        unsafeWindow
// @run-at       document-idle
// @namespace https://github.com/khayrie
// ==/UserScript==
(function() {
'use strict';
let CUSTOM_NAME = "khayrie's little slave";
let isNameActive = true;
let gameReady = false;
let mutationObserver = null;
const nicknames = {};
const customLevels = {};
const remoteCustomizations = {};
const uw = unsafeWindow;
const NAME_SELECTORS = [
'#pretty_top_name', '.newbonklobby_playerentry_name', '.ingamescoreboard_playername',
'.ingamechatname', '.newbonklobby_chat_msg_name', '#ingamewinner_top', '.replay_playername'
];
const LEVEL_SELECTORS = [
'#pretty_top_level', '.newbonklobby_playerentry_level', '.ingamescoreboard_playerlevel'
];
const UPDATE_INTERVAL = 200;
const PRESETS = {
rainbow: { colors: ['#FF0000', '#FFA500', '#FFFF00', '#00FF00', '#0000FF', '#4B0082', '#8B00FF'], speed: 100 },
fire: { colors: ['#FF4500', '#FF8C00', '#FFD700'], speed: 150 },
ocean: { colors: ['#1E90FF', '#87CEEB', '#00BFFF'], speed: 200 },
sunset: { colors: ['#FF4500', '#FFA500', '#FFD700', '#FF69B4'], speed: 120 },
neon: { colors: ['#00FF00', '#00FFFF', '#FF00FF', '#FF0000'], speed: 80 },
lavender: { colors: ['#9370DB', '#BA55D3', '#DA70D6', '#EE82EE'], speed: 180 }
};
let lastUpdate = 0;

function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

function parseQuotedArgs(input) {
const tokens = [];
let current = '';
let inQuote = false;
let escapeNext = false;
for (let i = 0; i < input.length; i++) {
const char = input[i];
if (escapeNext) { current += char; escapeNext = false; continue; }
if (char === '\\') { escapeNext = true; continue; }
if (char === '"' && (i === 0 || input[i-1] !== '\\')) { inQuote = !inQuote; continue; }
if (char === ' ' && !inQuote) { if (current !== '') { tokens.push(current); current = ''; } continue; }
current += char;
}
if (current !== '') tokens.push(current);
return tokens;
}

function waitForGame(callback, retries = 0) {
if (retries > 50) return;
const frame = document.getElementById('maingameframe');
if (!frame || !frame.contentWindow) { setTimeout(() => waitForGame(callback, retries + 1), 200); return; }
const gameWin = frame.contentWindow;
const gameDoc = frame.contentDocument;
if (!gameWin.PIXI || typeof uw.playerids === 'undefined' || typeof uw.myid === 'undefined' || !gameDoc.body) {
setTimeout(() => waitForGame(callback, retries + 1), 200);
return;
}
gameReady = true;
callback(gameWin, gameDoc);
}

function hookPIXIText(gameWin) {
if (!gameWin?.PIXI?.Text?.prototype) return;
const originalUpdate = gameWin.PIXI.Text.prototype.updateText;
gameWin.PIXI.Text.prototype.updateText = function() {
try {
if (typeof this.text !== 'string') return originalUpdate.call(this);
const playerIds = uw.playerids || {};
const myId = uw.myid;
for (const id in playerIds) {
const player = playerIds[id];
if (!player || !player.userName) continue;
let displayName = player.userName;
if (nicknames[id]) { displayName = nicknames[id]; }
else if (id == myId && isNameActive) { displayName = CUSTOM_NAME; }
else if (remoteCustomizations[id]?.name && id != myId) { displayName = remoteCustomizations[id].name; }
if (displayName === player.userName) continue;
const safeName = escapeRegExp(player.userName);
if (new RegExp(safeName, 'i').test(this.text)) {
this.text = this.text.replace(new RegExp(safeName, 'ig'), displayName);
}
}
} catch (e) {}
return originalUpdate.call(this);
};
}

function forceInstantUpdate(doc) {
if (!doc) doc = uw.Gdocument;
if (!doc || !gameReady) return;
try {
const targets = NAME_SELECTORS.concat(LEVEL_SELECTORS);
for (let i = 0; i < targets.length; i++) {
const selector = targets[i];
const elements = doc.querySelectorAll(selector);
for (let j = 0; j < elements.length; j++) {
const el = elements[j];
if (el.style) {
el.style.transform = '';
el.style.animation = '';
el.style.textShadow = '';
el.style.textAlign = '';
el.style.position = '';
el.style.top = '';
el.style.backgroundImage = '';
el.style.backgroundClip = '';
el.style.webkitBackgroundClip = '';
el.style.color = '';
}
}
}
updateAllDOM(doc);
} catch (e) {}
}

function getDisplayName(playerId) {
if (playerId == uw.myid && isNameActive) return CUSTOM_NAME;
if (nicknames[playerId]) return nicknames[playerId];
if (remoteCustomizations[playerId]?.name && playerId != uw.myid) return remoteCustomizations[playerId].name;
return uw.playerids?.[playerId]?.userName || "Guest";
}

function updateAllDOM(doc) {
if (!doc || !gameReady || !uw.playerids) return;
const now = Date.now();
if (now - lastUpdate < UPDATE_INTERVAL) return;
lastUpdate = now;
try {
const playerIds = uw.playerids;
const myId = uw.myid;
const nameElements = [];
const levelElements = [];
for (let i = 0; i < NAME_SELECTORS.length; i++) {
const els = doc.querySelectorAll(NAME_SELECTORS[i]);
for (let j = 0; j < els.length; j++) {
nameElements.push(els[j]);
}
}
for (let i = 0; i < LEVEL_SELECTORS.length; i++) {
const els = doc.querySelectorAll(LEVEL_SELECTORS[i]);
for (let j = 0; j < els.length; j++) {
levelElements.push(els[j]);
}
}
for (let i = 0; i < nameElements.length; i++) {
const el = nameElements[i];
for (const id in playerIds) {
const player = playerIds[id];
if (!player || !player.userName) continue;
const safeName = escapeRegExp(player.userName);
let displayValue = player.userName;
if (nicknames[id]) { displayValue = nicknames[id]; }
else if (id == myId && isNameActive) { displayValue = CUSTOM_NAME; }
else if (remoteCustomizations[id]?.name && id != myId) { displayValue = remoteCustomizations[id].name; }
if (el.textContent && new RegExp(safeName, 'i').test(el.textContent)) {
el.textContent = el.textContent.replace(new RegExp(safeName, 'ig'), displayValue);
}
}
}
for (let i = 0; i < levelElements.length; i++) {
const el = levelElements[i];
const playerId = getPlayerIdFromLevelElement(el, doc);
if (playerId && customLevels[playerId]) { el.textContent = customLevels[playerId]; }
else if (playerId == myId && customLevels[myId]) { el.textContent = customLevels[myId]; }
else if (playerId && remoteCustomizations[playerId]?.level && playerId != myId) { el.textContent = remoteCustomizations[playerId].level; }
}
} catch (e) {}
}

function getPlayerIdFromLevelElement(el, doc) {
if (!el || !uw.playerids) return null;
let parent = el.parentElement;
let nameElement = null;
while (parent && !nameElement) {
try {
nameElement = parent.querySelector('.newbonklobby_playerentry_name, .ingamescoreboard_playername, .ingamechatname');
} catch (e) {}
if (nameElement) break;
parent = parent.parentElement;
}
if (!nameElement || !nameElement.textContent) return null;
const nameText = nameElement.textContent.trim();
const playerIds = uw.playerids;
for (const id in playerIds) {
const player = playerIds[id];
if (!player || !player.userName) continue;
let displayName = player.userName;
if (nicknames[id]) { displayName = nicknames[id]; }
else if (id == uw.myid && isNameActive) { displayName = CUSTOM_NAME; }
else if (remoteCustomizations[id]?.name && id != uw.myid) { displayName = remoteCustomizations[id].name; }
if (displayName === nameText) { return id; }
}
return null;
}

function broadcastCustomization() {
if (!uw.sendToServer || !gameReady) return;
try {
uw.sendToServer(JSON.stringify({
type: "bonk_customizer",
senderId: uw.myid,
name: CUSTOM_NAME,
level: customLevels[uw.myid] || "Level 1"
}));
} catch (e) {}
}

function broadcastNickname(playerId, nickname) {
if (!uw.sendToServer || !playerId || !gameReady) return;
try {
uw.sendToServer(JSON.stringify({
type: "bonk_nick",
senderId: uw.myid,
targetId: playerId,
nickname: nickname
}));
} catch (e) {}
}

function broadcastLevel(playerId, levelStr) {
if (!uw.sendToServer || !playerId || !gameReady) return;
try {
uw.sendToServer(JSON.stringify({
type: "bonk_level",
senderId: uw.myid,
targetId: playerId,
level: levelStr
}));
} catch (e) {}
}

function sendPrivateMessage(targetId, message) {
if (!uw.sendToServer || !gameReady) return;
try {
uw.sendToServer(JSON.stringify({
type: "bonk_pm",
senderId: uw.myid,
targetId: targetId,
senderName: getDisplayName(uw.myid),
content: message
}));
} catch (e) {}
}

function handleCustomMessage(data) {
try {
const msg = JSON.parse(data);
if (!msg.senderId) return;
switch(msg.type) {
case "bonk_customizer":
remoteCustomizations[msg.senderId] = {
name: msg.name,
level: msg.level
};
forceInstantUpdate(uw.Gdocument);
break;
case "bonk_nick":
if (msg.targetId) {
if (msg.nickname === "" || msg.nickname === null) { delete nicknames[msg.targetId]; }
else { nicknames[msg.targetId] = msg.nickname; }
forceInstantUpdate(uw.Gdocument);
}
break;
case "bonk_level":
if (msg.targetId && msg.level) {
customLevels[msg.targetId] = msg.level;
forceInstantUpdate(uw.Gdocument);
}
break;
case "bonk_pm":
if (msg.targetId === uw.myid && msg.senderName && msg.content) {
const displayMsg = `[PM from ${msg.senderName}] ${msg.content}`;
if (uw.displayInChat) uw.displayInChat(displayMsg, "#00FF00", "#00AA00");
}
break;
case "bonk_clearnicks":
Object.keys(nicknames).forEach(id => { broadcastNickname(id, ""); });
Object.keys(nicknames).forEach(id => delete nicknames[id]);
forceInstantUpdate(uw.Gdocument);
break;
case "bonk_clearlevel":
if (msg.targetId) {
delete customLevels[msg.targetId];
forceInstantUpdate(uw.Gdocument);
}
break;
}
} catch (e) {}
}

function findPlayerIdByName(namePart) {
if (!namePart || !uw.playerids) return null;
const cleanPart = namePart.toLowerCase().replace(/^"|"$/g, '').trim();
const playerIds = uw.playerids;
for (const id in playerIds) {
const player = playerIds[id];
if (player && player.userName && player.userName.toLowerCase().includes(cleanPart)) { return id; }
}
return null;
}

function showHelp() {
const helpLines = [
"╔════════════════════════════════════════════════╗",
"║   Rie's Mod v5.0 - Command List                ║",
"╠════════════════════════════════════════════════╣",
"║ /name <text>          Change your name         ║",
"║                       (supports ASCII art!)    ║",
"║ /nick <player> <name> Nickname a player        ║",
"║                       (supports ASCII art!)    ║",
"║ /level <player> <num> Set player's level       ║",
"║ /whois <player>       Show real username       ║",
"║ /m <player> <msg>     Private message          ║",
"║ /clearnick            Clear all nicknames      ║",
"║ /info                 Show this help           ║",
"╚════════════════════════════════════════════════╝"
];
const display = uw.displayInChat;
if (!display) return;
for (let i = 0; i < helpLines.length; i++) {
display(helpLines[i], "#FFD700", "#FFA500");
}
}

function cleanupRoom() {
if (mutationObserver) {
try { mutationObserver.disconnect(); } catch (e) {}
mutationObserver = null;
}
gameReady = false;
lastUpdate = 0;
Object.keys(remoteCustomizations).forEach(id => delete remoteCustomizations[id]);
}

function addCommands() {
if (typeof uw.commandhandle !== 'function') { setTimeout(addCommands, 500); return; }
const originalCommandHandle = uw.commandhandle;
uw.commandhandle = function(chat_val) {
if (!gameReady) return originalCommandHandle(chat_val);
const display = uw.displayInChat;
if (chat_val.startsWith('/whois ')) {
const playerName = chat_val.substring(7).trim();
const playerId = findPlayerIdByName(playerName);
if (!playerId) { if (display) display(`Player "${playerName}" not found.`, "#FF0000", "#FF0000"); return ""; }
const realName = uw.playerids?.[playerId]?.userName || "Unknown";
const nick = nicknames[playerId] || "None";
if (display) display(`🔍 ${playerName}: Real = "${realName}", Nick = "${nick}"`, "#00FF00", "#00AA00"); return "";
}
if (chat_val.startsWith('/level ')) {
const rest = chat_val.substring(7).trim();
const args = parseQuotedArgs(rest);
if (args.length < 2) { if (display) display("Usage: /level <player> <number>", "#FF0000", "#FF0000"); return ""; }
const playerName = args[0];
const levelNum = parseInt(args[1]);
const playerId = findPlayerIdByName(playerName);
if (!playerId) { if (display) display(`Player "${playerName}" not found.`, "#FF0000", "#FF0000"); return ""; }
if (isNaN(levelNum) || levelNum < 0 || levelNum > 9999) { if (display) display("Level must be 0-9999.", "#FF0000", "#FF0000"); return ""; }
const levelStr = `Level ${levelNum}`;
customLevels[playerId] = levelStr; broadcastLevel(playerId, levelStr); forceInstantUpdate(uw.Gdocument);
const targetName = uw.playerids?.[playerId]?.userName || "Player";
if (display) display(`📊 Set ${targetName}'s level to: ${levelStr}`, "#00FF00", "#00AA00"); return "";
}
if (chat_val === '/clearnick') {
Object.keys(nicknames).forEach(id => { broadcastNickname(id, ""); });
Object.keys(nicknames).forEach(id => delete nicknames[id]);
if (uw.sendToServer) { try { uw.sendToServer(JSON.stringify({ type: "bonk_clearnicks", senderId: uw.myid })); } catch (e) {} }
forceInstantUpdate(uw.Gdocument);
if (display) display("🏷️ All nicknames cleared", "#FFD700", "#FFA500"); return "";
}
if (chat_val.startsWith('/nick ')) {
const rest = chat_val.substring(6).trim();
const args = parseQuotedArgs(rest);
if (args.length < 2) { if (display) display('Usage: /nick <player> <nickname>', "#FF0000", "#FF0000"); return ""; }
const playerName = args[0];
const nickname = args.slice(1).join(" ");
const playerId = findPlayerIdByName(playerName);
if (!playerId) { if (display) display(`Player "${playerName}" not found.`, "#FF0000", "#FF0000"); return ""; }
if (nickname.trim().length === 0) { if (display) display("Nickname cannot be empty.", "#FF0000", "#FF0000"); return ""; }
nicknames[playerId] = nickname; broadcastNickname(playerId, nickname); forceInstantUpdate(uw.Gdocument);
if (display) display(`🏷️ Nickname applied`, "#00FF00", "#00AA00"); return "";
}
if (chat_val.startsWith('/m ')) {
const rest = chat_val.substring(3).trim();
const args = parseQuotedArgs(rest);
if (args.length < 2) { if (display) display('Usage: /m <player> <message>', "#FF0000", "#FF0000"); return ""; }
const playerName = args[0];
const message = args.slice(1).join(" ");
const playerId = findPlayerIdByName(playerName);
if (!playerId) { if (display) display(`Player "${playerName}" not found.`, "#FF0000", "#FF0000"); return ""; }
sendPrivateMessage(playerId, message);
if (display) display(`💬 [PM to ${getDisplayName(playerId)}] ${message}`, "#00FF00", "#00AA00"); return "";
}
if (chat_val.startsWith('/name ')) {
const newName = chat_val.substring(6);
if (newName.trim().length > 0) {
CUSTOM_NAME = newName; isNameActive = true; broadcastCustomization(); forceInstantUpdate(uw.Gdocument);
if (display) display(`🏷️ Name applied`, "#00FF00", "#00AA00");
} else { if (display) display("Name cannot be empty.", "#FF0000", "#FF0000"); }
return "";
} else if (chat_val === '/name') {
isNameActive = !isNameActive; broadcastCustomization(); forceInstantUpdate(uw.Gdocument);
if (display) display(isNameActive ? "✅ Custom name enabled" : "✅ Custom name disabled", "#FFD700", "#FFA500"); return "";
}
if (chat_val === '/info') { showHelp(); return ""; }
return originalCommandHandle(chat_val);
};
}

function init() {
cleanupRoom();
waitForGame((gameWin, gameDoc) => {
if (!gameDoc.body) return;
if (typeof uw.handleCustomMessageOriginal === 'undefined') {
uw.handleCustomMessageOriginal = uw.handleCustomMessage || (() => {});
uw.handleCustomMessage = function(data) {
handleCustomMessage(data);
uw.handleCustomMessageOriginal(data);
};
}
hookPIXIText(gameWin);
addCommands();
broadcastCustomization();
setInterval(() => { if (gameReady) updateAllDOM(gameDoc); }, UPDATE_INTERVAL);
mutationObserver = new MutationObserver(() => { if (gameReady) updateAllDOM(gameDoc); });
try { mutationObserver.observe(gameDoc.body, { childList: true, subtree: true, characterData: true }); } catch (e) {}
let lastRoomId = uw.roomid;
setInterval(() => {
if (uw.roomid && uw.roomid !== lastRoomId) {
lastRoomId = uw.roomid;
cleanupRoom();
setTimeout(() => init(), 1000);
}
}, 1000);
});
}

const originalCreateOrJoinRoom = uw.createOrJoinRoom;
uw.createOrJoinRoom = function(...args) {
cleanupRoom();
return originalCreateOrJoinRoom.apply(this, args);
};

if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); }
else { init(); }
})();