Slither.io - 607ch00 remix

slither.io MOD - High score, Custom backgrounds, Zoom, Clock, and more!

当前为 2016-04-26 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Slither.io - 607ch00 remix
// @namespace    slitherio.remix.607ch00
// @version      0.6.9.10
// @description  slither.io MOD - High score, Custom backgrounds, Zoom, Clock, and more!
// @author       607ch00
// @match        http://slither.io/*
// @noframes
// @run-at       document-body
// @grant        none
// ==/UserScript==
/*jshint multistr: true */
(function(w) {
    var modVersion = 'v0.6.9.10', //used in menu box
        graphicsMode = '4', //4 - customized high quality 3 - high quality, 2 - simple optimized, 1 - simple (mobile)
        graphicsModeChanged = true, //flag to indicate graphics mode has changed
        statsContainer = null, //reference to stats container
        fpsContainer = null, //reference to fps div
        xferContainer = null, //refernce to current transfer rate div
        zoomContainer = null, //reference to zoom div
        positionContainer = null, //reference to coordinates div
        ipContainer = null, //reference to current/last connected server div
        highscoreContainer = null, //reference to high score display
        clockContainer = null, //reference to clock container
        backgroundImage = -1, //store the user selected background image
        randomizeBackground = false, //indicate whether or not to randomize background
        originalBackground = null, //store the game's default background image
        originalBackgroundCanvas = null, //store the game's default background canvas object
        backgroundImageChanged = true, //indicate if background image needs to be set
        clearedGlow = false, //store whether glow was attempted to be cleared
        highScore = 0, //store the user's current high score
        currentIP = null, //store the current connected server ip
        selectedServer = -1, //store the user selected server ip
        manualServer = false, //store user manual server entry
        connectButtonOverride = false, //store whether the connect button click listener was overridden
        connectButton = null,  //reference to the connect button
        retry = 0; //hold the current number of connection retries

    /**
     * Init script
     */
    function init() {
        createCSS();

        stopLogoAnimation();

        statsContainer = document.createElement('div');
        statsContainer.id = 'stats-container';
        statsContainer.innerHTML = ' \
            <div id="fps-container"></div> \
            <div id="xfer-container"></div> \
            <div id="zoom-container"></div> \
            <div id="position-container"></div> \
            <div id="ip-container"></div> \
            <div id="highscore-container"></div> \
            <div id="clock-container"></div> \
        ';
        document.body.appendChild(statsContainer);

        fpsContainer = document.getElementById('fps-container');
        xferContainer = document.getElementById('xfer-container');
        zoomContainer = document.getElementById('zoom-container');
        positionContainer = document.getElementById('position-container');
        ipContainer = document.getElementById('ip-container');
        highscoreContainer = document.getElementById('highscore-container');
        clockContainer = document.getElementById('clock-container');

        // Add zoom
        if (/firefox/i.test(navigator.userAgent)) {
            document.addEventListener('DOMMouseScroll', zoom, false);
        } else {
            document.body.onmousewheel = zoom;
        }

        //Setup keyboard shortcuts
        w.onkeydown = function(e) {
            switch (e.keyCode) {
                //Toggle stats (tab)
                case 9:
                    e.preventDefault();
                    toggleStats();
                    break;
                //Respawn (escape)
                case 27:
                    customConnect();
                    break;
                //Disconnect (q)
                case 81:
                    disconnect();
                    break;
                //Reset zoom (~ tilde)
                case 192:
                    resetZoom();
                    break;
            }
        };

        // Set menu
        setupMenu();
        // Override play button behavior
        customConnectButton();
        // Setup graphics
        setupGraphics();
        // Update loop
        updateLoop();
        // Show FPS
        showFPS();
    }

    /**
     * Prevent laggy logo animation
     */
    function stopLogoAnimation() {
        if (typeof w.showlogo_iv !== 'undefined') {
            w.ncka = w.lgss = w.lga = 1;
            clearInterval(w.showlogo_iv);
            showLogo(!0);
        } else {
            setTimeout(stopLogoAnimation, 25);
        }
    }

    /**
     * Create stylesheet in head
     */
    function createCSS() {
        var styleElement = document.createElement('style');
        document.getElementsByTagName('head')[0].appendChild(styleElement);
        styleElement.type = 'text/css';

        var cssString = ' \
            body { \
                background-color: #000!important; \
                overflow-x:hidden; \
            } \
            #nbg { \
                display:none; \
                visibility:hidden; \
            } \
            #clq { \
                bottom:0!important; \
                height:auto!important; \
            } \
            #grqh { \
                top: auto!important; \
                right: auto!important; \
                bottom: 20px; \
                left: 150px; \
            } \
            #login { \
                /* margin-top:0!important; */ \
                position:relative!important; \
                width:auto!important; \
                height:auto!important; \
            } \
            #logo { \
                /* margin-top:30px!important; */ \
            } \
            #stats-container { \
                position:fixed; \
                right: 30px; \
                bottom: 120px; \
                opacity: 0.35; \
                z-index: 7; \
                color: #FFF; \
                font: 14px Arial, Helvetica Neue, Helvetica, sans-serif; \
                text-align: right; \
            } \
            #custom-menu-container { \
                width:260px; \
                color:#8058D0; \
                background-color:#1E262E; \
                border-radius:29px; \
                font: 14px Lucida Sans Unicode, Lucida Grande, sans-serif; \
                text-align:center; \
                margin: 20px auto 0; \
                padding:10px 14px; \
            } \
            .custom-select-container { \
                background-color:#A5A5A5; \
                border-radius:10px; \
                margin:5px auto; \
                padding:5px 0; \
            } \
            .custom-select-container select { \
                width:100%; \
                background:none; \
                border:none; \
                outline:none; \
            } \
            #server-manual-input { \
                width: 100%; \
                display:none; \
            } \
            #hotkey-help { \
                margin:0; \
                padding:0; \
                display:flex; \
                flex-wrap:wrap; \
            } \
            #hotkey-help li { \
                display:inline; \
                white-space:nowrap; \
                flex-grow:1; \
            } \
            #clock-container { \
                font-weight:900; \
                font: 14px Courier New, Courier, monospace; \
            } \
        ';

        if (styleElement.styleSheet) {
            styleElement.styleSheet.cssText = cssString;
        } else {
            styleElement.appendChild(document.createTextNode(cssString));
        }
    }

    /**
     * Toggle display of stats window
     */
    function toggleStats() {
        if (statsContainer.style.display == 'none') {
            statsContainer.style.display = 'block';
        } else {
            statsContainer.style.display = 'none';
        }
    }

    /**
     * Calculate zoom from mousewheel
     */
    function zoom(e) {
        if (!w.gsc || !w.playing) {
            return;
        }

        w.gsc *= Math.pow(0.9, e.wheelDelta / -120 || e.detail / 2 || 0);

        zoomContainer.textContent = 'Zoom: ' + w.gsc.toFixed(2);
    }

    /**
     * Reset zoom to default level
     */
    function resetZoom() {
        w.gsc = 0.9;

        zoomContainer.textContent = 'Zoom: ' + w.gsc.toFixed(2);
    }

    /**
     * Setup main menu
     */
    function setupMenu() {
        var login = document.getElementById('login');
        var playButtonContainer = document.getElementById('playh');
        if (playButtonContainer) {
            // Load settings
            loadSettings();

            //Create container
            var menuContainer = document.createElement('div');
            menuContainer.id = 'custom-menu-container';
            menuContainer.innerHTML = '\
                <div class="custom-select-container"> \
                    <select id="server-select"> \
                        <option value="-1">Server: Default Closest</option> \
                        <option value="-2">Server: Random</option> \
                        <option value="-3">Server: Manual Input</option> \
                    </select> \
                    <input type"text" id="server-manual-input"> \
                </div> \
                <div class="custom-select-container"> \
                    <select id="graphics-select"> \
                        <option value="4">Graphics: customized</option> \
                        <option value="3">Graphics: normal</option> \
                        <option value="2">Graphics: no background</option> \
                        <option value="1">Graphics: low</option> \
                    </select> \
                </div> \
                <div class="custom-select-container" id="background-select-container"> \
                    <select id="background-select"> \
                        <option value="-2">Background Image: Random</option> \
                        <option value="-1">Background Image: Default</option> \
                        <option value="http://i.imgur.com/YioXLYV.jpg">Grid</option> \
                        <option value="http://i.imgur.com/Iffij8a.jpg">Cats</option> \
                        <option value="http://i.imgur.com/jYFIA9J.jpg">Dirt</option> \
                        <option value="http://i.imgur.com/wQIghye.jpg">Grass</option> \
                        <option value="http://i.imgur.com/HVnFfK9.jpg">Magma Storm</option> \
                        <option value="http://i.imgur.com/HaxzRtX.jpg">Wood</option> \
                        <option value="http://i.imgur.com/kQvgICX.jpg">Stonewall</option> \
                        <option value="http://i.imgur.com/bwfU0Qr.jpg">Hungry Like Wolf</option> \
                        <option value="http://i.imgur.com/TyKD6Ie.png">Shaq-fu</option> \
                    </select> \
                </div> \
                <ul id="hotkey-help"> \
                    <li>[Mousewheel] Zoom</li> \
                    <li>[~] Reset Zoom</li> \
                    <li>[ESC] Respawn</li> \
                    <li>[Q]uit Game</li> \
                    <li>[TAB] Toggle Stats</li> \
                </ul> \
                <strong>607ch00 remix</strong> | <strong>' + modVersion + '</strong> \
            ';

            login.insertBefore(menuContainer, playButtonContainer);

            //Capture and store nickname
            var nick = document.getElementById('nick');
            nick.addEventListener("input", getNick, false);

            //Set graphics mode
            var selectGraphics = document.getElementById('graphics-select');
            selectGraphics.value = graphicsMode;
            toggleBackgroundSelect();

            selectGraphics.onchange = function() {
                var mode = selectGraphics.value;
                if (mode) {
                    graphicsMode = mode;
                    w.localStorage.setItem('graphics-mode', graphicsMode);
                    toggleBackgroundSelect();
                    graphicsModeChanged = true;
                    backgroundImageChanged = true;
                    if (graphicsMode != '4') {
                        randomizeBackground = false;
                    } else {
                        if (w.localStorage.getItem('background-image') == '-2') {
                            randomizeBackground = true;
                        }
                    }
                }
            };

            var selectBackground = document.getElementById('background-select');
            if (selectBackground) {
                selectBackground.value = backgroundImage;
            }
            selectBackground.onchange = function() {
                backgroundImage = selectBackground.value;
                w.localStorage.setItem('background-image', backgroundImage);
                graphicsModeChanged = true;
                backgroundImageChanged = true;
                randomizeBackground = (backgroundImage == '-2') ? true : false;
            };

            getServersList();

            var selectServer = document.getElementById('server-select');
            var inputServerManual = document.getElementById('server-manual-input');

            if (selectedServer) {
                selectServer.value = selectedServer;
                inputServerManual.style.display = (selectedServer === '-3') ? 'block' : 'none';
            }

            if (manualServer && manualServer !== 'false') {
                inputServerManual.value = manualServer;
            }

            selectServer.onchange = function() {
                selectedServer = selectServer.value;

                if (selectedServer === '-3') {
                    inputServerManual.style.display = 'block';
                    inputServerManual.focus();
                } else {
                    inputServerManual.style.display = 'none';
                }
                
                w.localStorage.setItem('server-selected', selectedServer);
            };

            inputServerManual.onchange = function() {
                manualServer = inputServerManual.value;
                w.localStorage.setItem('server-manual', manualServer);
            };

            //Move this out of the way
            document.body.appendChild(document.getElementById('nbg'));

            resizeView();
        } else {
            setTimeout(setupMenu, 100);
        }
    }

    /**
     * Validate IP address format
     */
    function validIP (ip) {
        return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ip);
    }

    /**
     * Toggle availablility of background image selection based on graphics mode
     */
    function toggleBackgroundSelect() {
        if (graphicsMode == '4') {
            document.getElementById('background-select-container').style.display = 'block';
        } else {
            document.getElementById('background-select-container').style.display = 'none';
        }
    }

    /**
     * Select a random background when the game loads
     */
    function randomBackground() {
        var selectBackground = document.getElementById('background-select');
        var backgroundOptions = selectBackground.getElementsByTagName('option');
        var randomSelection = Math.floor(Math.random() * (backgroundOptions.length-1))+1;
        backgroundImage = backgroundOptions[randomSelection].value;
        backgroundImageChanged = true;
    }

    /**
     * Load settings from browser local storage
     */
    function loadSettings() {
        //Enable skins
        localStorage.setItem('edttsg', 1);

        if (w.localStorage.getItem('nick') !== null) {
            var nick = w.localStorage.getItem('nick');
            document.getElementById('nick').value = nick;
        }

        if (w.localStorage.getItem('high-score') !== null) {
             highScore = parseInt(w.localStorage.getItem('high-score'));
             highscoreContainer.textContent = 'Hi Score: ' + highScore;
        }

        if (w.localStorage.getItem('graphics-mode') !== null) {
            var mode = parseInt(w.localStorage.getItem('graphics-mode'));
            if (mode >= 1 && mode <= 4) {
                graphicsMode = mode;
            }
        } else {
            w.localStorage.setItem('graphics-mode', '4');
        }

        if (w.localStorage.getItem('background-image') !== null) {
            backgroundImage = w.localStorage.getItem('background-image');
            randomizeBackground = (backgroundImage == '-2' && graphicsMode == '4') ? true : false;
        } else {
            w.localStorage.setItem('background-image', '-2');
        }

        if (w.localStorage.getItem('server-selected') !== null) {
            selectedServer = w.localStorage.getItem('server-selected');
        } else {
            w.localStorage.setItem('server-selected', selectedServer);
        }

        if (w.localStorage.getItem('server-manual') !== null) {
            manualServer = w.localStorage.getItem('server-manual');
        } else {
            w.localStorage.setItem('server-manual', false);
        }
    }

    /**
     * Get and store user's nickname
     */
    function getNick() {
        var nick = document.getElementById('nick').value;
        w.localStorage.setItem('nick', nick);
    }

    /**
     * Generate select list of game servers available
     */
    function getServersList() {
        if (w.sos && w.sos.length > 0) {
            var selectSrv = document.getElementById('server-select');
            for (var i = 0; i < sos.length; i++) {
                var srv = sos[i];
                var option = document.createElement('option');
                var serverLoopString = option.value = srv.ip + ':' + srv.po;
                option.text = (i + 1) + '. ' + option.value;
                selectSrv.appendChild(option);
            }
        } else {
            setTimeout(getServersList, 100);
        }
    }

    /**
     * Override default connect button behavior to use custom server lists
     */
    function customConnectButton() {
        connectBtn = document.getElementById('playh').getElementsByClassName('btnt')[0];
        if (connectBtn && !connectButtonOverride) {
            // Force connect
            connectBtn.onclick = customConnect;
        } else {
            setTimeout(customConnectButton, 50);
        }
    }

    /**
     * Custom connection function to allow for selection of server ip, random or default behavior
     */
    function customConnect() {
        if (!w.connect) {
            return;
        }

        if (!connectBtn.disabled) {
            connectBtn.disabled = true;
        } else {
            return false;
        }

        if (randomizeBackground) {
            randomBackground();
        }

        if (selectedServer != '-1') {
            w.forcing = true;
            if (!w.bso) {
                w.bso = {};
            }
        }

        if (selectedServer == '-3') {
            //double check custom server entry
            manualServer = document.getElementById('server-manual-input').value;
            w.localStorage.setItem('server-manual', manualServer);

            var srv = manualServer.trim().split(':');

            if (validIP(srv[0])) {
                w.bso.ip = srv[0];
                w.bso.po = srv[1];
            } else {
                alert('The custom server you entered does not have a valid IP address format');
                document.getElementById('server-manual-input').focus();
                return false;
            }
        } else if (selectedServer == '-2') {
            var connectToServer = w.sos[Math.floor(Math.random()*w.sos.length)];
            w.bso.ip = connectToServer.ip;
            w.bso.po = connectToServer.po;
            selectedServer = connectToServer.ip + ':' + connectToServer.po;
            var selectSrv = document.getElementById('server-select').value = selectedServer;
        } else if (selectedServer != '-1') {
            var srv = selectedServer.trim().split(':');
            w.bso.ip = srv[0];
            w.bso.po = srv[1];
        }

        w.connect();
        setTimeout(connectionStatus, 1000);
    }

    /**
     * Loop to force retry of connection
     */
    function connectionStatus() {
        if (!w.connecting || retry == 10) {
            w.forcing = false;
            retry = 0;
            connectBtn.disabled = false;
            return;
        }
        retry++;
        setTimeout(connectionStatus, 1000);
    }

    /**
     * Force disconnect from game and return to menu
     */
    function disconnect() {
        if (w.playing) {
            w.want_close_socket = -1;
            w.dead_mtm = Date.now() - 5E3;
            w.ws.close();
            w.ws = null;
            w.playing = !1;
            w.connected = !1;
            w.resetGame();
            w.play_btn.setEnabled(!0);
        }
    }

    /**
     * Set up graphics mode
     */
    function setupGraphics() {
        //Store original background image
        if ((!originalBackground || !originalBackgroundCanvas) && w.bgp2 && w.ii) {
            originalBackground = w.ii.src;
            originalBackgroundCanvas = w.bgp2;
        }

        //Handle game graphics quality if needed
        if (graphicsModeChanged) {
            if (graphicsMode == '3') {
                w.grqi.style.display = 'block';
                w.grqi.src = '/s/highquality.png';

                w.want_quality = 1;
                w.localStorage.setItem('qual', '1');

                if (typeof w.high_quality !== 'undefined') {
                    w.high_quality = true;
                }

                //Global alpha
                if (w.gla) {
                    w.gla = 1;
                }

                if (typeof w.render_mode !== 'undefined') {
                    w.render_mode = 2;
                }
            } else {
                if (graphicsMode == '4') {
                    w.grqi.style.display = 'none';
                } else {
                    w.grqi.style.display = 'block';
                    w.grqi.src = '/s/lowquality.png';
                }

                w.want_quality = 0;
                w.localStorage.setItem('qual', '0');

                if (typeof w.high_quality !== 'undefined') {
                    w.high_quality = false;
                }

                //Global alpha
                if (w.gla) {
                    w.gla = 0;
                }

                //Snake rendering
                if (typeof w.render_mode !== 'undefined') {
                    if (graphicsMode == '4') {
                        w.render_mode = 2;
                    } else {
                        w.render_mode = parseInt(graphicsMode);
                    }
                }
            }

            graphicsModeChanged = false;
        }

        //Handle game background change if needed
        if (backgroundImageChanged && typeof w.bgp2 !== 'undefined' && typeof w.ii !== 'undefined') {
            //Customized high quality
            if (graphicsMode == '4') {
                clearGlow();

                if (w.bgp2) {
                    w.bgp2 = originalBackgroundCanvas;
                }

                if (w.ii) {
                    if (backgroundImage != '-1') {
                        w.ii.src = backgroundImage;
                    } else {
                        w.ii.src = originalBackground;
                    }
                }
            //Default quality
            } else if (graphicsMode == '3') {
                if (w.ggbg && w.gbgmc) {
                    w.ggbg = true;
                }
                if (w.bgp2) {
                    w.bgp2 = originalBackgroundCanvas;
                }
                if (w.ii) {
                    w.ii.src = originalBackground;
                }
            //Low quality / no background
            } else {
                clearGlow();
                //Background picture
                if (w.bgp2) {
                    w.bgp2 = null;
                }
            }

            backgroundImageChanged = false;
        }
    }

    /**
     * Clear glow from game
     */
    function clearGlow() {
        if (w.ggbg) {
            w.ggbg = false;
        }
        if (clearedGlow) {
            return;
        } else if (w.gbgi && !clearedGlow) {
            w.gbgi.src = '';
            w.gbgi.onload = null;
            w.gbgi = null;
            if (w.gbgmc) {
                w.gbgmc = null;
            }
            clearedGlow = true;
        } else {
            setTimeout(clearGlow, 50);
        }
    }

    /**
     * Resize the view to the current browser window
     */
    function resizeView() {
        if (w.resize) {
            w.lww = 0; // Reset width (force resize)
            w.wsu = 0; // Clear ad space
            w.resize();
            var wh = Math.ceil(w.innerHeight);
            if (wh < 800) {
                var login = document.getElementById('login');
                w.lgbsc = wh / 800;
                login.style.top = - (Math.round(wh * (1 - w.lgbsc) * 1E5) / 1E5) + 'px';
                if (w.trf) {
                    w.trf(login, 'scale(' + w.lgbsc + ',' + w.lgbsc + ')');
                }
            }
        } else {
            setTimeout(resizeView, 100);
        }
    }

    /**
     * Show FPS
     */
    function showFPS() {
        if (w.playing && w.fps && w.lrd_mtm) {
            if (Date.now() - w.lrd_mtm > 970) {
                fpsContainer.textContent = 'FPS: ' + w.fps;
            }
        }
        setTimeout(showFPS, 250);
    }

    /**
     * Update loop for real-time data
     */
    function updateLoop() {
        setupGraphics();

        //testing this
        //w.testing = true;

        if (w.playing) {
            positionContainer.textContent = 'X: ' + (~~w.view_xx || 0) + ' Y: ' + (~~w.view_yy || 0);

            if (w.bso && currentIP != w.bso.ip + ':' + w.bso.po) {
                currentIP = w.bso.ip + ":" + w.bso.po;
                ipContainer.textContent = 'IP: ' + currentIP;
            }

            if (zoomContainer.innerHTML === '') {
                zoomContainer.textContent = 'Zoom: ' + w.gsc.toFixed(2);
            }

            xferContainer.textContent = 'BPS: ' + w.rdps;

            var currentScore = Math.floor(150 * (w.fpsls[w.snake.sct] + w.snake.fam / w.fmlts[w.snake.sct] - 1) - 50) / 10;
            if (currentScore > highScore) {
                highScore = currentScore;
                localStorage.setItem('high-score', highScore);
                highscoreContainer.textContent = 'Hi Score: ' + highScore;
            }
        } else {
            xferContainer.textContent = '';
            fpsContainer.textContent = '';
            zoomContainer.textContent = '';
            positionContainer.textContent = '';
        }

        //Add/update clock
        var now = new Date();
        var hours = now.getHours();
        var minutes = now.getMinutes();
        var seconds = now.getSeconds();
        var timeValue = "" + ((hours > 12) ? hours - 12 : hours);
        timeValue  += ((minutes < 10) ? ':0' : ':') + minutes;
        timeValue  += ((seconds < 10) ? ':0' : ':') + seconds;
        timeValue  += (hours >= 12) ? ' PM' : ' AM';
        clockContainer.textContent = timeValue;

        //Fix this
        if (typeof window.oncontextmenu === 'function') {
            window.oncontextmenu=null;
        }

        setTimeout(updateLoop, 1000);
    }
    // Init
    init();
})(window);