Agar.io---Chat, Minimap, Bar Remover, Custom Skins, Skin Maker

Adds a draggable chat interface with sound notifications, disappearing messages, ad bar remover, game ip, custom skin upload, use skin urls and minimap.

当前为 2024-05-07 提交的版本,查看 最新版本

// ==UserScript==
// @name         Agar.io---Chat, Minimap, Bar Remover, Custom Skins, Skin Maker
// @namespace    All in one mod, doesnt add cheats.
// @version      0.1
// @description  Adds a draggable chat interface with sound notifications, disappearing messages, ad bar remover, game ip, custom skin upload, use skin urls and minimap.
// @author       𝓝𝑒ⓦ 𝓙ⓐ¢𝓀🕹️
// @match        https://agar.io/*
// @grant        none
// @run-at       document-idle
// @license MIT
// ==/UserScript==
(function() {
    'use strict';


    // Utility functions
    function createAudioElement(audioUrl) {
        const audio = new Audio(audioUrl);
        return audio;
    }

    const messageSound = createAudioElement('https://jimboy3100.github.io/notification_01.mp3');
    const openSound = createAudioElement('https://jimboy3100.github.io/sounds/notification-open.mp3');
    let musicOn = true; // Variable to track music state

    // Append styles
    const style = document.createElement('style');
    document.head.appendChild(style);
    style.textContent = `
        .send-button, .resize-handle, .toggle-button, .info-box, .status-indicator, .toast {
            flex-shrink: 0;
            background-color: #54c800;
            color: white;
            padding: 8px 16px;
            border: none;
            cursor: pointer;
            border-radius: 4px;
        }
        .send-button:hover, .toggle-button:hover {
            background-color: #3d8b00;
        }
        .send-button:active, .send-button.active, .toggle-button.active {
            background-color: #296600;
        }
        .draggable, .toast {
            position: fixed;
            bottom: 0;
            left: 0;
            width: 25%;
            height: 400px;
            background-color: rgba(0,0,0,.2);
            display: flex;
            flex-direction: column;
            cursor: move;
            overflow: hidden;
        }
        .resize-handle {
            position: absolute;
            bottom: 0;
            right: 0;
            width: 10px;
            height: 10px;
            background-color: #ccc;
            cursor: nwse-resize;
        }
        .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; // Position at the bottom of the container
          left: 10px;
            width: 50%; // Full width
            text-align: center; // Center text
        }
                .info-box {
            background-color: #0077ff;
        }
               #settingsContainer {
            display: flex;
            justify-content: space-around;
            padding: 10px;
            background: rgba(0,0,0,.2);
            color: white;
        }
                .toast {
            bottom: 10%;  // Position above the bottom of the viewport
            left: 50%;  // Center horizontally
            transform: translateX(-50%);  // Align center
            background-color: #333;  // Dark background for the toast
            color: white;
            padding: 10px;
            border-radius: 5px;
            text-align: center;
            z-index: 1000;  // Make sure it is on top
            display: none;  // Initially hidden
        }
                .icon-container {
            position: absolute;
            bottom: 10px;
            left: 10px;
            display: flex;
            color: white;

        }
    `;
  const getUsernameFromStorage = () => {
        const settingsJson = localStorage.getItem("settings");
        if (settingsJson) {
            try {
                const settings = JSON.parse(settingsJson);
                return settings.lastNick || '';// Ensure default if undefined
            } catch (e) {
                console.error("Error parsing settings from local storage:", e);
                return ''; // Default to empty if error occurs
            }
        }
        return '';// Default to empty if no settings
    };
function showToast(htmlMessage, duration) {
    const toast = document.createElement('div');
    toast.className = 'toast';
    toast.innerHTML = htmlMessage; // Set innerHTML to interpret the string as HTML
    document.body.appendChild(toast);

    setTimeout(() => {
        if (document.body.contains(toast)) {
            document.body.removeChild(toast);
        }
    }, duration);
}
    // 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...'; // Initial message
    chatDiv.appendChild(statusIndicator);

    // WebSocket setup with reconnection
    let socket; // Hold the WebSocket in a variable accessible in the scope

    function connectWebSocket() {
        socket = new WebSocket("wss://newjackchat.glitch.me");

        socket.onopen = function() {
            console.log("Connected to the chat server.");
            statusIndicator.textContent = 'Connected';
            statusIndicator.style.backgroundColor = '#00C851'; // Green for connected
        };

        socket.onmessage = function(event) {
            const data = JSON.parse(event.data);
            displayMessage(data.name, data.text);
            messageSound.play();
        };

        socket.onclose = function(event) {
            console.log("WebSocket closed. Attempting to reconnect...");
            statusIndicator.textContent = 'Disconnected - Reconnecting...';
            statusIndicator.style.backgroundColor = '#ffbb33'; // Yellow for reconnecting
            setTimeout(connectWebSocket, 5000); // Attempt to reconnect after 5 seconds
        };

        socket.onerror = function(error) {
            console.error("WebSocket Error:", error);
            statusIndicator.textContent = 'Connection Error';
            statusIndicator.style.backgroundColor = '#ff4444'; // Red for error
        };
    }

    connectWebSocket(); // Initial connection
     // Settings container
    const settingsContainer = document.createElement('div');
    settingsContainer.id = 'settingsContainer';
    chatDiv.appendChild(settingsContainer);

    // Music toggle button
    const musicToggleButton = document.createElement('button');
    musicToggleButton.className = 'toggle-button';
    musicToggleButton.textContent = 'Toggle Sound';
    musicToggleButton.onclick = () => {
        musicOn = !musicOn;
        musicToggleButton.textContent = musicOn ? 'Sounds: ON' : 'Sounds: OFF';
        if (musicOn) {
            openSound.play();
        }
    };
    settingsContainer.appendChild(musicToggleButton);

    // Info box to display the game IP
const gameIPBox = document.createElement('div');
gameIPBox.className = 'info-box';
gameIPBox.style.flexBasis = '100px'; // Ensuring it matches the size of toggle buttons
gameIPBox.style.textAlign = 'center'; // Centering the text
settingsContainer.appendChild(gameIPBox);

// Function to update game IP in the box
function updateGameIP() {
    // Ensure MC and MC.getHost are available to prevent errors
    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';
    }
}

// Set interval to update the game IP every 3 seconds
setInterval(updateGameIP, 3000);

    // Minimap toggle button
    const minimapToggleButton = document.createElement('button');
    minimapToggleButton.className = 'toggle-button';
    minimapToggleButton.textContent = 'Toggle Minimap';
    let minimapOn = true;
    minimapToggleButton.onclick = () => {
        minimapOn = !minimapOn;
        minimapToggleButton.textContent = minimapOn ? 'Minimap: ON' : 'Minimap: OFF';
        // Toggle minimap functionality here
        minimapOn ? core.setMinimap(1) : core.setMinimap(0);
    };
    settingsContainer.appendChild(minimapToggleButton);

    // Initially set minimap and music to on
    window.addEventListener('load', () => {
        setTimeout(() => {
            musicOn && openSound.play();
            minimapOn && core.setMinimap(1);
        }, 1000);
    });


  // Resize handle
  const resizeHandle = document.createElement("div");
  resizeHandle.className = "resize-handle";
  resizeHandle.textContent = "↗️"; // Using the vertical arrow emoji as the content
  resizeHandle.style.color = "white"; // Set the emoji/text color to black
  resizeHandle.style.backgroundColor = "#00d3ff"; // Set the background color to cyan blue
  resizeHandle.style.display = "inline-block"; // Ensure the div behaves like an inline element with block capabilities
  resizeHandle.style.padding = "5px"; // Add some padding around the emoji
  resizeHandle.style.fontSize = "12px"; // Set a specific font size if needed
  resizeHandle.style.borderRadius = "50%"; // Optionally make it circular
  resizeHandle.style.cursor = "ns-resize"; // Set the cursor for resizing indication
  chatDiv.appendChild(resizeHandle);

  // Resize functionality
  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);
  }
const closeButton = document.createElement('div');
closeButton.textContent = 'x';
closeButton.className = 'close-button';
closeButton.onclick = () => {
    chatDiv.style.display = 'none';
    showToast(`
        <center>
            Special thanks to<br>
            <a href="https://imsolo.pro/" target="_blank"><img src="https://i.imgur.com/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>
    `, 4000);
};
chatDiv.appendChild(closeButton);



  // Username input
  const usernameContainer = document.createElement("div");
  usernameContainer.id = "usernameContainer";
  const usernameInput = document.createElement("input");
  usernameInput.value = getUsernameFromStorage();
  usernameInput.placeholder = "Enter your nickname";
  usernameInput.style.cssText =
    "width: 75%; padding: 8px; border-radius: 4px; background: rgba(0,0,0,.1); color: white;";
  usernameContainer.appendChild(usernameInput);
  chatDiv.appendChild(usernameContainer);

  // Message input area
  const messageContainer = document.createElement("div");
  messageContainer.id = "messageContainer";
  const inputArea = document.createElement("input");
  inputArea.placeholder = "Enter your message";
  inputArea.style.cssText =
    "width: 75%; flex-grow: 1; padding: 8px; border-radius: 4px; background: rgba(0,0,0,.1); color: white;";
  messageContainer.appendChild(inputArea);

  // Send button
  const sendButton = document.createElement("button");
  sendButton.textContent = "Send";
  sendButton.className = "send-button";
  messageContainer.appendChild(sendButton);

  chatDiv.appendChild(messageContainer);
  const messageArea = document.createElement("div");
  messageArea.style.cssText =
    "flex-grow: 1; overflow: auto; margin: 5px; padding: 5px; background: rgba(0,0,0,.1); color: white;";
  chatDiv.appendChild(messageArea);




  // Function to handle sending messages
  function sendMessage() {
    const message = {
      name: usernameInput.value.trim() || "Anonymous",
      text: inputArea.value.trim(),
    };

    if (message.text) {
      socket.send(JSON.stringify(message));
      inputArea.value = ""; // Clear input after sending
      simulateButtonClick(); // Visual feedback for button press
    }
  }

  // Simulate button click effects
  function simulateButtonClick() {
    sendButton.classList.add("active");
    setTimeout(() => {
      sendButton.classList.remove("active");
    }, 100);
  }

  // Event listeners for sending messages
  sendButton.addEventListener("click", sendMessage);
  inputArea.addEventListener("keypress", function (event) {
    if (event.key === "Enter" && !event.shiftKey) {
      event.preventDefault();
      sendMessage();
    }
  });

  // Handle incoming messages
  socket.onmessage = function (event) {
    const data = JSON.parse(event.data);
    displayMessage(data.name, data.text);
    messageSound.play();
  };

  function displayMessage(name, text) {
    const messageElement = document.createElement("div");
    messageElement.style.cssText =
      "padding: 5px; border-bottom: 1px solid #ccc;"; // Styling for message

    // Create and format the timestamp
    const now = new Date();
    const hours = now.getHours().toString().padStart(2, "0");
    const minutes = now.getMinutes().toString().padStart(2, "0");
    const formattedTime = `${hours}:${minutes}`; // Format "HH:MM"

    const timestampSpan = document.createElement("span");
    timestampSpan.style.cssText = "color: #888; margin-right: 10px;"; // Styling for timestamp
    timestampSpan.textContent = formattedTime;

    // Create a span for the username
    const usernameSpan = document.createElement("span");
    usernameSpan.style.cssText = "font-weight: bold; margin-right: 5px;";
    usernameSpan.textContent = name + ":";

    // Append timestamp and username to the message element
    messageElement.appendChild(timestampSpan);
    messageElement.appendChild(usernameSpan);

    // Check if the text is likely an image URL
    if (/\.(jpeg|jpg|gif|png|svg)$/i.test(text)) {
      const image = document.createElement("img");
      image.src = text;
      image.style.maxWidth = "75px";
      image.style.maxHeight = "75px";
      image.alt = "Sent image"; // Alt text for accessibility
      image.onerror = function () {
        // Remove image and show error if it can't be loaded
        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);
    }

    // Append the complete message element to the message area and set to disappear after 1 minute
    messageArea.appendChild(messageElement);
    setTimeout(() => {
      if (messageArea.contains(messageElement)) {
        messageArea.removeChild(messageElement);
      }
    }, 60000);
  }

  // Reappear chat on double middle-click
  document.addEventListener("auxclick", function (e) {
    if (e.button === 1 && e.detail === 2) {
      chatDiv.style.display = "flex";
    }
  });

  // Draggable functionality
  function makeDraggable(element) {
    let pos1 = 0,
      pos2 = 0,
      pos3 = 0,
      pos4 = 0;
    element.onmousedown = function (e) {
      if (
        e.target === closeButton ||
        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);

  // Play open sound on load
  window.onload = function () {
    setTimeout(playOpenSound, 1000);
  };

  function playOpenSound() {
    openSound.play();
  }
  window.addEventListener("load", function () {
    // Set a timeout to run 5 seconds after the page loads
    setTimeout(function () {
      // Activate the minimap
      core.setMinimap(1);
      console.log("Minimap activated.");

      // Set another timeout to activate player indicators 5 seconds after the minimap is activated
      setTimeout(function () {
        core.playersMinimap(1);
        console.log("Player indicators on minimap activated.");
      }, 5000);
    }, 5000); // 5 seconds delay to start the first action
  });


    // Change --bottom-banner-height to 0px
    document.documentElement.style.setProperty('--bottom-banner-height', '0px');

    // Change the size of the div with id agar-io_970x90
    let targetDiv = document.getElementById('agar-io_970x90');
    if (targetDiv) {
        targetDiv.style.width = '970px';
        targetDiv.style.height = '1px';
    }






    function addCustomSkinField() {
        const mainPanel = document.querySelector('#mainPanel');

        if (mainPanel) {
            const container = document.createElement('div');
            container.style.marginBottom = '10px';

            const urlInput = document.createElement('input');
            urlInput.placeholder = 'Enter skin URL or leave blank for default...';
            urlInput.style.marginRight = '5px';

            const loadButton = createButton('Turn Skin on', '#54c800', '#347f01', () => {
                let skinURL = urlInput.value;
                if (!skinURL) {
                    skinURL = 'default_skin_url'; // Placeholder for 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...");
                        // Implement manual reset logic here if unregisterSkin is not available
                    }
                    urlInput.value = '';  // Reset the URL input field
                    console.log("Skin reset or unloaded.");
                } catch (e) {
                    console.error("Error attempting to unload the skin:", e);
                }
            });

            container.appendChild(urlInput);
            container.appendChild(loadButton);
            container.appendChild(unloadButton);

            mainPanel.insertBefore(container, mainPanel.firstChild);
        } else {
            console.warn('Main panel not found. Cannot insert skin loader.');
        }
    }

    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.innerText = text;
        button.onmouseover = function() {
            this.style.backgroundColor = hoverColor;
        };
        button.onmouseout = function() {
            this.style.backgroundColor = bgColor;
        };
        button.addEventListener('click', action);
        return button;
    }

    const checkInterval = setInterval(() => {
        if (document.querySelector('#mainPanel')) {
            clearInterval(checkInterval);
            addCustomSkinField();
        }
    }, 1000);

})();

(function () {
  'use strict';

function createButton() {
    const container = document.createElement("div");
    container.style.position = "relative";
    container.style.display = "inline-block";

    // The file input, which will be visually hidden
    const input = document.createElement("input");
    input.type = "file";
    input.accept = "image/*";
    input.id = "customImageUpload";
    input.style.width = "100%";
    input.style.height = "100%";
    input.style.opacity = "0";
    input.style.position = "absolute";
    input.style.left = "0";
    input.style.top = "0";
    input.style.zIndex = "1";// Ensure it's clickable

    // A styled div or button that will be visible and clickable
    const button = document.createElement("button");
    button.textContent = "Upload Image";
    button.style.color = "#fff";
    button.style.backgroundColor = "#54c800";
    button.style.border = "1px solid black";
    button.style.padding = "5px 10px";
    button.style.cursor = "pointer";

    // Append the input and the styled div/button to the container
    container.appendChild(input);
    container.appendChild(button);

    // Return the entire container
    return container;
}

function insertButton(container, target) {
    if (target) {
        const newDiv = document.createElement("div");
        newDiv.style.marginTop = "50px"; // Add some space between the divs
        newDiv.appendChild(container);
        target.querySelector(".save").appendChild(newDiv);
    }
}


  // Convert the uploaded image to a base64 string and draw it on the canvas
  function convertImageToBase64(event) {
    const file = event.target.files[0];
    const reader = new FileReader();

    reader.onloadend = function () {
      const base64 = reader.result;
      drawImage(base64);
    };

    reader.readAsDataURL(file);
  }

  // Draw the given base64 image on the canvas, resizing it to 512x512
  function drawImage(base64) {
    const canvas = document.getElementById("skin-editor-canvas");
    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;
  }

  // Check for the target element every 5 seconds (5000 milliseconds)
  function checkForTarget() {
    const target = document.querySelector(".right-tools");

    if (target) {
      const button = createButton();
      insertButton(button, target);
      button.addEventListener("change", convertImageToBase64);
      clearInterval(checkInterval); // Clear the interval once the button is added
    }
  }

  // Start checking for the target element
  const checkInterval = setInterval(checkForTarget, 1000);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址