BumpyBall Unlimiter

Every server is Super Server!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         BumpyBall Unlimiter
// @name:ru      BumpyBall Unlimiter
// @description  Every server is Super Server!
// @description:ru  Каждый сервер это Супер Сервер!
// @author       0vC4
// @version      3.2
// @namespace    https://greasyfork.org/users/670183-exnonull
// @match        http://www.pucks.io/
// @match        https://www.pucks.io/
// @match        http://www.bumpyball.io/
// @match        https://www.bumpyball.io/
// @icon         https://www.google.com/s2/favicons?domain=bumpyball.io
// @run-at       document-start
// @grant        none
// @license      MIT
// @require      https://greasyfork.org/scripts/438620-workertimer/code/WorkerTimer.js
// @require      https://greasyfork.org/scripts/448029-rblu/code/RBLU.js
// ==/UserScript==

//hello from O

document.addEventListener('DOMContentLoaded', e => document.body.style.overflow = 'hidden');
window.logout = () => {
    window.indexedDB.databases().then(d=>d[2]).then(d=>window.indexedDB.deleteDatabase(d.name))
};
// try { window.logout(); } catch (e) {}



const r7bit = arr => {let r=0,e=0;for(;35!=e;){let f=arr[e/7];if(r|=(127&f)<<e,0==(128&f))return[r,e/7+1];e+=7}};
const int7 = (arr, start) => {
    let [value, bytes] = r7bit(arr.slice(start));
    return [value, start+bytes];
};
const float = (arr, start) => {
    let value = new Float32Array(new Uint8Array(arr.slice(start, start+4)).buffer)[0]
    return [value, start+4];
};
const w7bit = num => {let r=[];for(;num>=128;num>>=7)r.push((128|num)%256);return r.push(num%256),r};



const client = window.client = {
    bots: [],
    num: 15,
    team: 2,
    enabled: false,
    chatEnabled: false,
    moveEnabled: true,

    antiAfk: WorkerTimer.setInterval(()=>{
        const hiddenForward = new Uint8Array([8,7,18,10,18,5,13,0,0,128,63,24,200,1]).buffer;
        if (client.ws && client.ws.readyState === 1 && client.ws.id > -1) client.ws._send(hiddenForward);
        client.bots.forEach(b => {
            if (b.readyState === 1 && b.id > -1) b._send(hiddenForward);
        });
    }, 1000),

    sendMessage(text='') {
        if (!this.ws || !this.ws.constId) return;
        const msg = new TextEncoder().encode(text);
        const body = [8,...w7bit(this.ws.constId), 18,...w7bit(msg.length),...msg];
        const head = [8,5, 18,...w7bit(body.length)];
        const data = new Uint8Array([...head, ...body]);
        this.ws.send(data);
    },

    bot(num=15, team=2){
        this.team = team;
        this.num = num;
        return this.enabled = !this.enabled
    },

    move(on = null){
        if (on == null) return this.moveEnabled = !this.moveEnabled;
        return this.moveEnabled = !!on;
    },

    chatBot(on = null){
        if (on == null) return this.chatEnabled = !this.chatEnabled;
        return this.chatEnabled = !!on;
    },

    // 0 - blue, 1 - red
    close(team=2){
        this.bots.forEach(b=>{
            if (team === 2 || team === b.team) {
                WorkerTimer.clearInterval(b.inter);
                b.close();
            }
        });

        this.bots = this.bots.filter(b => team !== b.team);
        if (team === 2) this.bots = [];
    },

    setup(data, num=this.num){
        if (!this.ws.url || !this.enabled) return false;
        for(;num--;){
            WorkerTimer.setTimeout(()=>{
                const ws = new WebSocket(this.ws.url);
                this.bots.push(ws);
                ws.query = [data];
                ws.onopen=function(){
                    ws.inter = WorkerTimer.setInterval(()=>{
                        if (!ws.query.length) return;
                        let data = [...new Uint8Array(ws.query.shift())];
                        ws.send(new Uint8Array(data).buffer);
                    }, 17);
                }
            }, 57*num);
        }
    }
};



const packet = {};
packet.open = (arr, pos=0) => {
    packet.cancel = false;
    packet.arr = arr;
    packet.value = undefined;
    packet.pos = pos;
    return packet;
}
packet.null = () => {
    packet.cancel = true;
    packet.value = null;
    return packet;
}
packet.len = () => {
    if (packet.cancel) return packet;
    let {arr, pos, value} = packet;

    if (arr[pos++] !== 10) return packet.null();
    [value, pos] = int7(arr, pos);

    return Object.assign(packet, {pos, value});
}
packet.code = () => {
    if (packet.cancel) return packet;
    let {arr, pos, value} = packet;

    if (arr[pos++] !== 8) return packet.null();
    [value, pos] = int7(arr, pos);

    return Object.assign(packet, {pos, value});
}
packet.player = () => {
    if (packet.cancel) return packet;
    let {arr, pos, value} = packet;

    let data = {
        id: null,
        constId: null,
        team: null,
        x: null,
        z: null
    };

    if (arr[pos++] !== 10) return packet.null();
    [value, pos] = int7(arr, pos);

    if (arr[pos++] !== 8) return packet.null();
    if (arr[pos++] !== 8) return packet.null();

    if (arr[pos++] !== 18) return packet.null();
    [value, pos] = int7(arr, pos);

    if (arr[pos++] !== 16) return packet.null();
    [value, pos] = int7(arr, pos);
    data.id = value;

    if (arr[pos++] !== 26) return packet.null();
    [value, pos] = int7(arr, pos);

    if (arr[pos++] !== 10) return packet.null();
    [value, pos] = int7(arr, pos);

    if (arr[pos++] !== 13) return packet.null();
    [value, pos] = float(arr, pos);
    data.x = value;

    if (arr[pos++] !== 21) return packet.null();
    [value, pos] = float(arr, pos);
    data.z = value;

    if (arr[pos++] !== 24) return packet.null();
    [value, pos] = int7(arr, pos);
    data.constId = value;

    if (arr[pos] === 42) { //42,0
        data.team = 0;
        pos += 2;
        packet.value = data;
        return Object.assign(packet, {pos});
    }

    //37,219,15,73,192, 42,0
    data.team = 1;
    pos += 5+2;
    packet.value = data;
    return Object.assign(packet, {pos});
}
packet.players = () => {
    if (packet.cancel) return packet;
    let {arr, pos, value} = packet;
    const players = [];

    for (let i = 0; i < arr.length; i++) {
        if (arr[i] !== 10) continue;
        packet.pos = i;
        let data = packet.player().value;
        if (data === null) {
            packet.cancel = false;
            continue;
        }
        players.push(data);
        i = packet.pos-1;
    }

    packet.value = players;
    return packet;
}



const isConnected = arr => {
    packet.open(arr);
    const code = packet.len().code().value;
    if (code === null) return false;
    if (code === 3) return true;
    return false;
}
const isJoinOther = arr => {
    packet.open(arr);
    const code = packet.len().code().value;
    if (code === null) return false;
    if (code === 2) return true;
    return false;
}
const isSpawn = arr => {
    packet.open(arr);
    const code = packet.len().code().value;
    if (code === null) return false;
    if (code === 8) return packet.player().value;
    return false;
}



const getId = arr => {
    // 10,x, 8,8,18,x, 16,id, 26,x, 10,10,13,... ,0,42];
    if (isConnected(arr)) return packet.id(arr).value;
    if (isJoinOther(arr)) return null;
    if (isSpawn(arr)) return packet.id(arr).value;
}
window.r7bit = r7bit;
window.w7bit = w7bit;
window.getId = getId;


(()=>{
    const proto = WebSocket.prototype;
    proto._send = proto.send;
    proto.send = function (data) {
        if (!this.event) {
            this.event = true;
            this.addEventListener('message', async function(e){
                const data = [...new Uint8Array(await e.data.arrayBuffer())];
                const players = packet.open(data).players().value;
                if (players == null) return;

                if (players.length) {
                    if (this.constId == null) Object.assign(this, players[0]);
                    const player = players.find(p => p.constId === this.constId);
                    if (player) Object.assign(this, player);
                }

                if (client.team !== 2 && client.bots.every(b => b.team > -1)) client.close(+(!client.team));
            });
        }

        if (!client.ws) {
            client.ws = this;
            this.addEventListener('close', e=>{
                delete client.ws;
                client.close();
            });
            this.own = true;
            client.setup(data);
        }

        if (this.own) {
            const d = [...new Uint8Array(data)];
            let move = false;
            let packet = d;

            if (
                (d[0]==8&&d[1]==7&&d[2]==18) // move
            ) {
                move = true;
                packet = d.slice(0, d.length-w7bit(this.id||0).length);
            }

            if (
                client.moveEnabled&&
                !(!client.chatEnabled&&d[0]==8&&d[1]==5&&d[2]==18) // chat
            ) {
                client.bots.forEach(b=>{
                    if (move && b.id == null) return;
                    if (b.readyState===3) return;
                    if (b.readyState!==1) return b.query.push(packet);
                    if (move) b.send(new Uint8Array([...packet, ...w7bit(b.id)]));
                    else b.send(new Uint8Array(packet));
                })
            }
        }

        //if (this.own) console.log('own', new Uint8Array(data));
        //else console.log('bot', new Uint8Array(data));
        this._send(data);
    }
})();



window.genMatrix = () => {
    const steps = 10;
    const fps = 1000/20;
    const time = performance.now()/100;
    const step = time/fps>>0;

    const light = num => {
        const gradient = "_O";
        const max = gradient.length-1;
        num = Math.min(100, Math.max(num, 0));
        const x = max*num/100>>0;
        return gradient[x];
    }

    const matrix = Array(10).fill(0).map((a,y)=>{
        //y = y + step%steps >> 0;
        return Array(10).fill(0).map((a,x)=>{
            //x = x + step%steps >> 0;
            const dxy = x^y;
            const drawIf = dxy>time%25 || x==0 || x == 9 || y == 0 || y == 9;
            const formula = drawIf*100;
            const color = light(formula);
            return color;
        }).join('');
    });

    return matrix;
};
window.genMatrix2 = () => {
    return [
        'OOOOOOOOOO',
        'O________O',
        'O_O____O_O',
        'O_O____O_O',
        'O_O____O_O',
        'O________O',
        'O_O____O_O',
        'O__OOOO__O',
        'O________O',
        'OOOOOOOOOO',
    ];
};
window.genMatrix3 = () => {
    return [
        'OOOOOOOOOO',
        'O________O',
        'O_O____O_O',
        'O_O____O_O',
        'O_O____O_O',
        'O________O',
        'O__OOOO__O',
        'O_O____O_O',
        'O________O',
        'OOOOOOOOOO',
    ];
};
var iter = null;
const fps = 1000/250;
document.onkeydown = e => {
    if (e.code == 'NumpadAdd') {
        client.sendMessage('');
        for(let i=0;i<9;i++)client.sendMessage('');
        return;
    }
    if (e.code == 'NumpadMultiply') {
        const matrix = window.genMatrix2();
        for(let i=0;i<10;i++)client.sendMessage(matrix[i]);
        return;
    }
    if (e.code == 'NumpadDivide') {
        const matrix = window.genMatrix3();
        for(let i=0;i<10;i++)client.sendMessage(matrix[i]);
        return;
    }
    if (e.code == 'NumpadSubtract') {
        if (iter != null) {
            WorkerTimer.clearInterval(iter);
            iter = null;
            return;
        }
        let g = 0;
        iter = WorkerTimer.setInterval(()=>{
            let matrix = Array(120).fill(' ').join('');
            client.sendMessage(matrix);
        }, fps);
        return;
    }
}
// 0vC4#7152