Dette scriptet burde ikke installeres direkte. Det er et bibliotek for andre script å inkludere med det nye metadirektivet // @require https://update.greasyfork.org/scripts/448028/1071803/RBDB.js
// ==UserScript==
// @name RBDB
// @version 1.0
// @author 0vC4
// @description RocketBall Decoder Buffer
// @namespace https://greasyfork.org/users/670183-exnonull
// @license MIT
// ==/UserScript==
const RBScheme = {
pos: [
[13, 'x', 'f32'],
[21, 'y', 'f32'],
],
object: [
[10, 'pos', 'pos'],
[16, 'type', 'objectType'],
[24, 'playerId', 'int7'],
[37, 'angle', 'f32'],
[42, 'speed', 'pos'],
],
entity: [
[8, 'objectId', 'int7'],
[18, 'data', 'object'],
],
entities: [
[10, 'item', 'entity'],
],
user: [
[8, 'playerId', 'int7'],
[18, 'username', 'string'],
[24, 'goals', 'int7'],
[32, 'assists', 'int7'],
[40, 'team', 'teamName'],
[48, 'car', 'int7'],
[56, 'bot', 'int7'],
[64, 'exp', 'int7'],
],
users: [
[10, 'item', 'user'],
],
team: [
[8, 'name', 'teamName'],
[16, 'goals', 'int7'],
],
round: [
[13, 'time', 'f32'],
[18, 'red', 'team'],
[18, 'blue', 'team'],
[18, 'spectator', 'team'],
[24, 'magic', 'int7'],
],
finish: [
[10, 'authToken', 'string'],
[34, 'username', 'string'],
[40, 'goals', 'int7'],
[48, 'assists', 'int7'],
[56, 'wins', 'int7'],
[72, 'lost', 'int7'],
[80, 'spareExp', 'int7'],
[88, 'exp', 'int7'],
],
};
class ReadBuffer {
offset = 0
buffer = []
finished = false
constructor(packet) {
this.buffer = [...packet];
this.offset = 0
}
next(size=1) {
let offset = this.offset;
this.offset += size;
if (this.offset == this.buffer.length) this.finished = true;
return offset;
}
get skip8() {
this.u8;
return this;
}
get skip16() {
this.u16;
return this;
}
get skip32() {
this.u32;
return this;
}
get skip64() {
this.u64;
return this;
}
get skip7() {
this.int7;
return this;
}
get skipString() {
this.string;
return this;
}
get u8() {
return new Uint8Array([this.buffer[this.next()]])[0];
}
get u16() {
return new Uint16Array(new Uint8Array(this.buffer.slice(this.next(2), this.offset)).buffer)[0];
}
get u32() {
return new Uint32Array(new Uint8Array(this.buffer.slice(this.next(4), this.offset)).buffer)[0];
}
get u64() {
return new BigUint64Array(new Uint8Array(this.buffer.slice(this.next(8), this.offset)).buffer)[0];
}
get s8() {
return new Int8Array([this.buffer[this.next()]])[0];
}
get s16() {
return new Int16Array(new Uint8Array(this.buffer.slice(this.next(2), this.offset)).buffer)[0];
}
get s32() {
return new Int32Array(new Uint8Array(this.buffer.slice(this.next(4), this.offset)).buffer)[0];
}
get s64() {
return new BigInt64Array(new Uint8Array(this.buffer.slice(this.next(8), this.offset)).buffer)[0];
}
get f32() {
return new Float32Array(new Uint8Array(this.buffer.slice(this.next(4), this.offset)).buffer)[0];
}
get f64() {
return new Float64Array(new Uint8Array(this.buffer.slice(this.next(8), this.offset)).buffer)[0];
}
get int7() {
let offset = 0;
let num = 0;
while (offset != 0b100011) {
let byte = this.buffer[this.offset + offset/7];
num |= (byte&0x7f)<<offset;
offset += 7;
if ((byte&0x80) == 0) {
this.next(offset/7);
return num;
}
}
this.next(offset/7);
return num;
}
get array() {
return new Uint8Array(this.buffer.slice(this.next(this.buffer.length-this.offset), this.offset));
}
get array7() {
const offset = this.next(this.int7);
return new Uint8Array(this.buffer.slice(offset, this.offset));
}
get string() {
return new TextDecoder().decode(this.array7);
}
// custom types
read(scheme) {
const buffer = new ReadBuffer(this.array7);
if (buffer.buffer.length == 0) return {};
const data = {};
const skip = [];
while (!buffer.finished) {
const slotId = buffer.u8;
try {
const [id, key, type] = RBScheme[scheme].find(([id], i) => {
if (id == slotId && !skip.includes(i)) {
skip.push(i);
return true;
}
});
data[key] = buffer[type];
} catch (e) {
console.log(scheme, buffer.buffer+'', buffer.offset, slotId, RBScheme[scheme]);
throw e;
}
}
return data;
}
readArray(scheme) {
const buffer = new ReadBuffer(this.array7);
if (buffer.buffer.length == 0) return [];
const data = [];
while (!buffer.finished)
data.push(buffer.skip8.read(RBScheme[scheme][0][2]));
return data;
}
get pos() {
const data = this.read('pos');
if (!data.x) data.x = 0;
if (!data.y) data.y = 0;
return data;
}
get object() {
return this.read('object');
}
get entity() {
return this.read('entity');
}
get entities() {
return this.readArray('entities');
}
get user() {
return this.read('user');
}
get users() {
return this.readArray('users');
}
get objectType() {
return ['player', 'ball', 'magic', 'magic2', 'boost'][this.int7];
}
get teamName() {
return ['red', 'blue', 'spectator'][this.int7];
}
get team() {
const data = this.read('team');
if (!data.name) data.name = 'red';
if (!data.goals) data.goals = 0;
return data;
}
get round() {
return this.read('round');
}
get finish() {
return this.read('finish');
}
}
class WriteBuffer {
offset = 0
buffer = []
constructor(buffer = []) {
this.buffer = [...buffer];
this.offset = buffer.length;
}
u8(...nums) {
for (let byte of new Uint8Array([...nums]))
this.buffer[this.offset++] = byte;
return this;
}
u16(...nums) {
for (let byte of new Uint8Array(new Uint16Array([...nums]).buffer))
this.buffer[this.offset++] = byte;
return this;
}
u32(...nums) {
for (let byte of new Uint8Array(new Uint32Array([...nums]).buffer))
this.buffer[this.offset++] = byte;
return this;
}
u64(...nums) {
for (let byte of new Uint8Array(new BigUint64Array([...nums]).buffer))
this.buffer[this.offset++] = byte;
return this;
}
s8(...nums) {
for (let byte of new Uint8Array([...nums]))
this.buffer[this.offset++] = byte;
return this;
}
s16(...nums) {
for (let byte of new Uint8Array(new Int16Array([...nums]).buffer))
this.buffer[this.offset++] = byte;
return this;
}
s32(...nums) {
for (let byte of new Uint8Array(new Int32Array([...nums]).buffer))
this.buffer[this.offset++] = byte;
return this;
}
s64(...nums) {
for (let byte of new Uint8Array(new BigInt64Array([...nums]).buffer))
this.buffer[this.offset++] = byte;
return this;
}
f32(...nums) {
for (let byte of new Uint8Array(new Float32Array([...nums]).buffer))
this.buffer[this.offset++] = byte;
return this;
}
f64(...nums) {
for (let byte of new Uint8Array(new Float64Array([...nums]).buffer))
this.buffer[this.offset++] = byte;
return this;
}
int7(...nums) {
const bytes = [];
for (let num of nums) {
while(num >= 0x80) {
bytes.push((num|0x80)%0x100);
num >>= 7;
}
bytes.push(num%0x100);
}
for (let byte of bytes)
this.buffer[this.offset++] = byte;
return this;
}
array(...arrays) {
for (let array of arrays)
for (let byte of array)
this.buffer[this.offset++] = new Uint8Array([byte])[0];
return this;
}
array7(...arrays) {
for (let array of arrays) {
this.int7(array.length);
for (let byte of array)
this.buffer[this.offset++] = new Uint8Array([byte])[0];
}
return this;
}
string(...strs) {
for (let str of strs) this.array7(new TextEncoder().encode(str));
return this;
}
// custom types
write(scheme, ...items) {
for (let item of items) {
const buffer = new WriteBuffer();
for (let k in item) {
try {
const [id, key, type] = RBScheme[scheme].find(([id, key]) => key == k);
buffer.u8(id);
buffer[type](item[k]);
} catch (e) {
console.log(scheme, items, item, k, RBScheme[scheme], buffer.buffer+'');
throw e;
}
}
this.int7(buffer.buffer.length).array(buffer.buffer);
}
return this;
}
writeArray(scheme, ...itemLists) {
for (let itemList of itemLists) {
const buffer = new WriteBuffer();
for (let items of itemList)
buffer.int7(10).write(RBScheme[scheme][0][2], items);
this.int7(10, buffer.buffer.length).array(buffer.buffer);
}
return this;
}
pos(...items) {
return this.write('pos', ...items);
}
object(...items) {
return this.write('object', ...items);
}
entity(...items) {
return this.write('entity', ...items);
}
entities(...itemLists) {
return this.writeArray('entities', ...itemLists);
}
user(...items) {
return this.write('user', ...items);
}
users(...itemLists) {
return this.writeArray('users', ...itemLists);
}
objectType(name) {
this.buffer[this.offset++] = ['player', 'ball', 'magic', 'magic2', 'boost'].indexOf(name);
return this;
}
teamName(name) {
this.buffer[this.offset++] = ['red', 'blue', 'spectator'].indexOf(name);
return this;
}
team(...items) {
return this.write('team', ...items);
}
round(...items) {
return this.write('round', ...items);
}
finish(...items) {
return this.write('finish', ...items);
}
}
// 0vC4#7152