// ==UserScript==
// @name Agar.io---Chat, Minimap, Bar Remover, Custom Skins, Skin Maker (Drag&Drop + Layout) [Updated]
// @namespace All in one mod, doesnt add cheats.
// @version 1.0
// @description Removes #agar-io_970x90, improves drag & drop styling, places Turn Skin On/Off under the skin URL.
// @author 𝓝𝑒ⓦ 𝓙ⓐ¢𝓀🕹️
// @match https://agar.io/*
// @grant none
// @run-at document-idle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
document.documentElement.removeAttribute('style');
//------------------------------------------------------------------
// 0) REMOVE #agar-io_970x90 DIV
//------------------------------------------------------------------
const adDiv = document.querySelector('#agar-io_970x90');
if (adDiv) {
adDiv.remove();
}
//------------------------------------------------------------------
// AUDIO: Default OFF
//------------------------------------------------------------------
let musicOn = false;
const messageSound = new Audio('https://jimboy3100.github.io/notification_01.mp3');
const openSound = new Audio('https://jimboy3100.github.io/sounds/notification-open.mp3');
//------------------------------------------------------------------
// GLOBAL STYLES
//------------------------------------------------------------------
const style = document.createElement('style');
style.textContent = `
/* --- COMMON BUTTON / CONTAINER STYLES --- */
.styled-button, .toggle-button, .send-button, .resize-handle, .info-box, .status-indicator {
background-color: #54c800;
color: white;
padding: 8px 16px;
border: none;
cursor: pointer;
border-radius: 4px;
}
.styled-button:hover,
.toggle-button:hover,
.send-button:hover,
.info-box:hover {
background-color: #3d8b00;
}
.styled-button:active,
.toggle-button:active,
.send-button:active {
background-color: #296600;
}
/* --- CHAT DRAGGABLE BOX --- */
.draggable {
position: fixed;
bottom: 0;
left: 0;
width: 25%;
height: 400px;
background-color: rgba(0,0,0,.2);
display: flex;
flex-direction: column;
overflow: hidden;
cursor: move;
z-index: 9999;
}
/* --- RESIZE HANDLE --- */
.resize-handle {
position: absolute;
bottom: 0;
right: 0;
width: 10px;
height: 10px;
background-color: #ccc;
cursor: nwse-resize;
}
/* --- CLOSE BUTTON & STATUS --- */
.close-button, .status-indicator {
position: absolute;
right: 0;
padding: 2px 5px;
cursor: pointer;
color: white;
}
.close-button {
top: 0;
background-color: red;
}
.status-indicator {
bottom: 0;
left: 1px;
width: 25%;
text-align: center;
}
/* --- MESSAGES --- */
#messageContainer {
display: flex;
flex-wrap: wrap;
background: rgba(0,0,0,.3);
padding: 8px;
}
#messageArea {
flex-grow: 1;
overflow: auto;
margin: 5px;
padding: 5px;
background: rgba(0,0,0,.1);
color: white;
}
.chat-message {
padding: 5px;
border-bottom: 1px solid #ccc;
display: flex;
align-items: center;
}
/* --- INPUTS --- */
#avatarInputContainer {
width: 100%;
margin-bottom: 5px;
padding: 5px;
}
#avatarInputContainer label {
color: white;
background: transparent;
font-size: 14px;
}
#avatarInput {
color: white;
width: 80%;
background: rgba(255,255,255,0.1);
margin-left: 4px;
border: 1px solid #666;
border-radius: 3px;
}
#inputArea {
width: 75%;
flex-grow: 1;
padding: 8px;
border-radius: 4px;
background: rgba(0,0,0,.1);
color: white;
margin-right: 5px;
}
/* --- TOAST --- */
.toast {
position: fixed;
bottom: 10%;
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: white;
padding: 10px;
border-radius: 5px;
text-align: center;
z-index: 1000;
display: none;
}
/* --- TOASTER (FOR COPY IP, ETC.) --- */
.toaster {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1001;
left: 50%;
bottom: 30px;
font-size: 17px;
transition: visibility 0.5s, opacity 0.5s ease-out;
}
.toaster.show {
visibility: visible;
opacity: 1;
}
/* --- FUN STUFF POPUP --- */
#funStuffPopup {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
height: 80%;
background-color: white;
border: 2px solid #54c800;
z-index: 10000;
resize: both;
overflow: auto;
}
#funStuffPopup iframe {
width: 100%;
height: 100%;
}
#funStuffPopupClose {
position: absolute;
top: 10px;
right: 10px;
background-color: red;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
/* --- NEW RIGHT PANEL FOR BIG BOXES & TOGGLES --- */
#rightPanel {
position: fixed;
top: 80px;
right: 10px;
width: 200px;
background: rgba(0,0,0,0.2);
border: 1px solid #54c800;
border-radius: 4px;
padding: 10px;
z-index: 9999;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 8px;
}
#rightPanel button {
margin: 0;
width: 100%;
}
#gameIPBox {
background-color: #0077ff;
text-align: center;
cursor: pointer;
padding: 8px 0;
border-radius: 4px;
color: white;
font-weight: bold;
}
/* --- DRAG & DROP AREA FOR IMAGE UPLOAD (IMPROVED LOOK) --- */
.drop-zone {
position: relative;
margin-top: 10px;
padding: 15px;
border: 2px dashed #54c800;
border-radius: 5px;
text-align: center;
color: #fff;
font-weight: bold;
transition: background-color 0.2s;
background-color: rgba(0, 0, 0, 0.4);
}
.drop-zone.dragover {
background-color: rgba(84, 200, 0, 0.3);
}
`;
document.head.appendChild(style);
//------------------------------------------------------------------
// LOCALSTORAGE HELPERS
//------------------------------------------------------------------
function getUsernameFromStorage() {
const settingsJson = localStorage.getItem("settings");
if (settingsJson) {
try {
const settings = JSON.parse(settingsJson);
return settings.lastNick || '';
} catch (e) {
console.error("Error parsing settings from local storage:", e);
return '';
}
}
return '';
}
function getAvatarURL() {
return localStorage.getItem('avatarURL') || '';
}
function setAvatarURL(url) {
localStorage.setItem('avatarURL', url);
}
//------------------------------------------------------------------
// TOAST / TOASTER
//------------------------------------------------------------------
function showToast(htmlMessage, duration) {
const toast = document.createElement('div');
toast.className = 'toast';
toast.innerHTML = htmlMessage;
document.body.appendChild(toast);
toast.style.display = 'block';
setTimeout(() => {
if (document.body.contains(toast)) {
document.body.removeChild(toast);
}
}, duration);
}
function showToaster(message) {
const toaster = document.createElement('div');
toaster.className = 'toaster';
toaster.textContent = message;
document.body.appendChild(toaster);
setTimeout(() => {
toaster.classList.add('show');
setTimeout(() => {
toaster.classList.remove('show');
setTimeout(() => {
document.body.removeChild(toaster);
}, 500);
}, 2000);
}, 10);
}
//------------------------------------------------------------------
// MAIN CHAT CONTAINER
//------------------------------------------------------------------
const chatDiv = document.createElement('div');
chatDiv.className = 'draggable';
document.body.appendChild(chatDiv);
// Status indicator
const statusIndicator = document.createElement('div');
statusIndicator.className = 'status-indicator';
statusIndicator.textContent = 'Connecting...';
chatDiv.appendChild(statusIndicator);
// The container that holds avatar input + chat input + send button
const messageContainer = document.createElement('div');
messageContainer.id = 'messageContainer';
chatDiv.appendChild(messageContainer);
// Avatar input container
const avatarInputContainer = document.createElement('div');
avatarInputContainer.id = "avatarInputContainer";
const avatarInputLabel = document.createElement('label');
avatarInputLabel.textContent = "Avatar URL:";
avatarInputContainer.appendChild(avatarInputLabel);
const avatarInput = document.createElement('input');
avatarInput.type = 'text';
avatarInput.id = 'avatarInput';
avatarInput.placeholder = "Enter Image URL";
avatarInput.value = getAvatarURL();
avatarInputContainer.appendChild(avatarInput);
messageContainer.appendChild(avatarInputContainer);
// Chat text input
const inputArea = document.createElement('input');
inputArea.id = 'inputArea';
inputArea.placeholder = 'Enter your message';
messageContainer.appendChild(inputArea);
// Send button
const sendButton = document.createElement('button');
sendButton.textContent = "Send";
sendButton.className = "send-button";
messageContainer.appendChild(sendButton);
// Message display area
const messageArea = document.createElement('div');
messageArea.id = "messageArea";
chatDiv.appendChild(messageArea);
//------------------------------------------------------------------
// CHAT WEBSOCKET LOGIC
//------------------------------------------------------------------
let socket;
function connectWebSocket() {
socket = new WebSocket("wss://newjackchat2.glitch.me");
socket.onopen = function() {
console.log("Connected to the chat server.");
statusIndicator.textContent = 'Connected';
statusIndicator.style.backgroundColor = '#00C851';
};
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
displayMessage(data.name, data.text, data.avatar || '');
if (musicOn) messageSound.play();
};
socket.onclose = function() {
console.log("WebSocket closed. Attempting to reconnect...");
statusIndicator.textContent = 'Disconnected - Reconnecting...';
statusIndicator.style.backgroundColor = '#ffbb33';
setTimeout(connectWebSocket, 5000);
};
socket.onerror = function(error) {
console.error("WebSocket Error:", error);
statusIndicator.textContent = 'Connection Error';
statusIndicator.style.backgroundColor = '#ff4444';
};
}
connectWebSocket();
function sendMessage() {
const avatarURL = avatarInput.value.trim() || getAvatarURL();
setAvatarURL(avatarURL); // store the avatar in localStorage
const message = {
name: getUsernameFromStorage().trim() || "Anonymous",
text: inputArea.value.trim(),
avatar: avatarURL
};
if (message.text) {
socket.send(JSON.stringify(message));
inputArea.value = "";
simulateButtonClick();
}
}
function simulateButtonClick() {
sendButton.classList.add("active");
setTimeout(() => {
sendButton.classList.remove("active");
}, 100);
}
sendButton.addEventListener("click", sendMessage);
inputArea.addEventListener("keypress", function(event) {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
sendMessage();
}
});
inputArea.addEventListener("keydown", function(event) {
if (event.key === " ") {
event.stopPropagation(); // prevent space from affecting gameplay
}
});
//------------------------------------------------------------------
// DISPLAY MESSAGES
//------------------------------------------------------------------
function displayMessage(name, text, avatar) {
const messageElement = document.createElement("div");
messageElement.className = "chat-message";
const avatarImg = document.createElement("img");
avatarImg.src = avatar || getAvatarURL();
avatarImg.style.width = "30px";
avatarImg.style.height = "30px";
avatarImg.style.marginRight = "10px";
avatarImg.style.verticalAlign = "middle";
avatarImg.onerror = function() {
avatarImg.src = getAvatarURL(); // fallback
};
const now = new Date();
const hours = now.getHours().toString().padStart(2, "0");
const minutes = now.getMinutes().toString().padStart(2, "0");
const formattedTime = `${hours}:${minutes}`;
const timestampSpan = document.createElement("span");
timestampSpan.style.cssText = "color: #888; margin-right: 10px;";
timestampSpan.textContent = formattedTime;
const usernameSpan = document.createElement("span");
usernameSpan.style.cssText = "font-weight: bold; margin-right: 5px;";
usernameSpan.textContent = name + ":";
messageElement.appendChild(avatarImg);
messageElement.appendChild(timestampSpan);
messageElement.appendChild(usernameSpan);
// If text is an image link, display image
if (/\.(jpeg|jpg|gif|png|svg|webp)$/i.test(text)) {
const image = document.createElement("img");
image.src = text;
image.style.maxWidth = "75px";
image.style.maxHeight = "75px";
image.alt = "Sent image";
image.onerror = function() {
image.parentNode.removeChild(image);
const errorText = document.createElement("span");
errorText.textContent = " [Invalid image URL]";
messageElement.appendChild(errorText);
};
messageElement.appendChild(image);
} else {
const messageText = document.createElement("span");
messageText.textContent = text;
messageElement.appendChild(messageText);
}
messageArea.appendChild(messageElement);
// Remove after 60 seconds
setTimeout(() => {
if (messageArea.contains(messageElement)) {
messageArea.removeChild(messageElement);
}
}, 60000);
}
//------------------------------------------------------------------
// SHOW / HIDE CHAT + RIGHT PANEL
//------------------------------------------------------------------
document.addEventListener("auxclick", function (e) {
// Double-click middle mouse to show chat & right panel
if (e.button === 1 && e.detail === 2) {
chatDiv.style.display = "flex";
rightPanel.style.display = "flex";
}
});
//------------------------------------------------------------------
// CHAT DRAGGING
//------------------------------------------------------------------
function makeDraggable(element) {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
element.onmousedown = function (e) {
// if user clicks close btn or an input or send button, don't drag
if (
e.target.classList.contains("close-button") ||
e.target.tagName === "INPUT" ||
e.target === sendButton
) {
return;
}
e.preventDefault();
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
};
function elementDrag(e) {
e.preventDefault();
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
element.style.top = element.offsetTop - pos2 + "px";
element.style.left = element.offsetLeft - pos1 + "px";
}
function closeDragElement() {
document.onmouseup = null;
document.onmousemove = null;
}
}
makeDraggable(chatDiv);
//------------------------------------------------------------------
// RESIZE HANDLE
//------------------------------------------------------------------
const resizeHandle = document.createElement("div");
resizeHandle.className = "resize-handle";
resizeHandle.textContent = "↗️";
resizeHandle.style.color = "white";
resizeHandle.style.backgroundColor = "#00d3ff";
resizeHandle.style.display = "inline-block";
resizeHandle.style.padding = "5px";
resizeHandle.style.fontSize = "12px";
resizeHandle.style.borderRadius = "50%";
resizeHandle.style.cursor = "ns-resize";
chatDiv.appendChild(resizeHandle);
let startX, startY, startWidth, startHeight;
resizeHandle.addEventListener("mousedown", function (e) {
e.preventDefault();
startX = e.clientX;
startY = e.clientY;
startWidth = parseInt(window.getComputedStyle(chatDiv).width, 10);
startHeight = parseInt(window.getComputedStyle(chatDiv).height, 10);
document.documentElement.addEventListener("mousemove", doDrag, false);
document.documentElement.addEventListener("mouseup", stopDrag, false);
});
function doDrag(e) {
chatDiv.style.width = `${startWidth + e.clientX - startX}px`;
chatDiv.style.height = `${startHeight + e.clientY - startY}px`;
}
function stopDrag() {
document.documentElement.removeEventListener("mousemove", doDrag, false);
document.documentElement.removeEventListener("mouseup", stopDrag, false);
}
//------------------------------------------------------------------
// CLOSE BUTTON
//------------------------------------------------------------------
const closeButton = document.createElement('div');
closeButton.textContent = 'x';
closeButton.className = 'close-button';
closeButton.onclick = () => {
// Hide both chat & right panel
chatDiv.style.display = 'none';
rightPanel.style.display = 'none';
showToast(`
<center>
Special thanks to<br>
<a href="https://imsolo.pro/" target="_blank"><img src="https://i.ibb.co/vC3f6M7f/K361z2W.png"></a>
ImSolo.Pro & LegendsMod
<a href="https://jimboy3100.github.io/" target="_blank">
<img src="https://jimboy3100.github.io/banners/icon32croped.ico.gif" class="icon-link">
</a><br><br>
Double click middle mouse button to bring chat back up
</center>
`, 3000);
};
chatDiv.appendChild(closeButton);
//------------------------------------------------------------------
// MINIMAP AUTO-ACTIVATE
//------------------------------------------------------------------
window.addEventListener("load", function () {
// 5 seconds after load, activate minimap
setTimeout(function () {
if (window.core && typeof core.setMinimap === 'function') {
core.setMinimap(1);
console.log("Minimap activated.");
// 5 seconds after that, enable players on minimap
setTimeout(function () {
if (typeof core.playersMinimap === 'function') {
core.playersMinimap(1);
console.log("Player indicators on minimap activated.");
}
}, 5000);
}
}, 5000);
});
//------------------------------------------------------------------
// CREATE RIGHT PANEL
//------------------------------------------------------------------
const rightPanel = document.createElement('div');
rightPanel.id = 'rightPanel';
document.body.appendChild(rightPanel);
// 1) Music toggle (default OFF)
const musicToggleButton = document.createElement('button');
musicToggleButton.className = 'toggle-button';
musicToggleButton.textContent = 'Sounds: OFF';
musicToggleButton.onclick = () => {
musicOn = !musicOn;
musicToggleButton.textContent = musicOn ? 'Sounds: ON' : 'Sounds: OFF';
if (musicOn) openSound.play();
};
rightPanel.appendChild(musicToggleButton);
// 2) Minimap toggle
let minimapOn = true;
const minimapToggleButton = document.createElement('button');
minimapToggleButton.className = 'toggle-button';
minimapToggleButton.textContent = 'Minimap: ON';
minimapToggleButton.onclick = () => {
minimapOn = !minimapOn;
minimapToggleButton.textContent = minimapOn ? 'Minimap: ON' : 'Minimap: OFF';
if (window.core && typeof core.setMinimap === 'function') {
core.setMinimap(minimapOn ? 1 : 0);
}
};
rightPanel.appendChild(minimapToggleButton);
// 3) Game IP Box
const gameIPBox = document.createElement('div');
gameIPBox.id = 'gameIPBox';
gameIPBox.textContent = 'Your game IP: Not available';
rightPanel.appendChild(gameIPBox);
function updateGameIP() {
if (typeof MC === "object" && typeof MC.getHost === "function") {
const fullHost = MC.getHost() || 'live-arena-undefined.agar.io';
const gameIP = fullHost.replace(/^live-arena-/, '').replace(/\.agar\.io$/, '');
gameIPBox.textContent = `Your game IP: ${gameIP}`;
} else {
gameIPBox.textContent = 'Your game IP: Not available';
}
}
setInterval(updateGameIP, 3000);
// Click to copy IP
gameIPBox.addEventListener('click', () => {
if (gameIPBox.textContent.includes('Your game IP:')) {
const gameIP = gameIPBox.textContent.replace('Your game IP: ', '');
navigator.clipboard.writeText(gameIP).then(() => {
showToaster('Game IP copied to clipboard!');
}).catch(err => {
console.error('Failed to copy text: ', err);
});
}
});
// 4) Fun stuff button
const funStuffButton = document.createElement('button');
funStuffButton.id = 'funStuffButton';
funStuffButton.className = 'styled-button';
funStuffButton.textContent = 'Agar.io Fun Stuff';
funStuffButton.addEventListener('click', () => {
document.getElementById('funStuffPopup').style.display = 'block';
});
rightPanel.appendChild(funStuffButton);
//------------------------------------------------------------------
// FUN STUFF POPUP
//------------------------------------------------------------------
const popupDiv = document.createElement('div');
popupDiv.id = 'funStuffPopup';
popupDiv.innerHTML = `
<button id="funStuffPopupClose">Close 🕹️</button>
<iframe src="https://newjackchat2.glitch.me/emojis.html"></iframe>
`;
document.body.appendChild(popupDiv);
document.getElementById('funStuffPopupClose').addEventListener('click', () => {
popupDiv.style.display = 'none';
});
//------------------------------------------------------------------
// RUSSIA -> UKRAINE REPLACE
//------------------------------------------------------------------
(function () {
function replaceText() {
const options = document.querySelectorAll('option[value="RU-Russia"]');
options.forEach(option => {
const text = option.textContent;
if (text.includes("Russia")) {
option.textContent = text.replace("Russia", "Ukraine");
}
});
}
replaceText();
const observer = new MutationObserver(replaceText);
observer.observe(document.body, { childList: true, subtree: true });
})();
//------------------------------------------------------------------
// ACID MODE CHECKBOX
//------------------------------------------------------------------
(function() {
function addAcidModeCheckbox() {
if (document.querySelector('#acidMode')) return;
const optionsDiv = document.querySelector('.options');
if (!optionsDiv) return;
const acidModeDiv = document.createElement('div');
acidModeDiv.className = 'checkbox checkbox-info checkbox-circle option';
const acidModeCheckbox = document.createElement('input');
acidModeCheckbox.type = 'checkbox';
acidModeCheckbox.id = 'acidMode';
acidModeCheckbox.className = 'styled';
const acidModeLabel = document.createElement('label');
acidModeLabel.setAttribute('for', 'acidMode');
acidModeLabel.textContent = 'Acid Mode';
acidModeDiv.appendChild(acidModeCheckbox);
acidModeDiv.appendChild(acidModeLabel);
optionsDiv.appendChild(acidModeDiv);
function applyShading(isChecked) {
if (isChecked) {
acidModeLabel.style.backgroundColor = '#4CAF50';
acidModeLabel.style.color = '#FFFFFF';
} else {
acidModeLabel.style.backgroundColor = '';
acidModeLabel.style.color = '';
}
}
const savedState = localStorage.getItem('acidModeEnabled') === 'true';
acidModeCheckbox.checked = savedState;
applyShading(savedState);
acidModeCheckbox.addEventListener('change', function() {
const isChecked = acidModeCheckbox.checked;
localStorage.setItem('acidModeEnabled', isChecked);
if (window.core && typeof window.core.setAcid === 'function') {
window.core.setAcid(isChecked);
console.log('Acid mode set to:', isChecked);
}
applyShading(isChecked);
});
}
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' || mutation.type === 'subtree') {
addAcidModeCheckbox();
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
addAcidModeCheckbox();
})();
//------------------------------------------------------------------
// DRAG-AND-DROP IMAGE UPLOAD (IMPROVED LOOK)
//------------------------------------------------------------------
function createUploadArea() {
// Container with "Upload Image" button and drop zone
const container = document.createElement('div');
container.style.position = "relative";
container.style.display = "inline-block";
// Drop zone area
const dropZone = document.createElement("div");
dropZone.className = "drop-zone";
dropZone.textContent = "Drag & Drop or Click 'Upload Image' above";
dropZone.style.display = "none"; // will show on button click
// File input
const fileInput = document.createElement("input");
fileInput.type = "file";
fileInput.accept = "image/*";
fileInput.id = "customImageUpload";
// We'll hide the file input behind the zone if we want:
fileInput.style.width = "100%";
fileInput.style.height = "100%";
fileInput.style.opacity = "0";
fileInput.style.position = "absolute";
fileInput.style.left = "0";
fileInput.style.top = "0";
fileInput.style.zIndex = "1";
fileInput.style.cursor = "pointer";
// Upload button
const uploadButton = document.createElement("button");
uploadButton.textContent = "Upload or drop an image here";
uploadButton.style.color = "#fff";
uploadButton.style.backgroundColor = "#54c800";
uploadButton.style.border = "1px solid black";
uploadButton.style.padding = "5px 10px";
uploadButton.style.cursor = "pointer";
// Clicking the upload button triggers the file input
uploadButton.addEventListener("click", (e) => {
e.stopPropagation();
dropZone.style.display = "block"; // show the drop zone on click
fileInput.click();
});
// Show/hide drop zone on fileInput click
fileInput.addEventListener("click", () => {
dropZone.style.display = "block";
});
// Handle file input "change" event
fileInput.addEventListener("change", (e) => {
if (e.target.files && e.target.files[0]) {
handleFile(e.target.files[0]);
}
});
// DRAG & DROP events
dropZone.addEventListener("dragover", (e) => {
e.preventDefault();
dropZone.classList.add("dragover");
});
dropZone.addEventListener("dragleave", () => {
dropZone.classList.remove("dragover");
});
dropZone.addEventListener("drop", (e) => {
e.preventDefault();
dropZone.classList.remove("dragover");
if (e.dataTransfer.files && e.dataTransfer.files[0]) {
handleFile(e.dataTransfer.files[0]);
}
});
// Build the container
container.appendChild(fileInput);
container.appendChild(uploadButton);
container.appendChild(dropZone);
return container;
}
function handleFile(file) {
if (!file) return;
if (file.type.startsWith("image/")) {
const reader = new FileReader();
reader.onloadend = function() {
const base64 = reader.result;
drawImage(base64);
};
reader.readAsDataURL(file);
} else {
console.log("Invalid file type or no file dropped.");
}
}
function drawImage(base64) {
// The code below draws the image to #skin-editor-canvas (if that exists),
// or do anything else you'd like with the base64
const canvas = document.getElementById("skin-editor-canvas");
if (!canvas) {
console.log("No skin-editor-canvas found, but here's your base64:\n", base64);
return;
}
const context = canvas.getContext("2d");
const image = new Image();
image.onload = function () {
canvas.width = 512;
canvas.height = 512;
context.drawImage(image, 0, 0, 512, 512);
context.save();
};
image.src = base64;
}
//------------------------------------------------------------------
// ADD SKIN FIELD RIGHT BELOW AVATAR URL
//------------------------------------------------------------------
function addCustomSkinField() {
// We'll place it inside #avatarInputContainer, right below the Avatar URL input
const container = document.getElementById('avatarInputContainer');
if (!container) return;
const wrapper = document.createElement('div');
wrapper.style.marginTop = '6px';
const urlInput = document.createElement('input');
urlInput.placeholder = 'Enter skin URL or leave blank';
urlInput.style.marginRight = '5px';
urlInput.style.width = '70%';
urlInput.style.border = '1px solid #666';
urlInput.style.background = 'rgba(255,255,255,0.1)';
urlInput.style.color = '#fff';
urlInput.style.borderRadius = '3px';
const loadButton = createButton('Turn Skin on', '#54c800', '#347f01', () => {
let skinURL = urlInput.value;
if (!skinURL) {
skinURL = 'default_skin_url';
console.log('No URL provided. Using default skin.');
}
console.log(`Setting skin to ${skinURL}`);
try {
core.registerSkin(null, "%SubscribeToBeeChasnyAgario", skinURL, 2, null);
core.loadSkin("%SubscribeToBeeChasnyAgario");
} catch (e) {
console.error("Error loading the skin:", e);
}
});
const unloadButton = createButton('Turn Skin off', '#c85400', '#7f3401', () => {
try {
if (typeof core.unregisterSkin === "function") {
core.unregisterSkin("%SubscribeToBeeChasnyAgario");
} else {
console.error("unregisterSkin function is not available. Resetting manually...");
}
urlInput.value = '';
console.log("Skin reset or unloaded.");
} catch (e) {
console.error("Error attempting to unload the skin:", e);
}
});
wrapper.appendChild(urlInput);
wrapper.appendChild(loadButton);
wrapper.appendChild(unloadButton);
container.appendChild(wrapper);
}
function createButton(text, bgColor, hoverColor, action) {
const button = document.createElement('button');
button.style.backgroundColor = bgColor;
button.style.color = "#FFFFFF";
button.style.border = "none";
button.style.padding = "5px 10px";
button.style.cursor = "pointer";
button.style.marginLeft = "5px";
button.innerText = text;
button.onmouseover = function() {
this.style.backgroundColor = hoverColor;
};
button.onmouseout = function() {
this.style.backgroundColor = bgColor;
};
button.addEventListener('click', action);
return button;
}
//------------------------------------------------------------------
// INSERT DRAG & DROP UPLOAD AREA INTO .right-tools (optional)
//------------------------------------------------------------------
function observeTargetContainer() {
const observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
const target = document.querySelector(".right-tools");
if (target && !target.querySelector("#customImageUpload")) {
const uploadArea = createUploadArea();
const newDiv = document.createElement("div");
newDiv.style.marginTop = "50px";
newDiv.appendChild(uploadArea);
if (target.querySelector(".save")) {
target.querySelector(".save").appendChild(newDiv);
} else {
target.appendChild(newDiv);
}
}
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
//------------------------------------------------------------------
// ACTIVATE EVERYTHING
//------------------------------------------------------------------
addCustomSkinField(); // Adds "Turn Skin on/off" right under the avatar URL
observeTargetContainer(); // Adds drag/drop in the .right-tools panel (if present)
})();
(function () {
'use strict';
// --- Remove the default agar.io background image ---
const originalDrawImage = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function (img) {
// Skip drawing the default background
if (img && img.src === "https://agar.io/img/background.png") {
return;
}
originalDrawImage.apply(this, arguments);
};
})();