BumpyBall Unlimiter

Every server is Super Server!

当前为 2021-12-25 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         BumpyBall Unlimiter
// @name:ru      BumpyBall Unlimiter
// @namespace    https://greasyfork.org/users/670183
// @version      3
// @description  Every server is Super Server!
// @description:ru  Каждый сервер это Супер Сервер!
// @author       0vC4
// @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
// ==/UserScript==

//hello from O

//Worker Timer
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).WorkerTimer=e()}}(function(){return function o(i,s,l){function u(r,e){if(!s[r]){if(!i[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(f)return f(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[r]={exports:{}};i[r][0].call(a.exports,function(e){var t=i[r][1][e];return u(t||e)},a,a.exports,o,i,s,l)}return s[r].exports}for(var f="function"==typeof require&&require,e=0;e<l.length;e++)u(l[e]);return u}({1:[function(e,r,t){(function(e){"use strict";var t,n,a,o;e===e.window&&e.URL&&e.Blob&&e.Worker?r.exports=(t=["var timerIds = {}, _ = {};","_.setInterval = function(args) {","  timerIds[args.timerId] = setInterval(function() { postMessage(args.timerId); }, args.delay);","};","_.clearInterval = function(args) {","  clearInterval(timerIds[args.timerId]);","};","_.setTimeout = function(args) {","  timerIds[args.timerId] = setTimeout(function() { postMessage(args.timerId); }, args.delay);","};","_.clearTimeout = function(args) {","  clearTimeout(timerIds[args.timerId]);","};","onmessage = function(e) { _[e.data.type](e.data) };"].join(""),n=0,a={},(o=new e.Worker(e.URL.createObjectURL(new e.Blob([t],{type:"text/javascript"})))).onmessage=function(e){a[e.data]&&a[e.data].callback.apply(null,a[e.data].params)},{setInterval:function(e,t){var r=Array.prototype.slice.call(arguments,2);return n+=1,o.postMessage({type:"setInterval",timerId:n,delay:t}),a[n]={callback:e,params:r},n},setTimeout:function(e,t){var r=Array.prototype.slice.call(arguments,2);return n+=1,o.postMessage({type:"setTimeout",timerId:n,delay:t}),a[n]={callback:e,params:r},n},clearInterval:function(e){o.postMessage({type:"clearInterval",timerId:e}),a[e]=null},clearTimeout:function(e){o.postMessage({type:"clearTimeout",timerId:e}),a[e]=null}}):r.exports=e}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)});

window.logout = () => {
    window.indexedDB.databases().then(d=>d[2]).then(d=>window.indexedDB.deleteDatabase(d.name))
};
//window.logout();



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/5;
document.onkeydown = e => {
    if (e.code == 'NumpadAdd') {
        client.sendMessage('[Censored]');
        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;
        }
        iter = WorkerTimer.setInterval(()=>{
            const matrix = window.genMatrix();
            for(let i=0;i<10;i++)client.sendMessage(matrix[i]);
        }, fps);
        return;
    }
}



(function() {
    const proto=XMLHttpRequest.prototype;

    if(!proto._open)proto._open=proto.open;
    proto.open=function(){
        const[method,url]=arguments;
        Object.assign(this,{method,url});
        return this._open.apply(this,arguments);
    };

    if(!proto._send)proto._send=proto.send;
    proto.send=function(body){
        if(this.url.match(/Listing\?Game=BumpyBall/)) {
            this._lnd=this.onload;
            this.onload=function(e){
                const table = JSON.parse(new TextDecoder().decode(this.response));
                table.forEach(server=>server.MaxPlayers=999);

                Object.defineProperty(this, 'response', {
                  enumerable: true,
                  configurable: true,
                  writable: true,
                  value: new TextEncoder().encode(JSON.stringify(table)).buffer
                });
                this._lnd(e);
            };
        }
        if(this.url.match(/\/Ping/)) {
            this._lnd=this.onload;
            this.onload=function(e){
                const server = JSON.parse(new TextDecoder().decode(this.response));
                server.MaxPlayers=999;

                Object.defineProperty(this, 'response', {
                  enumerable: true,
                  configurable: true,
                  writable: true,
                  value: new TextEncoder().encode(JSON.stringify(server)).buffer
                });
                this._lnd(e);
            };
        }
        return this._send.apply(this,arguments)
    };
})();
// 0vC4#7152