Altanis / Diep.io Chatting Service

// ==UserScript==
// @name         Diep.io Chatting Service
// @namespace    http://tampermonkey.net/
// @version      1.1.0
// @description  Talk to other users using this script!
// @author       Altanis#9863
// @match        *://diep.io/*
// @license      MIT
// ==/UserScript==

/*
Version 1.1.0
   * Fixed Bugs
   * SHIFT + ENTER replaced with ENTER
   * Transparency set to 50%
*/

(async function() {
    var token = '';

    const enableTheAntiBotting = true; // shadam and diep7444 mad

    var guiToggle = false;
    var sendText = false;
    var didSpawn = false;
    var isPrivate = false;

    var didConnect = true;
    var allowLink = true;

    var currentText = '';
    var pText = '';
    var name = '';
    var region = '';
    var servID = '';

    var playerCount = 'Awaiting';

    var pingTime = 0;
    var autoLinkCount = 0;

    var link = {auto: '', user: ''};

    // START SHLONG GUI
    const GUIWrapper = document.createElement("div");
    const gui = document.createElement("div");
    gui.style = `position: fixed;
top:450px;
left:10px;
font-family: Ubuntu;
color: #FFFFFF;
font-style: normal;
font-size: 15px;
text-shadow: black 2px 0px, black -2px 0px, black 0px -2px, black 0px 2px, black 2px 2px, black -2px 2px, black 2px -2px, black -2px -2px, black 1px 2px, black -1px 2px, black 1px -2px, black -1px -2px, black 2px 1px, black -2px 1px, black 2px -1px, black -2px -1px;`;

    document.body.appendChild(GUIWrapper);
    GUIWrapper.appendChild(gui);
    gui.innerHTML = `<div style='
border-radius: 25px;
border: 3px solid #42bff5;
padding: 0px 9px;
opacity:0.7;
align-content: center;
background-color: #42bff5;
height:500px;
width:500px;
overflow: hidden;
position:fixed;
opacity: 50%;' id="chatdiv">
<p style="color:#FFFFFF; text-align:center;">
<strong>Chat</strong>
</p>
<p style="color:#FFFFFF; font-size:10px; text-align:center;">
[Alt + T] Toggle Chat GUI
[Enter] To start typing and sending messages
<br>
${playerCount} users online
<p style="text-align:center;" id="chat-base">
Messages will appear as people start talking.
</p>
<input type="text" id="chatInput" style="width:500px;
position:bottom;
bprder:none;
-webkit-appearance:none;
-ms-appearance:none;
-moz-appearance:none;
appearance:none;
background:#f2f2f2;
border-radius:3px;
outline:none;
">
</div>
</div>
`;
    // END SHLONG GUI

    const linkSpecify = document.createElement('button');
    const text = document.createTextNode('Specify link');
    linkSpecify.appendChild(text);
    document.body.appendChild(linkSpecify);

    linkSpecify.style = 'align-content: top-right; position:relative; background: linear-gradient(135deg, #6e8efb, #a777e3); width:150px; height:50px; border-radius: 12px; border: none;';
    linkSpecify.onclick = function() {
        link.user = prompt('Please input your link to be shared with others.\nIf you are in FFA/Maze: Your link will already be taken.\nIf you are in 2TDM/4TDM: If you have not yet copied your link, press Cancel, copy your link, and then press this button again. Paste the link here.') || '';
        if (didSpawn) {
            socket.send(JSON.stringify({
                type: 'CHANGE_LINK',
                newLink: link.user,
            }));
        }
    };

    const privateChatSpecify = document.createElement('button');
    const t = document.createTextNode('Enable private chat');
    privateChatSpecify.appendChild(t);
    document.body.appendChild(privateChatSpecify);

    privateChatSpecify.style = 'align-content: top-right; position:relative; background: linear-gradient(135deg, #6e8efb, #a777e3); width:150px; height:50px; border-radius: 12px; border: none;';
    privateChatSpecify.onclick = function() {
        isPrivate = !isPrivate;
        privateChatSpecify.innerText = `${isPrivate ? 'Disable' : 'Enable'} private chat`;

        socket.send(JSON.stringify({ type: 'PRIVATE_CHAT', isPrivate: isPrivate }));
    };

    const linkToggle = document.createElement('button');
    const _text = document.createTextNode('Disable link sharing');
    linkToggle.appendChild(_text);
    document.body.appendChild(linkToggle);

    linkToggle.style = 'align-content: top-right; position:relative; background: linear-gradient(135deg, #6e8efb, #a777e3); width:150px; height:50px; border-radius: 12px; border: none;';
    linkToggle.onclick = function() {
        allowLink = !allowLink;
        linkToggle.innerText = `${allowLink ? 'Disable' : 'Enable'} link sharing`;
    };

    linkSpecify.style.display = 'block';
    privateChatSpecify.style.display = 'block';
    linkToggle.style.display = 'block';

    let __send = WebSocket.prototype.send;
    WebSocket.prototype.send = function(data) {
        if (!allowLink) {
            link = {}
        } else {
            let url = this.url.split("://")[1].split(".")[0].toLowerCase();
            servID = url;
            let letters = url.split('');
            let l = 'https://diep.io/#';

            letters.forEach((letter, index) => {
                let byte = letter.charCodeAt();
                let upper = (byte / 16).toString(16).split('.')[0];
                let lower = (byte % 16).toString(16);
                l += lower.toUpperCase() + '' + upper.toUpperCase();
                if (index === 3)
                    link.auto = l;
            });
        }
        __send.call(this, data);
    };

    setInterval(function() {
        dragElement(document.getElementById("chatdiv"));
    }, 1000);

    function dragElement(el) {
        if (gui.innerHTML === '') return;
        var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        if (document.getElementById(el.id + "header")) {
            // if present, the header is where you move the DIV from:
            document.getElementById(el.id + "header").onmousedown = dragMouseDown;
        } else {
            // otherwise, move the DIV from anywhere inside the DIV:
            el.onmousedown = dragMouseDown;
        }

        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();

            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;

            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();

            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;

            el.style.top = (el.offsetTop - pos2) + "px";
            el.style.left = (el.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }


    let socket = new WebSocket('wss://diep-chat-api.glitch.me/');
    socket.onmessage = function({ data }) {
        data = JSON.parse(data);
        switch (data.type) {
            case 'PROXY_DETECTED':
                alert('Sorry for the inconvience, but a VPN/Proxy cannot be enabled. If you must use one, please disable it when opening Diep.io, then re-enable it 5 seconds later. If you are not using a VPN, contact me at Altanis#9863.');
                break;
            case 'MESSAGE_RECV':
                const { message, sender } = data;
                pText += `\n<p>\n${sender}: ${message}\n</p>`;
                if (document.getElementById('chat-base'))
                    document.getElementById('chat-base').remove();
                if (gui.innerHTML === '') return;
                gui.innerHTML = `<div style='
border-radius: 25px;
border: 3px solid #42bff5;
padding: 0px 9px;
opacity:0.7;
align-content: center;
background-color: #42bff5;
height:500px;
width:500px;
overflow: auto;
position:fixed;
opacity: 50%;' id="chatdiv">
<p style="color:#FFFFFF; text-align:center;">
<strong>Chat</strong>
</p>
<p style="color:#FFFFFF; font-size:10px; text-align:center;">
[Alt + T] Toggle Chat GUI
[Enter] To start typing and sending messages
<br>
${playerCount} users online
${pText}
<input type="text" id="chatInput" style="width:500px;
position:bottom;
bprder:none;
-webkit-appearance:none;
-ms-appearance:none;
-moz-appearance:none;
appearance:none;
background:#f2f2f2;
border-radius:3px;
outline:none;
">
</div>
</div>
`;
                break;
            case 'RATELIMIT':
                alert(data.message);
                break;
            case 'USERCOUNT_RECV':
                const { count } = data;
                playerCount = count;
                if (gui.innerHTML === '') return;
                gui.innerHTML = `<div style='
border-radius: 25px;
border: 3px solid #42bff5;
padding: 0px 9px;
opacity:0.7;
align-content: center;
background-color: #42bff5;
height:500px;
width:500px;
overflow: hidden;
position:fixed;
opacity: 50%;' id="chatdiv">
<p style="color:#FFFFFF; text-align:center;">
<strong>Chat</strong>
</p>
<p style="color:#FFFFFF; font-size:10px; text-align:center;">
[Alt + T] Toggle Chat GUI
[Enter] To start typing and sending messages
<br>
${playerCount} users online
<p style="text-align:center;" id="chat-base">
${pText || 'Messages will appear as people start talking.'}
</p>
<input type="text" id="chatInput" style="width:500px;
position:bottom;
bprder:none;
-webkit-appearance:none;
-ms-appearance:none;
-moz-appearance:none;
appearance:none;
background:#f2f2f2;
border-radius:3px;
outline:none;
">
</div>
</div>
`;
        }
    };

    /*    socket.onclose = function() {
        didConnect = false;
        gui.innerHTML = `<div style='
border-radius: 25px;
border: 3px solid #42bff5;
padding: 0px 9px;
opacity:0.7;
align-content: center;
background-color: #42bff5;
height:500px;
width:500px;
position:absolute;
overflow: auto;' id="chatdiv">
<p style="color:#FFFFFF; text-align:center;">
<strong>Chat</strong>
</p>
<p style="color:#FFFFFF; font-size:10px; text-align:center;">
[Alt + T] Toggle Chat GUI
<p style="text-align:center;" id="chat-base">
Socket connection broke, attempting to re-connect.
</p>
<input type="text" id="chatInput" style="width:500px;
position:bottom;
bprder:none;
-webkit-appearance:none;
-ms-appearance:none;
-moz-appearance:none;
appearance:none;
background:#f2f2f2;
border-radius:3px;
outline:none;
">
</div>
</div>
`;
        const interval = setInterval(function() {
            if (didConnect) return clearInterval(interval);
            socket = new WebSocket('wss://diep-chat-api.glitch.me/');
            setTimeout(function() {
                if (socket.readyState === 1) {
                    didConnect = true;
                    gui.innerHTML = `<div style='
border-radius: 25px;
border: 3px solid #42bff5;
padding: 0px 9px;
opacity:0.7;
align-content: center;
background-color: #42bff5;
height:500px;
width:500px;
position:absolute;
overflow: auto;' id="chatdiv">
<p style="color:#FFFFFF; text-align:center;">
<strong>Chat</strong>
</p>
<p style="color:#FFFFFF; font-size:10px; text-align:center;">
[Alt + T] Toggle Chat GUI
${pText}
<input type="text" id="chatInput" style="width:500px;
position:bottom;
bprder:none;
-webkit-appearance:none;
-ms-appearance:none;
-moz-appearance:none;
appearance:none;
background:#f2f2f2;
border-radius:3px;
outline:none;
">
</div>
</div>
`;
                    const currentLink = link.user || link.auto;

                    socket.send(JSON.stringify({
                        type: 'SPAWN',
                        name: name,
                        link: currentLink,
                        region: 'miami',
                    }));
                    socket.send(JSON.stringify({
                        type: 'TOKEN',
                        token: token,
                    }));
                }
            }, 2000);
        }, 15000);
    };*/


    document.addEventListener('keydown', function(event) {
        if (sendText) {
            if (event.key.length === 1) {
                '~`!@#$%^&*()-_=+/*-qwertyuiop[{]}\|asdfghjkl;:\'"zxcvbnm,<.>?1234567890QWERTYUIOPASDFGHJKLZXCVBNM'.split('').forEach(function(letter) {
                    if (event.key.includes(letter)) {
                        currentText += letter;
                        document.getElementById('chatInput').value = currentText;
                    }
                });
            } else {
                switch (event.key) {
                    case 'Backspace':
                        currentText = currentText.slice(0, -1)
                        document.getElementById('chatInput').value = currentText;
                        break;
                }
            }

            if (event.code === 'Space') {
                currentText += ' ';
                console.log(currentText);
                document.getElementById('chatInput').value = currentText;

            }
        }

        if (event.code === 'KeyT') {
            if (!event.altKey) return;

            guiToggle = !guiToggle;
            if (guiToggle) {
                gui.innerHTML = '';
                linkSpecify.style.display = 'none';
                privateChatSpecify.style.display = 'none';
                linkToggle.style.display = 'none';
            } else {
                gui.innerHTML = `<div style='
border-radius: 25px;
border: 3px solid #42bff5;
padding: 0px 9px;
opacity:0.7;
align-content: center;
background-color: #42bff5;
height:500px;
width:500px;
overflow: auto;
position:fixed;
opacity: 50%;' id="chatdiv">
<p style="color:#FFFFFF; text-align:center;">
<strong>Chat</strong>
</p>
<p style="color:#FFFFFF; font-size:10px; text-align:center;">
[Alt + T] Toggle Chat GUI
[Enter] To start typing and sending messages
<br>
${playerCount} users online
${pText || `<p style="text-align:center;" id="chat-base">
Messages will appear as people start talking.
</p>`}
<input type="text" id="chatInput" style="width:500px;
position:bottom;
bprder:none;
-webkit-appearance:none;
-ms-appearance:none;
-moz-appearance:none;
appearance:none;
background:#f2f2f2;
border-radius:3px;
outline:none;
">
</div>
</div>
`;
                linkSpecify.style.display = 'block';
                privateChatSpecify.style.display = 'block';
                linkToggle.style.display = 'block';
            }
        } else if (event.code === 'Enter' || event.code === 'NumpadEnter') {
            if (!didSpawn) {
                const inp = document.getElementById('textInput');
                didSpawn = true;

                const currentLink = allowLink ? (link.user || link.auto) : undefined;

                name = inp.value || 'Unnamed Tank';

                let crx = CanvasRenderingContext2D;
                crx.prototype.strokeText = new Proxy(crx.prototype.strokeText, {
                    apply: function(f, _this, args) {
                        const text = args[0];
                        if (text.includes('vultr')) {
                            region = text.split('vultr-')[1];
                        }

                        f.apply(_this, args);
                    },
                });

                setTimeout(function() {
                    socket.send(JSON.stringify({
                        type: 'SPAWN',
                        name: name,
                        link: currentLink,
                        region: region,
                    }));
                    socket.send(JSON.stringify({
                        type: 'TOKEN',
                        token: token,
                    }));
                    setInterval(function() {
                        socket.send(JSON.stringify({ type: 'PONG' }));
                    }, 30000);
                    socket.send(JSON.stringify({ type: 'USERCOUNT' }));
                    setInterval(function() {
                        socket.send(JSON.stringify({ type: 'USERCOUNT' }));
                    }, 60000);
                }, 2000);

                WebSocket.prototype.send = function(data) {
                    if (!allowLink) {
                        link = {};
                    } else {
                        if ((servID !== this.url) && this.url !== 'wss://diep-chat-api.glitch.me/') { // Change in region is occuring
                            let url = this.url.split("://")[1].split(".")[0].toLowerCase();

                            let letters = url.split('');
                            let l = 'https://diep.io/#';

                            letters.forEach((letter, index) => {
                                let byte = letter.charCodeAt();
                                let upper = (byte / 16).toString(16).split('.')[0];
                                let lower = (byte % 16).toString(16);
                                l += lower.toUpperCase() + '' + upper.toUpperCase();
                                if (index === 3) {
                                    if (link.auto == l) {
                                        autoLinkCount++;
                                        if (autoLinkCount >= 3) {
                                            servID = url;
                                            autoLinkCount = 0;
                                        }
                                    }
                                    link.auto = l;
                                }

                            });
                        }
                    }

                    __send.call(this, data);
                };
            } else {
                socket.send(JSON.stringify({
                    type: 'UPDATE_INFO',
                    r: region,
                    l: link.user || link.auto,
                }));
            }
            if (gui.innerHTML === '') return;
            if (!input.should_prevent_unload()) return;

            sendText = !sendText;

            if (!sendText) {
                socket.send(JSON.stringify({
                    type: 'MESSAGE',
                    message: currentText,
                }));
                currentText = '';
                document.getElementById('chatInput').value = '';
            }
        }
    });

    const _intervalXD = setInterval(function() {
        if (input) {
            clearInterval(_intervalXD);
            let _kd = input.keyDown;
            input.keyDown = (id) => !sendText && _kd(id)

            let _ku = input.keyUp;
            input.keyUp = (id) => !sendText && _ku(id)
        }
    }, 150);
})();