Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var bigint = require('bigint');
- function encodeName(s) {
- var l = bigint(0);
- for (var i = 0; i < s.length && i < 12; i++) {
- var c = s.charCodeAt(i);
- l = l.mul(37);
- l = (c >= 65 && c <= 90) ? l.add(l.add(c - 65)) : (c >= 97 && c <= 122) ? l.add(l.add(c - 97)) : (c >= 48 && c <= 57) ? l.add(27 + c - 48) : bigint(0);
- }
- for (;
- (l.mod(37).eq(0)) && l.ne(0); l = l.div(37));
- return l.toBuffer();
- }
- function getSizeForType(type) {
- switch (type) {
- default:
- case 'byte':
- return 1;
- case 'short':
- return 2;
- case 'medium':
- return 3;
- case 'int':
- return 4;
- case 'long':
- return 8;
- }
- }
- function toArray(val, size) {
- var shift, _ref, _results, _step;
- _results = [];
- for (shift = 0, _ref = (size - 1) << 3, _step = 8;
- 0 <= _ref ? shift <= _ref : shift >= _ref; shift += _step)
- _results.push((val >> shift) & 0xFF);
- return _results;
- }
- function PacketBuffer(buffer) {
- if (typeof buffer === 'number') {
- buffer = new Buffer(buffer);
- for (var i = 0; i < buffer.length; i++)
- buffer[i] = 0;
- }
- this.buffer = buffer;
- this.position = 0;
- this.bitPosition = 0;
- this.bitAccess = false;
- }
- require('util').inherits(PacketBuffer, require('events').EventEmitter);
- PacketBuffer.prototype.getByte = function getByte(index) {
- if (this.bitAccess) throw 'Can\'t do that in bit mode!';
- return this.buffer[index || this.position++];
- };
- PacketBuffer.prototype.getShort = function getShort(index) {
- var b1 = this.getByte(index) & 0xFF;
- var b2 = this.getByte(index) & 0xFF;
- return (b1 << 8) | b2;
- }
- PacketBuffer.prototype.getInt = function getInt(index) {
- var b1 = this.getByte(index) & 0xFF;
- var b2 = this.getByte(index) & 0xFF;
- var b3 = this.getByte(index) & 0xFF;
- var b4 = this.getByte(index) & 0xFF;
- return (b1 << 24) | (b2 << 16) |(b3 << 8) | b4 ;
- }
- PacketBuffer.prototype.getString = function getString(index) {
- var string = '';
- var read = 0;
- while((read = this.getByte() & 0xFF) != 10) {
- string += String.fromCharCode(read);
- }
- return string;
- }
- PacketBuffer.prototype.remaining = function () {
- return this.buffer.length - this.position;
- }
- PacketBuffer.prototype.putByte = function putByte(index, value) {
- if (this.bitAccess) throw 'Can\'t do that in bit mode!';
- if (value !== undefined) {
- this.buffer[index] = value;
- } else {
- this.buffer[this.position++] = index;
- }
- return this;
- };
- PacketBuffer.prototype.startBitAccess = function () {
- this.bitAccess = true;
- this.bitPosition = this.position * 8;
- return this;
- };
- PacketBuffer.prototype.finishBitAccess = function () {
- this.bitAccess = false;
- this.position = this.size = Math.ceil((this.bitPosition + 7) / 8)
- return this;
- };
- PacketBuffer.prototype.putBits = function putBits(numBits, value) {
- if (!this.bitAccess) throw 'Can\'t do that in byte mode!';
- var bytePos = this.bitPosition >> 3;
- var bitOffset = 8 - (this.bitPosition & 7);
- this.bitPosition += numBits;
- for (; numBits > bitOffset; bitOffset = 8) {
- this.buffer[bytePos] &= ~ ((1 << numBits) - 1);
- this.buffer[bytePos++] |= (value >> (numBits - bitOffset)) & ((1 << numBits) - 1);
- numBits -= bitOffset;
- }
- if (numBits == bitOffset) {
- this.buffer[bytePos] &= ~ ((1 << numBits) - 1);
- this.buffer[bytePos] |= value & ((1 << numBits) - 1);
- } else {
- this.buffer[bytePos] &= ~ (((1 << numBits) - 1) << (bitOffset - numBits));
- this.buffer[bytePos] |= (value & ((1 << numBits) - 1)) << (bitOffset - numBits);
- }
- return this;
- };
- PacketBuffer.prototype.get = function (info) {
- switch (info.type) {
- case 'short': return this.getShort() & 0xFFFF;
- case 'byte': return this.getByte() & 0xFF;
- case 'int': return this.getInt();
- case 'string': return this.getString();
- }
- if (typeof info.type === 'object') {
- var retval = [];
- var type = info.type[0];
- var nelem = info.type[1];
- for(var i = 0; i < nelem; i++) {
- retval.push(this.get({type:type}));
- }
- return retval;
- }
- }
- PacketBuffer.prototype.put = function (info, data) {
- if (info.value !== undefined) {
- data = info.value;
- }
- if (info.type === 'bits') {
- this.putBits(info.size, data);
- return this;
- }
- if (info.type === 'string') {
- for (var i = 0; i < data.length; i++)
- this.putByte(data.charCodeAt(i));
- this.putByte(10);
- return this;
- }
- if (info.type === 'name') {
- var tmp = encodeName(data);
- for (var i = 0; i < 8; i++)
- this.putByte(0);
- this.position -= tmp.length;
- tmp.copy(this.buffer, this.position, 0, tmp.length);
- this.position += tmp.length;
- return;
- }
- var size = getSizeForType(info.type);
- var tmp = toArray(data, size);
- switch (info.transform) {
- case 'a':
- case 'add':
- tmp[0] += 128;
- break;
- }
- switch (info.order) {
- default:
- case 'big':
- case 'network':
- tmp = tmp.reverse();
- break;
- }
- for (var j = 0; j < size; j++) {
- if (info.position !== undefined) {
- this.putByte(info.position, tmp[j]);
- } else {
- this.putByte(tmp[j]);
- }
- }
- return this;
- };
- PacketBuffer.prototype.finallyPut = function (info, dataCB) {
- oldPos = this.position;
- this.put(info, 0);
- this.on('pack', function () {
- info.position = oldPos;
- this.put(info, dataCB(this.position, info.position + getSizeForType(info.type)));
- });
- return this;
- };
- PacketBuffer.prototype.pack = function pack(info, data) {
- var i = 0;
- data = data || [];
- this.emit('pack');
- for (entry in info)
- this.put(info[entry], data[i++]);
- return this.buffer.slice(0, this.position);
- };
- PacketBuffer.prototype.unpack = function unpack(info) {
- var i = 0;
- var packet = {};
- for (entry in info)
- packet[entry] = this.get(info[entry]);
- return packet;
- }
- module.exports.PacketBuffer = PacketBuffer;
- function Builder () {
- this.data = [];
- }
- Builder.prototype.put = function (val,size,order,transform) {
- switch (typeof val) {
- case 'string':
- for(var i = 0; i < val.length; i++) {
- this.data = this.data.concat(val.charCodeAt(i));
- }
- break;
- case 'number':
- if(val > 255 || size !== undefined) {
- if(size === undefined) throw 'you must define a size!';
- val = toArray(val,size);
- switch (transform) {
- case 'A':
- case 'add':
- val[0]+=128;
- break;
- }
- if(order === 'big' || order === 'network' ||order === undefined) {
- val = val.reverse();
- }
- }
- default:
- this.data = this.data.concat(val);
- break;
- }
- return this;
- };
- Builder.prototype.build = function () {
- return new Buffer(this.data);
- };
- module.exports.builder = function () { return new Builder()};
- module.exports.encodeName = encodeName;
Add Comment
Please, Sign In to add comment