New Jacks Agario Mod

Enhances Agar.io with custom controls, advanced features, and skin-maker drag-and-drop

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         New Jacks Agario Mod
// @namespace    All in one mod, doesnt add cheats.
// @version      1.1
// @description  Enhances Agar.io with custom controls, advanced features, and skin-maker drag-and-drop
// @author       𝓝𝑒ⓦ 𝓙ⓐ¢𝓀🕹️
// @match        https://agar.io/*
// @grant        none
// @license      MIT
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // Remove background image
    const originalDrawImage = CanvasRenderingContext2D.prototype.drawImage;
    CanvasRenderingContext2D.prototype.drawImage = function (img) {
        if (img && img.src === "https://agar.io/img/background.png") {
            return;
        }
        originalDrawImage.apply(this, arguments);
    };

    window.addEventListener('DOMContentLoaded', function() {
        document.documentElement.removeAttribute('style');
        const adDiv = document.querySelector('#agar-io_970x90');
        if (adDiv) {
            adDiv.remove();
        }
        initAgarioMod();
        observeTargetContainer();
        initRussiaToUkraine();
    });

    //------------------------------------------------------------------
    // 1) Main Agar.io Mod
    //------------------------------------------------------------------
    function initAgarioMod() {
        const CONFIG = {
            enableMod: true,
            leftMouseAction:  'macroFeed',  // "none" | "singleFeed" | "macroFeed" | "split"
            rightMouseAction: 'split',
            singleFeedKey:    'w',
            macroFeedKey:     'm',
            doubleSplitKey:   'd',
            tripleSplitKey:   't',
            quadSplitKey:     'q',
            straightLineKey:  'e',
            zoomOutKey:       '-',
            zoomInKey:        '=',
            acidModeKey:      'a',
            skinSwitcherKey:  's',
            toggleUIKey:      'h',
            pauseMovementKey: 'p',
            enableGamepad: false,
            enableAcidMode: false,
            enableMinimap: true,
            enableCustomSkin: true,
            customSkinUrl: '',
            feedRate: 50,
            splitDelay: 50,
            gamepadSplit:        0,
            gamepadFeed:         1,
            gamepadDoubleSplit:  2,
            gamepadTripleSplit:  3,
            gamepadAcidMode:     9,
            gamepadStraightLine: 10,
        };

        let isMacroFeeding = false;
        let macroFeedInterval = null;
        let gameCanvas = null;
        let startingMousePosition = { x: 0, y: 0 };
        let currentMousePosition = { x: 0, y: 0 };
        let isStraightLineMode = false;
        let originalSkin = '';
        let modUIVisible = false;
        let isPaused = false;
        let connectedGamepads = [];
        let lastGamepadState = {};
        let isRemappingGamepad = false;
        let remappingButton = null;
        let showControlsButton = null;
        let mainOverlay = null;

        function initMod() {
            console.log('Initializing New Jacks Agario Mod...');
            createShowControlsButton();
            createMainOverlay();
            setTimeout(findGameCanvas, 2000);
            document.addEventListener('keydown', handleKeyDown);
            document.addEventListener('keyup', handleKeyUp);
            captureOriginalSkin();
            increaseNickLimit();
            console.log('Mod initialized successfully!');
        }

        function createShowControlsButton() {
            showControlsButton = document.createElement('button');
            showControlsButton.id = 'show-controls-button';
            showControlsButton.textContent = 'Show Controls';
            showControlsButton.style.cssText = `
                position: fixed;
                top: 10px;
                left: 10px;
                z-index: 99999;
                padding: 5px 10px;
                background-color: #54c800;
                color: #fff;
                border: none;
                border-radius: 5px;
                cursor: pointer;
                font-family: Arial, sans-serif;
                transition: background-color 0.2s ease;
            `;
            showControlsButton.addEventListener('mouseover', () => {
                showControlsButton.style.backgroundColor = '#347f01';
            });
            showControlsButton.addEventListener('mouseout', () => {
                showControlsButton.style.backgroundColor = '#54c800';
            });
            showControlsButton.addEventListener('mousedown', () => {
                showControlsButton.style.backgroundColor = '#347f01';
            });
            showControlsButton.addEventListener('mouseup', () => {
                showControlsButton.style.backgroundColor = '#54c800';
            });
            showControlsButton.onclick = toggleMainOverlay;
            document.body.appendChild(showControlsButton);
        }

        function findGameCanvas() {
            const canvases = document.getElementsByTagName('canvas');
            if (canvases.length > 0) {
                for (let i = 0; i < canvases.length; i++) {
                    if (canvases[i].width > 500 && canvases[i].height > 500) {
                        gameCanvas = canvases[i];
                        break;
                    }
                }
                if (gameCanvas) {
                    console.log('Game canvas found!');
                    gameCanvas.addEventListener('mousedown', handleMouseDown);
                    gameCanvas.addEventListener('mouseup', handleMouseUp);
                    gameCanvas.addEventListener('contextmenu', (e) => e.preventDefault() );
                    gameCanvas.addEventListener('mousemove', (e) => {
                        currentMousePosition.x = e.clientX;
                        currentMousePosition.y = e.clientY;
                        if (isStraightLineMode) {
                            applyLineConstraint();
                        }
                    });
                    showNotification('Advanced Controls Active! Press H for help or to toggle UI.');
                } else {
                    console.log('Game canvas not found, retrying...');
                    setTimeout(findGameCanvas, 2000);
                }
            } else {
                console.log('No canvases found, retrying...');
                setTimeout(findGameCanvas, 2000);
            }
        }

        function handleMouseDown(e) {
            if (!CONFIG.enableMod) return;
            if (isPaused) return;
            if (e.button === 0) {
                doMouseAction(CONFIG.leftMouseAction, 'down');
            } else if (e.button === 2) {
                doMouseAction(CONFIG.rightMouseAction, 'down');
            }
        }
        function handleMouseUp(e) {
            if (!CONFIG.enableMod) return;
            if (isPaused) return;
            if (e.button === 0) {
                doMouseAction(CONFIG.leftMouseAction, 'up');
            } else if (e.button === 2) {
                doMouseAction(CONFIG.rightMouseAction, 'up');
            }
        }

        function doMouseAction(action, phase) {
            if (action === 'none') {
                return;
            }
            else if (action === 'singleFeed') {
                if (phase === 'down') {
                    window.core.eject();
                }
            }
            else if (action === 'macroFeed') {
                if (phase === 'down') {
                    startMacroFeed();
                } else if (phase === 'up') {
                    stopMacroFeed();
                }
            }
            else if (action === 'split') {
                if (phase === 'down') {
                    window.core.split();
                }
            }
        }

        function handleKeyDown(e) {
            if (e.key.toLowerCase() === CONFIG.toggleUIKey) {
                toggleMainOverlay();
                return;
            }
            if (!CONFIG.enableMod) return;
            if (isPaused) { }
            switch (e.key.toLowerCase()) {
                case CONFIG.singleFeedKey:
                    window.core.eject();
                    break;
                case CONFIG.macroFeedKey:
                    startMacroFeed();
                    break;
                case CONFIG.doubleSplitKey:
                    performMultiSplit(2);
                    break;
                case CONFIG.tripleSplitKey:
                    performMultiSplit(3);
                    break;
                case CONFIG.quadSplitKey:
                    performMultiSplit(4);
                    break;
                case CONFIG.straightLineKey:
                    toggleStraightLineMode();
                    break;
                case CONFIG.zoomOutKey:
                    window.core.playerZoom(0.8);
                    break;
                case CONFIG.zoomInKey:
                    window.core.playerZoom(1.2);
                    break;
                case CONFIG.acidModeKey:
                    toggleAcidMode();
                    break;
                case CONFIG.skinSwitcherKey:
                    openSkinSwitcherUI();
                    break;
                case CONFIG.pauseMovementKey:
                    isPaused = !isPaused;
                    showNotification(isPaused ? 'Movement is paused.' : 'Movement unpaused.');
                    break;
            }
        }
        function handleKeyUp(e) {
            if (!CONFIG.enableMod) return;
            if (e.key.toLowerCase() === CONFIG.macroFeedKey) {
                stopMacroFeed();
            }
        }

        function startMacroFeed() {
            if (isMacroFeeding) return;
            isMacroFeeding = true;
            showNotification('Macro feeding started');
            window.core.eject();
            macroFeedInterval = setInterval(() => {
                window.core.eject();
            }, CONFIG.feedRate);
        }
        function stopMacroFeed() {
            if (!isMacroFeeding) return;
            clearInterval(macroFeedInterval);
            isMacroFeeding = false;
            showNotification('Macro feeding stopped');
        }

        function performMultiSplit(count) {
            if (!window.core.playerHasCells || !window.core.playerHasCells()) {
                showNotification('Cannot split when dead');
                return;
            }
            showNotification(`${count}x Split`);
            for (let i = 0; i < count; i++) {
                setTimeout(() => {
                    window.core.split();
                }, CONFIG.splitDelay * i);
            }
        }

        function toggleStraightLineMode() {
            isStraightLineMode = !isStraightLineMode;
            if (isStraightLineMode) {
                startingMousePosition.x = currentMousePosition.x;
                startingMousePosition.y = currentMousePosition.y;
                showNotification('Straight line mode ON');
            } else {
                showNotification('Straight line mode OFF');
            }
        }
        function applyLineConstraint() {
            if (!isStraightLineMode) return;
            const dx = currentMousePosition.x - startingMousePosition.x;
            const dy = currentMousePosition.y - startingMousePosition.y;
            const angle = Math.atan2(dy, dx);
            const snappedAngle = Math.round(angle / (Math.PI / 4)) * (Math.PI / 4);
            const distance = Math.sqrt(dx*dx + dy*dy);
            const newX = startingMousePosition.x + Math.cos(snappedAngle)*distance;
            const newY = startingMousePosition.y + Math.sin(snappedAngle)*distance;
            window.core.setTarget(newX, newY);
        }

        function increaseNickLimit() {
            const updateNickInput = () => {
                const nickInputs = document.querySelectorAll('input[id="nick"], input[placeholder="Nick"], input[maxlength="15"]');
                if (nickInputs.length > 0) {
                    nickInputs.forEach(input => {
                        input.setAttribute('maxlength', '50');
                    });
                    showNotification('Nickname limit increased to 50 characters');
                } else {
                    setTimeout(updateNickInput, 2000);
                }
            };
            updateNickInput();
            try {
                const observer = new MutationObserver(mutations => {
                    for (const mutation of mutations) {
                        if (mutation.type === 'childList' && mutation.addedNodes.length) {
                            for (const node of mutation.addedNodes) {
                                if (node.nodeType === Node.ELEMENT_NODE) {
                                    const inputs = node.querySelectorAll ?
                                        node.querySelectorAll('input[id="nick"], input[placeholder="Nick"], input[maxlength="15"]') : [];
                                    if (
                                        node.tagName === 'INPUT' &&
                                        (node.id === 'nick' || node.placeholder === 'Nick' || node.getAttribute('maxlength') === '15')
                                    ) {
                                        node.setAttribute('maxlength', '50');
                                    }
                                    if (inputs.length > 0) {
                                        inputs.forEach(input => {
                                            input.setAttribute('maxlength', '50');
                                        });
                                    }
                                }
                            }
                        }
                    }
                });
                observer.observe(document.body, { childList: true, subtree: true });
            } catch (e) {
                console.error('Error setting up MutationObserver:', e);
            }
        }

        function showNotification(message) {
            let notification = document.getElementById('agario-mod-notification');
            if (!notification) {
                notification = document.createElement('div');
                notification.id = 'agario-mod-notification';
                notification.style.cssText = `
                    position: absolute;
                    top: 80px;
                    left: 50%;
                    transform: translateX(-50%);
                    background-color: rgba(0, 0, 0, 0.7);
                    color: white;
                    padding: 10px 20px;
                    border-radius: 5px;
                    font-family: Arial, sans-serif;
                    font-size: 16px;
                    z-index: 1000;
                    transition: opacity 0.5s;
                    pointer-events: none;
                `;
                document.body.appendChild(notification);
            }
            notification.textContent = message;
            notification.style.opacity = '1';
            clearTimeout(notification.fadeTimeout);
            notification.fadeTimeout = setTimeout(() => {
                notification.style.opacity = '0';
            }, 2000);
        }

        function captureOriginalSkin() {
            if (window.core) {
                try {
                    const observer = new MutationObserver((mutations, obs) => {
                        const skinContainer = document.querySelector('#skin-preview');
                        if (skinContainer) {
                            const skinImg = skinContainer.querySelector('img');
                            if (skinImg && skinImg.src) {
                                originalSkin = skinImg.src;
                                obs.disconnect();
                            }
                        }
                    });
                    observer.observe(document.body, { childList: true, subtree: true });
                    try {
                        const localData = localStorage.getItem('ogarioSettings');
                        if (localData) {
                            const settings = JSON.parse(localData);
                            if (settings && settings.skin) {
                                originalSkin = settings.skin;
                            }
                        }
                    } catch (e) {
                        console.warn('Failed to get skin from localStorage', e);
                    }
                } catch (e) {
                    console.warn('Failed to capture original skin', e);
                }
            }
        }

        function applyCustomSkin(url) {
            if (!window.core) return;
            try {
                if (!originalSkin) {
                    captureOriginalSkin();
                }
                window.core.registerSkin(null, "customskin", url, 0, 0);
                window.core.loadSkin("customskin");
                CONFIG.customSkinUrl = url;
                CONFIG.enableCustomSkin = true;
                showNotification('Custom skin applied');
            } catch (e) {
                showNotification('Failed to apply skin: ' + e.message);
                console.error('Failed to apply skin:', e);
            }
        }

        function toggleCustomSkin() {
            CONFIG.enableCustomSkin = !CONFIG.enableCustomSkin;
            if (CONFIG.enableCustomSkin && CONFIG.customSkinUrl) {
                applyCustomSkin(CONFIG.customSkinUrl);
            } else {
                if (window.core) {
                    if (originalSkin && originalSkin.startsWith('http')) {
                        window.core.registerSkin(null, "originalskin", originalSkin, 0, 0);
                        window.core.loadSkin("originalskin");
                        showNotification('Restored original skin');
                    } else if (originalSkin) {
                        window.core.loadSkin(originalSkin);
                        showNotification('Restored original skin');
                    } else {
                        window.core.loadSkin("");
                        showNotification('Custom skin disabled');
                    }
                }
            }
        }

        function loadSkinsFromStorage() {
            let data = localStorage.getItem('myCustomSkins');
            if (!data) return [];
            try {
                return JSON.parse(data);
            } catch(e) {
                console.error('Failed to parse myCustomSkins:', e);
                return [];
            }
        }
        function saveSkinsToStorage(arr) {
            localStorage.setItem('myCustomSkins', JSON.stringify(arr));
        }

        function openSkinSwitcherUI() {
            let existing = document.getElementById('skin-switcher-overlay');
            if (existing) {
                existing.style.display = 'flex';
                return;
            }
            const overlay = document.createElement('div');
            overlay.id = 'skin-switcher-overlay';
            overlay.style.cssText = `
                position: fixed;
                top: 10%;
                left: 10%;
                width: 640px;
                max-width: 90%;
                background-color: rgba(255, 255, 255, 0.9);
                border-radius: 8px;
                padding: 20px;
                z-index: 1000000;
                display: flex;
                flex-direction: column;
                box-shadow: 0 0 15px rgba(0,0,0,0.3);
                font-family: Arial, sans-serif;
            `;
            document.body.appendChild(overlay);
            const titleRow = document.createElement('div');
            titleRow.style.cssText = 'width: 100%; display: flex; justify-content: space-between; margin-bottom: 10px;';
            const titleH2 = document.createElement('h2');
            titleH2.textContent = 'Skin Switcher';
            titleH2.style.margin = '0';
            titleRow.appendChild(titleH2);
            const closeBtn = document.createElement('button');
            closeBtn.textContent = 'X';
            closeBtn.style.cssText = `
                background-color: #00d3ff;
                border: 1px solid #ff0000;
                color: #ff0000;
                font-size: 20px;
                font-weight: bold;
                cursor: pointer;
                padding: 0 8px;
                border-radius: 4px;
                transition: background-color 0.2s ease;
            `;
            closeBtn.onclick = () => {
                overlay.style.display = 'none';
            };
            titleRow.appendChild(closeBtn);
            overlay.appendChild(titleRow);
            const previewContainer = document.createElement('div');
            previewContainer.style.cssText = `
                position: relative;
                width: 200px;
                height: 200px;
                border-radius: 50%;
                overflow: hidden;
                margin: 10px auto 0 auto;
                display: flex;
                align-items: center;
                justify-content: center;
                background: #f0f0f0;
            `;
            overlay.appendChild(previewContainer);
            const previewImg = document.createElement('img');
            previewImg.style.cssText = `
                width: 100%;
                height: 100%;
                object-fit: cover;
            `;
            previewContainer.appendChild(previewImg);
            const arrowsContainer = document.createElement('div');
            arrowsContainer.style.cssText = `
                display: flex;
                justify-content: space-between;
                align-items: center;
                width: 200px;
                margin: 10px auto 0 auto;
            `;
            overlay.appendChild(arrowsContainer);
            const leftArrow = document.createElement('button');
            leftArrow.textContent = '◀';
            leftArrow.style.cssText = arrowButtonStyle();
            leftArrow.addEventListener('mouseover', () => {
                leftArrow.style.backgroundColor = '#347f01';
            });
            leftArrow.addEventListener('mouseout', () => {
                leftArrow.style.backgroundColor = '#54c800';
            });
            leftArrow.addEventListener('mousedown', () => {
                leftArrow.style.backgroundColor = '#347f01';
            });
            leftArrow.addEventListener('mouseup', () => {
                leftArrow.style.backgroundColor = '#54c800';
            });
            arrowsContainer.appendChild(leftArrow);
            const rightArrow = document.createElement('button');
            rightArrow.textContent = '▶';
            rightArrow.style.cssText = arrowButtonStyle();
            rightArrow.addEventListener('mouseover', () => {
                rightArrow.style.backgroundColor = '#347f01';
            });
            rightArrow.addEventListener('mouseout', () => {
                rightArrow.style.backgroundColor = '#54c800';
            });
            rightArrow.addEventListener('mousedown', () => {
                rightArrow.style.backgroundColor = '#347f01';
            });
            rightArrow.addEventListener('mouseup', () => {
                rightArrow.style.backgroundColor = '#54c800';
            });
            arrowsContainer.appendChild(rightArrow);
            const skinUrlLabel = document.createElement('div');
            skinUrlLabel.style.cssText = 'margin-top: 10px; text-align: center; font-style: italic; color: #333;';
            overlay.appendChild(skinUrlLabel);
            const urlInput = document.createElement('input');
            urlInput.type = 'text';
            urlInput.placeholder = 'https://i.imgur.com/skin.png';
            urlInput.style.cssText = `
                margin: 10px auto 0 auto;
                width: 80%;
                padding: 5px;
                border: 1px solid #ccc;
                border-radius: 3px;
                display: block;
            `;
            overlay.appendChild(urlInput);
            const buttonsContainer = document.createElement('div');
            buttonsContainer.style.cssText = 'display: flex; justify-content: space-around; margin-top: 10px;';
            overlay.appendChild(buttonsContainer);
            const addSkinBtn = document.createElement('button');
            addSkinBtn.textContent = 'Add Skin';
            addSkinBtn.style.cssText = buttonStyle();
            addSkinBtn.onclick = addSkin;
            buttonsContainer.appendChild(addSkinBtn);
            const useSkinBtn = document.createElement('button');
            useSkinBtn.textContent = 'Use This Skin';
            useSkinBtn.style.cssText = buttonStyle();
            useSkinBtn.onclick = useSkin;
            buttonsContainer.appendChild(useSkinBtn);
            const deleteSkinBtn = document.createElement('button');
            deleteSkinBtn.textContent = 'Delete Skin';
            deleteSkinBtn.style.cssText = `
                padding: 6px 12px;
                border: none;
                border-radius: 4px;
                background-color: #ff0000;
                color: #fff;
                cursor: pointer;
                transition: background-color 0.2s ease;
            `;
            deleteSkinBtn.addEventListener('mouseover', () => {
                deleteSkinBtn.style.backgroundColor = '#cc0000';
            });
            deleteSkinBtn.addEventListener('mouseout', () => {
                deleteSkinBtn.style.backgroundColor = '#ff0000';
            });
            deleteSkinBtn.addEventListener('mousedown', () => {
                deleteSkinBtn.style.backgroundColor = '#cc0000';
            });
            deleteSkinBtn.addEventListener('mouseup', () => {
                deleteSkinBtn.style.backgroundColor = '#ff0000';
            });
            deleteSkinBtn.onclick = deleteSkin;
            buttonsContainer.appendChild(deleteSkinBtn);
            let skins = loadSkinsFromStorage();
            let currentIndex = 0;
            function renderSkins() {
                if (skins.length === 0) {
                    currentIndex = 0;
                    previewImg.src = '';
                    skinUrlLabel.textContent = 'No skins yet';
                } else {
                    if (currentIndex >= skins.length) currentIndex = skins.length - 1;
                    if (currentIndex < 0) currentIndex = 0;
                    previewImg.src = skins[currentIndex];
                    skinUrlLabel.textContent = skins[currentIndex];
                }
            }
            leftArrow.onclick = () => {
                if (skins.length > 0) {
                    currentIndex = (currentIndex - 1 + skins.length) % skins.length;
                    renderSkins();
                }
            };
            rightArrow.onclick = () => {
                if (skins.length > 0) {
                    currentIndex = (currentIndex + 1) % skins.length;
                    renderSkins();
                }
            };
            function addSkin() {
                const url = urlInput.value.trim();
                if (!url) return;
                skins.push(url);
                saveSkinsToStorage(skins);
                urlInput.value = '';
                currentIndex = skins.length - 1;
                renderSkins();
            }
            function useSkin() {
                if (!skins[currentIndex]) {
                    alert('No skin selected!');
                    return;
                }
                applyCustomSkin(skins[currentIndex]);
                overlay.style.display = 'none';
            }
            function deleteSkin() {
                if (skins.length === 0) {
                    alert('No skins to delete!');
                    return;
                }
                if (confirm('Are you sure you want to delete this skin?')) {
                    skins.splice(currentIndex, 1);
                    saveSkinsToStorage(skins);
                    if (currentIndex >= skins.length) {
                        currentIndex = skins.length - 1;
                    }
                    renderSkins();
                }
            }
            function arrowButtonStyle() {
                return `
                    font-size: 24px;
                    width: 40px;
                    height: 40px;
                    border-radius: 8px;
                    cursor: pointer;
                    border: none;
                    background: #54c800;
                    color: #fff;
                    transition: background-color 0.2s ease;
                `;
            }
            function buttonStyle() {
                return `
                    padding: 6px 12px;
                    border: none;
                    border-radius: 4px;
                    background-color: #54c800;
                    color: #fff;
                    cursor: pointer;
                    transition: background-color 0.2s ease;
                `;
            }
            renderSkins();
        }

        function createMainOverlay() {
            mainOverlay = document.createElement('div');
            mainOverlay.id = 'main-overlay';
            mainOverlay.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 700px;
                max-width: 90%;
                background: #fff;
                border-radius: 8px;
                padding: 20px;
                z-index: 999999;
                display: block;
                box-shadow: 0 0 20px rgba(0,0,0,0.5);
                font-family: Arial, sans-serif;
            `;
            document.body.appendChild(mainOverlay);
            const titleBar = document.createElement('div');
            titleBar.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;';
            const h2 = document.createElement('h2');
            h2.textContent = 'Advanced Controls';
            h2.style.margin = '0';
            titleBar.appendChild(h2);
            const closeBtn = document.createElement('button');
            closeBtn.textContent = 'X';
            closeBtn.style.cssText = `
                background-color: #00d3ff;
                border: 1px solid #ff0000;
                color: #ff0000;
                font-size: 18px;
                font-weight: bold;
                cursor: pointer;
                padding: 0 8px;
                border-radius: 4px;
                transition: background-color 0.2s ease;
            `;
            closeBtn.onclick = toggleMainOverlay;
            titleBar.appendChild(closeBtn);
            mainOverlay.appendChild(titleBar);
            const mouseActionsContainer = document.createElement('div');
            mouseActionsContainer.style.cssText = 'display: flex; flex-direction: column; gap: 5px; margin-bottom: 10px;';
            mouseActionsContainer.appendChild(createMouseActionRow('Left Mouse Action', 'leftMouseAction'));
            mouseActionsContainer.appendChild(createMouseActionRow('Right Mouse Action','rightMouseAction'));
            mainOverlay.appendChild(mouseActionsContainer);
            mainOverlay.appendChild(document.createElement('hr'));
            const columnsDiv = document.createElement('div');
            columnsDiv.style.cssText = 'display: flex; gap: 20px; margin-top: 10px;';
            const pcCol = document.createElement('div');
            pcCol.style.cssText = 'flex:1; background: rgba(255,255,255,0.6); padding: 10px; border-radius: 5px;';
            pcCol.innerHTML = '<h3>PC Hotkeys</h3>';
            const pcHotkeysDiv = document.createElement('div');
            pcCol.appendChild(pcHotkeysDiv);
            columnsDiv.appendChild(pcCol);
            const gpCol = document.createElement('div');
            gpCol.style.cssText = 'flex:1; background: rgba(255,255,255,0.6); padding: 10px; border-radius: 5px;';
            gpCol.innerHTML = '<h3>Gamepad</h3>';
            const gpDiv = document.createElement('div');
            gpCol.appendChild(gpDiv);
            columnsDiv.appendChild(gpCol);
            mainOverlay.appendChild(columnsDiv);
            const bottomDiv = document.createElement('div');
            bottomDiv.style.cssText = 'margin-top: 20px; display: flex; flex-wrap: wrap; gap: 10px;';
            const toggleModBtn = document.createElement('button');
            toggleModBtn.textContent = CONFIG.enableMod ? 'Disable Mod' : 'Enable Mod';
            toggleModBtn.style.cssText = buttonStyle();
            toggleModBtn.onclick = () => {
                CONFIG.enableMod = !CONFIG.enableMod;
                toggleModBtn.textContent = CONFIG.enableMod ? 'Disable Mod' : 'Enable Mod';
                if (!CONFIG.enableMod) {
                    stopMacroFeed();
                    isStraightLineMode = false;
                }
            };
            bottomDiv.appendChild(toggleModBtn);
            const acidBtn = document.createElement('button');
            acidBtn.textContent = CONFIG.enableAcidMode ? 'Acid Mode: ON' : 'Acid Mode: OFF';
            acidBtn.style.cssText = buttonStyle();
            acidBtn.onclick = () => {
                toggleAcidMode();
                acidBtn.textContent = CONFIG.enableAcidMode ? 'Acid Mode: ON' : 'Acid Mode: OFF';
            };
            bottomDiv.appendChild(acidBtn);
            const skinBtn = document.createElement('button');
            skinBtn.textContent = 'Change Skin';
            skinBtn.style.cssText = buttonStyle();
            skinBtn.onclick = openSkinSwitcherUI;
            bottomDiv.appendChild(skinBtn);
            const pauseBtn = document.createElement('button');
            pauseBtn.textContent = 'Pause Movement';
            pauseBtn.style.cssText = buttonStyle();
            pauseBtn.onclick = () => {
                isPaused = !isPaused;
                pauseBtn.textContent = isPaused ? 'Unpause Movement' : 'Pause Movement';
                showNotification(isPaused ? 'Movement is paused.' : 'Movement unpaused.');
            };
            bottomDiv.appendChild(pauseBtn);
            mainOverlay.appendChild(bottomDiv);
            buildPCHotkeysUI(pcHotkeysDiv);
            buildGamepadUI(gpDiv);
            mainOverlay.style.display = 'none';

            function createMouseActionRow(label, configKey) {
                const row = document.createElement('div');
                row.style.cssText = 'display: flex; align-items: center; margin-bottom: 5px;';
                const lbl = document.createElement('span');
                lbl.textContent = label + ': ';
                lbl.style.width = '150px';
                row.appendChild(lbl);
                const select = document.createElement('select');
                select.style.cssText = `
                    border: 1px solid #777;
                    border-radius: 4px;
                    padding: 2px 4px;
                `;
                const actions = [
                    { value: 'none',       text: 'None' },
                    { value: 'singleFeed', text: 'Single Feed' },
                    { value: 'macroFeed',  text: 'Macro Feed' },
                    { value: 'split',      text: 'Split' }
                ];
                actions.forEach(a => {
                    const opt = document.createElement('option');
                    opt.value = a.value;
                    opt.textContent = a.text;
                    select.appendChild(opt);
                });
                select.value = CONFIG[configKey];
                select.onchange = () => {
                    CONFIG[configKey] = select.value;
                    showNotification(`${label} changed to: ${select.value}`);
                };
                row.appendChild(select);
                return row;
            }
        }

        function toggleMainOverlay() {
            modUIVisible = !modUIVisible;
            mainOverlay.style.display = modUIVisible ? 'block' : 'none';
            showControlsButton.textContent = modUIVisible ? 'Hide Controls' : 'Show Controls';
        }

        function buttonStyle() {
            return `
                padding: 6px 12px;
                font-size: 14px;
                border: none;
                border-radius: 5px;
                cursor: pointer;
                background-color: #54c800;
                color: #fff;
                transition: background-color 0.2s ease;
            `;
        }

        function buildPCHotkeysUI(container) {
            container.appendChild(createHotkeyRow('Single Feed',      'singleFeedKey'));
            container.appendChild(createHotkeyRow('Macro Feed',       'macroFeedKey'));
            container.appendChild(createHotkeyRow('Double Split',     'doubleSplitKey'));
            container.appendChild(createHotkeyRow('Triple Split',     'tripleSplitKey'));
            container.appendChild(createHotkeyRow('Quad Split',       'quadSplitKey'));
            container.appendChild(createHotkeyRow('Straight Line',    'straightLineKey'));
            container.appendChild(createHotkeyRow('Acid Mode',        'acidModeKey'));
            container.appendChild(createHotkeyRow('Skin Switcher',    'skinSwitcherKey'));
            container.appendChild(createHotkeyRow('Toggle UI',        'toggleUIKey'));
            container.appendChild(createHotkeyRow('Zoom Out',         'zoomOutKey'));
            container.appendChild(createHotkeyRow('Zoom In',          'zoomInKey'));
            container.appendChild(createHotkeyRow('Pause Movement',   'pauseMovementKey'));
        }

        function createHotkeyRow(label, configKey) {
            const row = document.createElement('div');
            row.style.cssText = 'display: flex; align-items: center; margin-bottom: 5px;';
            const lbl = document.createElement('span');
            lbl.textContent = label + ': ';
            lbl.style.width = '120px';
            row.appendChild(lbl);
            const input = document.createElement('input');
            input.type = 'text';
            input.readOnly = true;
            input.value = CONFIG[configKey];
            input.style.cssText = `
                width: 50px;
                text-align: center;
                border: 1px solid #777;
                border-radius: 3px;
                background-color: #f0f0f0;
                cursor: pointer;
            `;
            row.appendChild(input);
            let waitingForKey = false;
            input.addEventListener('click', () => {
                waitingForKey = true;
                input.value = '???';
                input.focus();
            });
            input.addEventListener('keydown', (evt) => {
                if (!waitingForKey) return;
                evt.preventDefault();
                evt.stopPropagation();
                const newKey = evt.key.toLowerCase();
                CONFIG[configKey] = newKey;
                input.value = newKey;
                waitingForKey = false;
                showNotification(`${label} changed to: ${newKey.toUpperCase()}`);
            });
            return row;
        }

        function buildGamepadUI(container) {
            const row = document.createElement('div');
            row.style.marginBottom = '10px';
            const label = document.createElement('label');
            label.textContent = 'Gamepad Enabled: ';
            const cb = document.createElement('input');
            cb.type = 'checkbox';
            cb.checked = CONFIG.enableGamepad;
            cb.style.marginLeft = '5px';
            cb.onchange = () => {
                toggleGamepadMode(cb.checked);
            };
            row.appendChild(label);
            row.appendChild(cb);
            container.appendChild(row);
            container.appendChild(createGamepadRow('Split Button',         'gamepadSplit',        CONFIG.gamepadSplit));
            container.appendChild(createGamepadRow('Feed Button',          'gamepadFeed',         CONFIG.gamepadFeed));
            container.appendChild(createGamepadRow('Double Split',         'gamepadDoubleSplit',  CONFIG.gamepadDoubleSplit));
            container.appendChild(createGamepadRow('Triple Split',         'gamepadTripleSplit',  CONFIG.gamepadTripleSplit));
            container.appendChild(createGamepadRow('Acid Mode',            'gamepadAcidMode',     CONFIG.gamepadAcidMode));
            container.appendChild(createGamepadRow('Straight Line',        'gamepadStraightLine', CONFIG.gamepadStraightLine));
        }

        function createGamepadRow(label, configKey, defaultVal) {
            const row = document.createElement('div');
            row.style.cssText = 'display: flex; align-items: center; margin-bottom: 5px;';
            const lbl = document.createElement('span');
            lbl.textContent = label + ': ';
            lbl.style.width = '120px';
            row.appendChild(lbl);
            const input = document.createElement('input');
            input.type = 'text';
            input.readOnly = true;
            input.value = `Button ${defaultVal}`;
            input.style.cssText = `
                width: 80px;
                text-align: center;
                border: 1px solid #777;
                border-radius: 3px;
                background-color: #54c800;
                color: #fff;
                cursor: pointer;
                transition: background-color 0.2s ease;
            `;
            input.addEventListener('mouseover', () => {
                input.style.backgroundColor = '#347f01';
            });
            input.addEventListener('mouseout', () => {
                input.style.backgroundColor = '#54c800';
            });
            input.addEventListener('mousedown', () => {
                input.style.backgroundColor = '#347f01';
            });
            input.addEventListener('mouseup', () => {
                input.style.backgroundColor = '#54c800';
            });
            input.addEventListener('click', () => {
                input.value = "Press Button...";
                input.style.backgroundColor = '#ffee99';
                isRemappingGamepad = true;
                remappingButton = configKey;
                setTimeout(() => {
                    if (input.value === "Press Button...") {
                        input.value = `Button ${CONFIG[configKey]}`;
                        input.style.backgroundColor = '#f0f0f0';
                        isRemappingGamepad = false;
                        remappingButton = null;
                    }
                }, 5000);
            });
            row.appendChild(input);
            return row;
        }

        function setupGamepadSupport() {
            window.addEventListener("gamepadconnected", handleGamepadConnected);
            window.addEventListener("gamepaddisconnected", handleGamepadDisconnected);
            if (CONFIG.enableGamepad) {
                startGamepadPolling();
            }
        }
        function handleGamepadConnected(event) {
            const gamepad = event.gamepad;
            connectedGamepads[gamepad.index] = gamepad;
            console.log(`Gamepad connected at index ${gamepad.index}: ${gamepad.id}`);
            showNotification(`Gamepad connected: ${gamepad.id.split('(')[0]}`);
            if (CONFIG.enableGamepad) {
                startGamepadPolling();
            }
        }
        function handleGamepadDisconnected(event) {
            const gamepad = event.gamepad;
            console.log(`Gamepad disconnected from index ${gamepad.index}: ${gamepad.id}`);
            showNotification('Gamepad disconnected');
            delete connectedGamepads[gamepad.index];
            const hasGamepads = Object.keys(connectedGamepads).length > 0;
            if (!hasGamepads) {
                stopGamepadPolling();
            }
        }
        let gamepadPollingId = null;
        function startGamepadPolling() {
            if (gamepadPollingId === null) {
                gamepadPollingId = setInterval(pollGamepads, 16);
                console.log('Gamepad polling started');
            }
        }
        function stopGamepadPolling() {
            if (gamepadPollingId !== null) {
                clearInterval(gamepadPollingId);
                gamepadPollingId = null;
                console.log('Gamepad polling stopped');
            }
        }
        function toggleGamepadMode(enabled) {
            CONFIG.enableGamepad = enabled;
            if (enabled) {
                startGamepadPolling();
                showNotification('Gamepad mode enabled');
            } else {
                stopGamepadPolling();
                showNotification('Gamepad mode disabled');
            }
        }
        function pollGamepads() {
            if (!CONFIG.enableGamepad) return;
            const gamepads = navigator.getGamepads
                ? navigator.getGamepads()
                : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
            for (let i = 0; i < gamepads.length; i++) {
                const gamepad = gamepads[i];
                if (!gamepad) continue;
                if (!lastGamepadState[gamepad.index]) {
                    lastGamepadState[gamepad.index] = {
                        buttons: Array(gamepad.buttons.length).fill(false),
                        axes: Array(gamepad.axes.length).fill(0)
                    };
                }
                for (let j = 0; j < gamepad.buttons.length; j++) {
                    const isPressed = gamepad.buttons[j].pressed;
                    const wasPressed = lastGamepadState[gamepad.index].buttons[j];
                    if (isPressed && !wasPressed) {
                        handleGamepadButtonPressed(gamepad.index, j);
                    } else if (!isPressed && wasPressed) {
                        handleGamepadButtonReleased(gamepad.index, j);
                    }
                    lastGamepadState[gamepad.index].buttons[j] = isPressed;
                }
                for (let j = 0; j < gamepad.axes.length; j++) {
                    const axisValue = gamepad.axes[j];
                    const prevAxisValue = lastGamepadState[gamepad.index].axes[j];
                    if (Math.abs(axisValue - prevAxisValue) > 0.1) {
                        handleGamepadAxisMoved(gamepad.index, j, axisValue);
                    }
                    lastGamepadState[gamepad.index].axes[j] = axisValue;
                }
            }
            if (isPaused && gameCanvas && window.core) {
                const rect = gameCanvas.getBoundingClientRect();
                const centerX = rect.left + rect.width / 2;
                const centerY = rect.top + rect.height / 2;
                window.core.setTarget(centerX, centerY);
            }
        }
        function handleGamepadButtonPressed(gamepadIndex, buttonIndex) {
            if (isRemappingGamepad) {
                if (remappingButton) {
                    CONFIG[remappingButton] = buttonIndex;
                    showNotification(`Mapped ${remappingButton} to button ${buttonIndex}`);
                    isRemappingGamepad = false;
                    const gpInputs = document.querySelectorAll('input[value="Press Button..."]');
                    for (let i = 0; i < gpInputs.length; i++) {
                        const input = gpInputs[i];
                        if (input.style.backgroundColor === 'rgb(255, 238, 153)') {
                            input.value = `Button ${buttonIndex}`;
                            input.style.backgroundColor = '#f0f0f0';
                            break;
                        }
                    }
                    remappingButton = null;
                }
                return;
            }
            if (!window.core || isPaused) return;
            if (buttonIndex === CONFIG.gamepadSplit) {
                window.core.split();
            }
            else if (buttonIndex === CONFIG.gamepadFeed) {
                window.core.eject();
            }
            else if (buttonIndex === CONFIG.gamepadDoubleSplit) {
                performMultiSplit(2);
            }
            else if (buttonIndex === CONFIG.gamepadTripleSplit) {
                performMultiSplit(3);
            }
            else if (buttonIndex === CONFIG.gamepadAcidMode) {
                toggleAcidMode();
            }
            else if (buttonIndex === CONFIG.gamepadStraightLine) {
                toggleStraightLineMode();
            }
        }
        function handleGamepadButtonReleased() { }
        function handleGamepadAxisMoved(gamepadIndex, axisIndex, value) {
            if (isPaused) return;
            if (axisIndex <= 1 && window.core && gameCanvas) {
                const gamepad = navigator.getGamepads()[gamepadIndex];
                const horizontalAxis = gamepad.axes[0];
                const verticalAxis = gamepad.axes[1];
                const deadzone = 0.15;
                let x = Math.abs(horizontalAxis) < deadzone ? 0 : horizontalAxis;
                let y = Math.abs(verticalAxis) < deadzone ? 0 : verticalAxis;
                if (Math.abs(x) > 0.1 || Math.abs(y) > 0.1) {
                    const rect = gameCanvas.getBoundingClientRect();
                    const centerX = rect.left + rect.width / 2;
                    const centerY = rect.top + rect.height / 2;
                    const sensitivity = 200;
                    const targetX = centerX + (x * sensitivity);
                    const targetY = centerY + (y * sensitivity);
                    window.core.setTarget(targetX, targetY);
                }
            }
        }

        function toggleAcidMode() {
            if (!window.core) return;
            CONFIG.enableAcidMode = !CONFIG.enableAcidMode;
            window.core.setAcid(CONFIG.enableAcidMode);
            const acidButtons = document.querySelectorAll('button');
            for (let i = 0; i < acidButtons.length; i++) {
                if (acidButtons[i].textContent.includes('Acid Mode')) {
                    acidButtons[i].textContent = CONFIG.enableAcidMode ? 'Acid Mode: ON' : 'Acid Mode: OFF';
                }
            }
            showNotification(CONFIG.enableAcidMode ? 'Acid mode: ON' : 'Acid mode: OFF');
        }

        function checkCoreAccess() {
            if (typeof window.core === 'undefined') {
                console.log('Waiting for core functions to load...');
                setTimeout(checkCoreAccess, 1000);
                return;
            }
            console.log('Core functions found!');
            if (CONFIG.enableMinimap && window.core) {
                window.core.setMinimap(true);
                window.core.minimizeMinimap(false);
                window.core.playersMinimap(true);
            }
            if (CONFIG.enableAcidMode && window.core) {
                window.core.setAcid(true);
            }
            setupGamepadSupport();
        }

        initMod();
        checkCoreAccess();
    }

    //------------------------------------------------------------------
    // 4) "Skin Maker" with Drag-and-Drop
    //------------------------------------------------------------------
    function convertImageFileToBase64(file) {
        const reader = new FileReader();
        reader.onloadend = function () {
            const base64 = reader.result;
            drawImage(base64);
        };
        reader.readAsDataURL(file);
    }
    function convertImageToBase64(event) {
        const file = event.target.files[0];
        if (file) {
            convertImageFileToBase64(file);
        }
    }
    function drawImage(base64) {
        const canvas = document.getElementById("skin-editor-canvas");
        if (!canvas) {
            console.warn("No skin-editor-canvas found to draw on!");
            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;
    }
    function createImageButton() {
        const container = document.createElement("div");
        container.style.position = "relative";
        container.style.display = "inline-block";
        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";
        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";
        container.appendChild(input);
        container.appendChild(button);
        input.addEventListener("change", convertImageToBase64);
        return container;
    }
    function createDragAndDropZone() {
        const dropZone = document.createElement('div');
        dropZone.id = 'dropZone';
        dropZone.style.border = "2px dashed #ccc";
        dropZone.style.padding = "10px";
        dropZone.style.marginTop = "10px";
        dropZone.style.textAlign = "center";
        dropZone.textContent = "Drag & drop your image file here";
        dropZone.addEventListener("dragover", (e) => {
            e.preventDefault();
            dropZone.style.backgroundColor = "#ddd";
        });
        dropZone.addEventListener("dragleave", (e) => {
            e.preventDefault();
            dropZone.style.backgroundColor = "";
        });
        dropZone.addEventListener("drop", (e) => {
            e.preventDefault();
            dropZone.style.backgroundColor = "";
            const file = e.dataTransfer.files[0];
            if (file && file.type.startsWith("image/")) {
                convertImageFileToBase64(file);
            } else {
                alert("Please drop an image file only!");
            }
        });
        return dropZone;
    }
    function insertImageButtonAndDropZone(container, target) {
        if (target) {
            const newDiv = document.createElement("div");
            newDiv.style.marginTop = "50px";
            newDiv.appendChild(container);
            const dropZone = createDragAndDropZone();
            newDiv.appendChild(dropZone);
            const saveArea = target.querySelector(".save");
            if (saveArea) {
                saveArea.appendChild(newDiv);
            }
        }
    }
    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(".save")) {
                        if (
                            !target.querySelector("#customImageUpload") &&
                            !target.querySelector("#dropZone")
                        ) {
                            const button = createImageButton();
                            insertImageButtonAndDropZone(button, target);
                        }
                    }
                }
            }
        });
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    //------------------------------------------------------------------
    // 5) Russia -> Ukraine Replacement
    //------------------------------------------------------------------
    function initRussiaToUkraine() {
        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
        });
    }
})();