Agma.io Tools - agus123.

Fast eject, Auto Re-spawn, Re-spawn on R, Quick buy, Chat uncensor, and more

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Agma.io Tools - agus123.
// @namespace    http://tampermonkey.net/
// @version      0.9
// @description  Fast eject, Auto Re-spawn, Re-spawn on R, Quick buy, Chat uncensor, and more
// @author       agus123
// @match        agma.io
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let features = [{
        name: "Auto re-spawn",
        enabled: true,
        bootstrap: function() {
            let advert = document.querySelector("#advert")
            let playBtn = document.querySelector("#playBtn");
            let overlays = document.querySelector("#overlays");
            let prevTimeout;
            let muts = [];
            let lastClosed = 0;
            let lastDisplay = "none";

            let closedByDeath = () => Date.now() - lastClosed < 300;
            let triggerPlay = () => {
                if(closedByDeath()) return; // info window was open and closed by dying in the background

                prevTimeout = null;
                window.closeStats();
                playBtn.disabled = false;
                playBtn.click();
            }


            this.load = () => {
                if(muts.length) throw "Auto-respawn feature already loaded";

                muts.push(new MutationObserver(mutations => {
                    for(let mutation of mutations){
                        if(mutation.target.style.display !== lastDisplay){
                            lastDisplay = mutation.target.style.display;

                            if(lastDisplay !== "none"){
                                if(prevTimeout) clearTimeout(prevTimeout);
                                prevTimeout = setTimeout(triggerPlay, 5);
                            }
                        }
                    }
                }))


                muts.push(new MutationObserver(mutations => {
                    for(let mutation of mutations){
                        if(overlays.style.display === "none"){
                            lastClosed = Date.now();
                        }
                    }
                }))

                muts[0].observe(advert, {attributes: true, attributeFilter: ["style"]});
                muts[1].observe(overlays, {attributes: true, attributeFilter: ["style"]});
            }

            this.unload = () => {
                for(let mut of muts){
                    mut.disconnect();
                }
                muts = [];
            }
        }
    },{
        name: "Chat un-censor",
        enabled: true,
        bootstrap: function() {
            let chatBox = document.querySelector("#chtbox");
            let forbiddenWords = ["fuck", "shit", "ass", "dick", "penis", "dick", "pussy", "fag", "bitch", "sucker", "tits", "porn", "cunt", "cock"];
            let listener;

            this.load = () => {
                if(listener) throw "Chat un-censor feature already loaded";
                chatBox.addEventListener("keydown", listener = event => {
                    let text = chatBox.value.toLowerCase();
                    for(let forbidden of forbiddenWords){
                        let loc = text.indexOf(forbidden);

                        if(loc !== -1){
                            let found = chatBox.value.substr(loc, forbidden.length); // retain original to keep case
                            chatBox.value = chatBox.value.replace(found, found.split("").join(String.fromCharCode(8203)))
                        }
                    }
                });
            }

            this.unload = () => listener = chatBox.removeEventListener("keydown", listener);
        }
    }, {
        name: "Fast Eject",
        enabled: true,
        bootstrap: function(){
            const syntheticEvent = {keyCode: 87, synthetic: true};
            Object.freeze(syntheticEvent);

            let int;
            let pressW = () => {
                window.onkeydown(syntheticEvent);
                window.onkeyup(syntheticEvent);
            }
            let downListener = event => {
                if(event.keyCode === 87 && !event.synthetic && !int){
                    int = setInterval(pressW, 25);
                    window.onkeyup(syntheticEvent); // complete first press
                }
            }
            let upListener = event => {
                if(event.keyCode === 87 && !event.synthetic){
                    clearInterval(int);
                    int = null;
                }
            }
            this.load = () => {
                window.addEventListener("keydown", downListener);
                window.addEventListener("keyup", upListener);
            }
            this.unload = () => {
                window.removeEventListener("keydown", downListener);
                window.removeEventListener("keyup", upListener);
            }
        }
    }, {
        name: "Re-spawn on R",
        enabled: true,
        bootstrap: function (){
            let nicknameInput = document.querySelector("#nick");
            let listener = event => {
                if(event.keyCode === 82 && document.activeElement === document.body){
                    window.rspwn(nicknameInput.value);
                }
            }
            this.load = () => {
                window.addEventListener("keydown", listener);
            }

            this.unload = () => {
                window.removeEventListener("keydown", listener);
            }

        }

    }, {
        name: "Quick-buy powerups with keys 1-4", // rename later
        enabled: true,
        bootstrap: function(){
            const [buyRecombine, buySpeed, buyGrowth, buyPushEnemies] = document.querySelectorAll(".purchase-btn.confirmation");
            let confirmButton;
            let alert;
            let onAlertAvailable = () => {
                const showingNow = alert.classList.contains("showSweetAlert");

                if(showingNow){
                    if(!confirmButton){
                        confirmButton = alert.querySelector("button.confirm");
                        if(!confirmButton) return;
                    }

                    // SweetAlert will ignore all clicks until this class is added
                    // which it waits nearly a full second to add.. annoying. Wasted a lot of time debugging this.
                    // https://github.com/lipis/bootstrap-sweetalert/blob/67fdf993b35fa0a9e2c2a34d218cc9d83a59b8bd/dev/modules/handle-click.js#L42
                    alert.classList.add("visible");
                    confirmButton.click();
                }
            }
            let watcher = new MutationObserver(mutations => {
                for(let mutation of mutations){
                    if(mutation.type === "attributes"){
                        if(mutation.target === alert){
                            onAlertAvailable();
                        }
                    }else if(mutation.type === "childList"){
                        for(let node of mutation.addedNodes){
                            if(node.nodeType !== Node.ELEMENT_NODE) continue;
                            if(node.classList.contains("sweet-alert")){
                                alert = node;
                                onAlertAvailable();
                                watcher.disconnect();
                                watcher.observe(node, {attributes: true, attributeFilter: ["class"]})
                            }
                        }
                    }
                }
            })

            let listener = event => {
                if(document.activeElement === document.body){ // focus is on the game rather than chat or anything else
                    if(event.keyCode === 49 || event.keyCode === 97){
                        buyRecombine.click();
                    }else if(event.keyCode === 50 || event.keyCode === 98){
                        buySpeed.click();
                    } else if(event.keyCode === 51 || event.keyCode === 99){
                        buyGrowth.click();
                    } else if(event.keyCode === 52 || event.keyCode === 100){
                        buyPushEnemies.click();
                    }
                }
            }

            this.load = () => {
                watcher.observe(document.body, {
                    childList: true
                });
                window.addEventListener("keydown", listener);
            }
            this.unload = () => {
                watcher.disconnect();
                window.addEventListener("keydown", listener);
            }
        }
    }, {
        name: "Freeze on F",
        enabled: false, // work in progress
        bootstrap: function() {
            const game = document.body;
            let freezing;
            const listener = (event) => {
                if(event.keyCode === 70 && document.activeElement === document.body){
                    if(!freezing){
                        let event = new MouseEvent("mousemove", {
                            clientX: window.innerWidth / 2,
                            clientY: window.innerHeight / 2
                        });
                        freezing = setInterval(() => game.dispatchEvent(event), 20);
                    }else{
                        clearInterval(freezing);
                        freezing = null;
                    }
                }
            }
            this.load = () => {
                window.addEventListener("keydown", listener);
            }
            this.unload = () => {
                window.removeEventListener("keydown", listener);
            }
        }
    }, {
        enabled: true,
        name: "Remove popups",
        bootstrap: function(){
            this.load = () => {
                const popups = document.querySelectorAll("body .modal");
                for(const popup of popups){
                    if(popup.textContent.indexOf("referral") !== -1){
                        popup.remove();
                    }
                }
            }
            this.unload = () => {

            }
        }
    }];

    for(let feature of features){
        if(feature.enabled) {
            feature.instance = new feature.bootstrap();
            feature.instance.load();
        }
    }
})();