// ==UserScript==
// @name Bonk.io Skin Sclee
// @namespace http://tampermonkey.net/
// @version 2.0
// @description Better Skin Editor
// @author Silly One
// @match https://*.bonk.io/*
// @match https://*.bonkisback.io/*
// @run-at document-start
// @grant none
// @license MIT
// ==/UserScript==
const injectorName = "Skin Sclee";
function injector(src) {
const style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = `
#skineditor_reset, #skineditor_undo, #skineditor_redo,
#skineditor_move, #skineditor_rotate,
#skineditor_scale, #skineditor_flipX, #skineditor_flipY,
#skineditor_invertcolors,
#skineditor_loadbutton, #skineditor_randombutton {
position: absolute;
width: 25px;
height: 25px;
line-height: 30px;
}
#skineditor_reset { top: 45px; left: 15px; }
#skineditor_undo { top: 45px; left: 45px; }
#skineditor_redo { top: 45px; left: 75px; }
#skineditor_move { top: 75px; right: 15px; }
#skineditor_rotate { top: 105px; right: 15px; }
#skineditor_inputrotate { position: absolute; top: 105px; left: -33px; width: 42px; height: 25px; }
#skineditor_scale { top: 135px; right: 15px; }
#skineditor_inputscale { position: absolute; top: 135px; left: -33px; width: 42px; height: 25px; }
#skineditor_flipX { top: 165px; right: 15px; }
#skineditor_flipY { top: 195px; right: 15px; }
#skineditor_invertcolors { top: 255px; left: 15px; }
#skineditor_loadbutton { bottom: -30px; right: 30px; width: 100px; height: 30px; }
#skineditor_inputload { position: absolute; bottom: -60px; right: 30px; width: 100px; height: 30px; }
#skineditor_randombutton { bottom: -90px; right: 30px; width: 100px; height: 30px; }
#skineditor_checkbox { bottom: -90px; right: 0px; width: 20px; height: 20px; }
`;
document.head.appendChild(style);
let newSrc = src;
const GetSkinOnEdit = /O7P\[6]\[j1y\[1]\[642]]\(t\$e\[61]\[j1y\[1]\[1014]]\[O7P\[2]]\);/;
newSrc = newSrc.replace(GetSkinOnEdit, `
O7P[6][j1y[1][642]](t$e[61][j1y[1][1014]][O7P[2]]);
t$e[61]["avatar"] = t$e[61][j1y[1][1014]][O7P[2]];
`);
const EditSkin = /u6B\(k7V\.w65\(2781\),s*N7I\[1]\)\;\};/;
newSrc = newSrc.replace(EditSkin, `
inputload.value = JSON.stringify(N7I[1]);
u6B(k7V.w65(2781), N7I[1]);
};
let skineditor_previewbox_skincontainer = document.getElementById("skineditor_previewbox_skincontainer");
let resetButton = document.createElement("div");
resetButton.id = "skineditor_reset";
resetButton.className = "brownButton brownButton_classic buttonShadow";
resetButton.textContent = "⭮";
document.getElementById("skineditor_previewbox").appendChild(resetButton);
let undoButton = document.createElement("div");
undoButton.id = "skineditor_undo";
undoButton.className = "brownButton brownButton_classic buttonShadow";
undoButton.textContent = "⤺";
document.getElementById("skineditor_previewbox").appendChild(undoButton);
let redoButton = document.createElement("div");
redoButton.id = "skineditor_redo";
redoButton.className = "brownButton brownButton_classic buttonShadow";
redoButton.textContent = "⤻";
document.getElementById("skineditor_previewbox").appendChild(redoButton);
let buttonMove = document.createElement("div");
buttonMove.id = "skineditor_move";
buttonMove.className = "brownButton brownButton_classic buttonShadow";
buttonMove.textContent = "↔";
document.getElementById("skineditor_previewbox").appendChild(buttonMove);
let buttonRotate = document.createElement("div");
buttonRotate.id = "skineditor_rotate";
buttonRotate.className = "brownButton brownButton_classic buttonShadow";
buttonRotate.textContent = "⟳";
document.getElementById("skineditor_previewbox").appendChild(buttonRotate);
let rotateInputField = document.createElement("input");
rotateInputField.id = "skineditor_inputrotate";
rotateInputField.type = "text";
rotateInputField.placeholder = "Angle";
document.getElementById("skineditor_propertiesbox").appendChild(rotateInputField);
let buttonScale = document.createElement("div");
buttonScale.id = "skineditor_scale";
buttonScale.className = "brownButton brownButton_classic buttonShadow";
buttonScale.textContent = "⤢";
document.getElementById("skineditor_previewbox").appendChild(buttonScale);
let scaleInputField = document.createElement("input");
scaleInputField.id = "skineditor_inputscale";
scaleInputField.type = "text";
scaleInputField.placeholder = "Scale";
document.getElementById("skineditor_propertiesbox").appendChild(scaleInputField);
let flipXButton = document.createElement("div");
flipXButton.id = "skineditor_flipX";
flipXButton.className = "brownButton brownButton_classic buttonShadow";
flipXButton.textContent = "⭾";
document.getElementById("skineditor_previewbox").appendChild(flipXButton);
let flipYButton = document.createElement("div");
flipYButton.id = "skineditor_flipY";
flipYButton.className = "brownButton brownButton_classic buttonShadow";
flipYButton.textContent = "⭿";
document.getElementById("skineditor_previewbox").appendChild(flipYButton);
let invertColors = document.createElement("div");
invertColors.id = "skineditor_invertcolors";
invertColors.className = "brownButton brownButton_classic buttonShadow";
invertColors.textContent = "☯";
document.getElementById("skineditor_previewbox").appendChild(invertColors);
let butload = document.createElement("div");
butload.id = "skineditor_loadbutton";
butload.className = "brownButton brownButton_classic buttonShadow";
butload.textContent = "Load";
t$e[61].setButtonSounds([butload]);
document.getElementById("skineditor_previewbox").appendChild(butload);
let inputload = document.createElement("input");
inputload.id = "skineditor_inputload";
inputload.type = "text";
document.getElementById("skineditor_previewbox").appendChild(inputload);
inputload.value = '{"layers":[],"bc":0}';
let butrandom = document.createElement("div");
butrandom.id = "skineditor_randombutton";
butrandom.className = "brownButton brownButton_classic buttonShadow";
butrandom.textContent = "Random";
t$e[61].setButtonSounds([butrandom]);
document.getElementById("skineditor_previewbox").appendChild(butrandom);
let avatarbefore;
function updateAvatar() {
let previewUpdater = new C_();
previewUpdater.completeRedraw(N7I[1]);
}
function initializeAvatar() {
let avatar = new t$e[80]();
avatar.fromObject(N7I[1]);
N7I[1] = avatar;
updateAvatar();
saveState();
}
document.getElementById('skinmanager_edit').addEventListener('click', function() {
let avatar = new t$e[80]();
avatar.fromObject(t$e[61]["allAvatars"][t$e[61]["activeAvatarNumber"]]);
inputload.value = JSON.stringify(t$e[61]["allAvatars"][t$e[61]["activeAvatarNumber"]]);
avatarbefore = avatar;
setTimeout(function() {
initializeAvatar();
}, 300);
});
let history = [];
let historyIndex = -1;
function saveState() {
history = history.slice(0, historyIndex + 1);
history.push(JSON.stringify(N7I[1].layers));
historyIndex++;
}
resetButton.onclick = function() {
N7I[1] = avatarbefore;
initializeAvatar();
};
undoButton.onclick = function() {
undo();
};
function undo() {
if (historyIndex > 0) {
historyIndex--;
N7I[1].layers = JSON.parse(history[historyIndex]);
updateAvatar();
}
}
redoButton.onclick = function() {
redo();
};
function redo() {
if (historyIndex < history.length - 1) {
historyIndex++;
N7I[1].layers = JSON.parse(history[historyIndex]);
updateAvatar();
}
}
let initialDistance, initialMousePos, initialLayerData = [];
let activeButton = null;
function debounce(func, wait) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(func, wait);
};
}
const debounceUpdate = debounce(() => S_z(), 300);
function onMouseUp() {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
activeButton = null;
debounceUpdate();
}
function onMouseMove(e) {
let layers = N7I[1].layers;
if (activeButton === 'scale') {
let containerRect = skineditor_previewbox_skincontainer.getBoundingClientRect();
let cursorDistance = Math.sqrt(Math.pow(e.clientX - (containerRect.left + containerRect.width / 2), 2) + Math.pow(e.clientY - (containerRect.top + containerRect.height / 2), 2));
let scaleChange = cursorDistance / initialDistance;
layers.forEach((layer, index) => {
layer.scale = initialLayerData[index].scale * scaleChange;
layer.x = initialLayerData[index].x * scaleChange;
layer.y = initialLayerData[index].y * scaleChange;
});
}
if (activeButton === 'move') {
let deltaX = e.clientX - initialMousePos.x;
let deltaY = e.clientY - initialMousePos.y;
layers.forEach((layer, index) => {
layer.x = initialLayerData[index].x + deltaX * 0.1;
layer.y = initialLayerData[index].y + deltaY * 0.1;
});
}
if (activeButton === 'rotate') {
let containerRect = skineditor_previewbox_skincontainer.getBoundingClientRect();
let centerX = containerRect.left + containerRect.width / 2;
let centerY = containerRect.top + containerRect.height / 2;
let angleChange = Math.atan2(e.clientY - centerY, e.clientX - centerX) * (180 / Math.PI);
layers.forEach((layer, index) => {
let initialAngle = initialLayerData[index].angle;
layer.angle = initialAngle + angleChange;
let initialX = initialLayerData[index].x;
let initialY = initialLayerData[index].y;
let radius = Math.sqrt(Math.pow(initialX, 2) + Math.pow(initialY, 2));
let initialAngleRadians = Math.atan2(initialY, initialX);
let newAngleRadians = initialAngleRadians + (angleChange * Math.PI / 180);
layer.x = radius * Math.cos(newAngleRadians);
layer.y = radius * Math.sin(newAngleRadians);
});
}
updateAvatar();
}
buttonMove.addEventListener('mousedown', (e) => {
activeButton = 'move';
initialMousePos = { x: e.clientX, y: e.clientY };
initialLayerData = N7I[1].layers.map(layer => ({
x: layer.x,
y: layer.y,
scale: layer.scale,
angle: layer.angle
}));
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
saveState();
});
buttonRotate.onclick = function() {
let rotateAngle = parseFloat(rotateInputField.value) || 22.5;
let layers = N7I[1].layers;
let containerRect = skineditor_previewbox_skincontainer.getBoundingClientRect();
let centerX = containerRect.left + containerRect.width / 2;
let centerY = containerRect.top + containerRect.height / 2;
layers.forEach((layer, index) => {
layer.angle += rotateAngle;
let initialX = layer.x;
let initialY = layer.y;
let radius = Math.sqrt(Math.pow(initialX, 2) + Math.pow(initialY, 2));
let initialAngleRadians = Math.atan2(initialY, initialX);
let newAngleRadians = initialAngleRadians + (rotateAngle * Math.PI / 180);
layer.x = radius * Math.cos(newAngleRadians);
layer.y = radius * Math.sin(newAngleRadians);
});
updateAvatar();
saveState();
};
buttonRotate.addEventListener('mousedown', (e) => {
activeButton = 'rotate';
initialMousePos = { x: e.clientX, y: e.clientY };
initialLayerData = N7I[1].layers.map(layer => ({
x: layer.x,
y: layer.y,
scale: layer.scale,
angle: layer.angle
}));
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
saveState();
});
buttonScale.onclick = function() {
let scaleInputValue = parseFloat(scaleInputField.value);
let scaleFactor = parseFloat(scaleInputField.value) || 2;
let layers = N7I[1].layers;
layers.forEach((layer, index) => {
layer.scale *= scaleFactor;
layer.x *= scaleFactor;
layer.y *= scaleFactor;
});
updateAvatar();
saveState();
};
buttonScale.addEventListener('mousedown', (e) => {
activeButton = 'scale';
let containerRect = skineditor_previewbox_skincontainer.getBoundingClientRect();
initialDistance = Math.sqrt(Math.pow(e.clientX - (containerRect.left + containerRect.width / 2), 2) + Math.pow(e.clientY - (containerRect.top + containerRect.height / 2), 2));
initialMousePos = { x: e.clientX, y: e.clientY };
initialLayerData = N7I[1].layers.map(layer => ({
x: layer.x,
y: layer.y,
scale: layer.scale,
angle: layer.angle
}));
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
saveState();
});
flipXButton.onclick = function() {
N7I[1].layers.forEach(layer => {
layer.flipX = !layer.flipX;
layer.x = -layer.x;
layer.angle = -layer.angle;
});
updateAvatar();
saveState();
};
flipYButton.onclick = function() {
N7I[1].layers.forEach(layer => {
layer.flipY = !layer.flipY;
layer.y = -layer.y;
layer.angle = -layer.angle;
});
updateAvatar();
saveState();
};
function invertColor(color) {
return 0xFFFFFF - color;
}
invertColors.onclick = function() {
let layers = N7I[1].layers;
layers.forEach(layer => {
layer.color = invertColor(layer.color);
});
N7I[1].bc = invertColor(N7I[1].bc);
updateAvatar();
S_z()
};
butload.onclick = function() {
let parsedData = JSON.parse(inputload.value);
let avatar = new t$e[80]();
avatar.fromObject(parsedData);
N7I[1] = avatar;
console.log("N7I[1] after load:", N7I[1]);
updateAvatar();
S_z()
};
inputload.onchange = function() {
try {
let parsedData = JSON.parse(inputload.value);
let avatar = new t$e[80]();
avatar.fromObject(parsedData);
N7I[1] = avatar;
inputload.value = JSON.stringify(N7I[1]);
console.log("Avatar updated from input:", N7I[1]);
} catch (error) {
console.error("Invalid JSON in input field:", error);
}
};
inputload.onkeydown = function(event) {
if (event.key === 'Enter' && inputload.value.trim() === '') {
inputload.value = '{"layers":[],"bc":0}';
}
};
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getRandomFloat(min, max) {
return Math.random() * (max - min) + min;
}
function getRandomBool() {
return Math.random() < 0.5;
}
function getRandomLayer() {
return {
id: getRandomInt(1, 115), // 1, 115
scale: getRandomFloat(0, 2),
angle: getRandomFloat(0, 360),
x: getRandomFloat(-25, 25),
y: getRandomFloat(-25, 25),
flipX: getRandomBool(),
flipY: getRandomBool(),
color: getRandomInt(0, 16777215) // 0, 16777215
};
}
function generateRandomAvatar() {
let layers = [];
let numLayers = getRandomInt(16, 16);
for (let i = 0; i < numLayers; i++) {
layers.push(getRandomLayer());
}
return { layers: layers, bc: getRandomInt(0, 16777215) };
}
let autoAvatarCheckbox = document.createElement("input");
autoAvatarCheckbox.type = "checkbox";
autoAvatarCheckbox.id = "skineditor_checkbox";
document.getElementById("skineditor_previewbox").appendChild(autoAvatarCheckbox);
function setRandomAvatar() {
let randomAvatar = generateRandomAvatar();
let avatar = new t$e[80]();
avatar.fromObject(randomAvatar);
t$e[61].avatar = avatar;
console.log("New random avatar set:", randomAvatar);
initializeAvatar();
}
let avatarInterval;
autoAvatarCheckbox.onchange = function() {
if (autoAvatarCheckbox.checked) {
console.log("Auto avatar change is enabled.");
avatarInterval = setInterval(setRandomAvatar, 2000);
} else {
console.log("Auto avatar change is disabled.");
clearInterval(avatarInterval);
}
};
butrandom.onclick = function() {
let randomAvatar = generateRandomAvatar();
inputload.value = JSON.stringify(randomAvatar);
let parsedData = JSON.parse(inputload.value);
let avatar = new t$e[80]();
avatar.fromObject(parsedData);
console.log("Random avatar generated:", randomAvatar);
N7I[1] = avatar;
updateAvatar();
};
`);
if (src === newSrc) throw "Injection failed!";
console.log(injectorName + " injector run");
return newSrc;
}
if (!window.bonkCodeInjectors) window.bonkCodeInjectors = [];
window.bonkCodeInjectors.push(bonkCode => {
try {
return injector(bonkCode);
} catch (error) {
alert(`Whoops! ${injectorName} was unable to load.`);
throw error;
}
});
console.log(injectorName + " injector loaded");