Merge branch 'zlib-compression' into packets-1.8

Conflicts:
	lib/protocol.js
This commit is contained in:
Will Franzen 2014-12-31 12:19:49 -06:00
commit 2c02ebfde9
3 changed files with 53 additions and 7 deletions

View file

@ -141,6 +141,8 @@ function createServer(options) {
hash = crypto.createHash("sha1"); hash = crypto.createHash("sha1");
hash.update(serverId); hash.update(serverId);
client.once([states.LOGIN, 0x01], onEncryptionKeyResponse); client.once([states.LOGIN, 0x01], onEncryptionKeyResponse);
client.once([states.LOGIN, 0x03], onCompressionRequest);
client.on( [states.PLAY, 0x46], onCompressionRequest);
client.write(0x01, { client.write(0x01, {
serverId: serverId, serverId: serverId,
publicKey: client.publicKey, publicKey: client.publicKey,
@ -193,6 +195,10 @@ function createServer(options) {
} }
} }
function onCompressionRequest(packet) {
client.compressionThreshold = packet.threshold;
}
function loginClient() { function loginClient() {
var isException = !!server.onlineModeExceptions[client.username.toLowerCase()]; var isException = !!server.onlineModeExceptions[client.username.toLowerCase()];
if (onlineMode == false || isException) { if (onlineMode == false || isException) {

View file

@ -4,6 +4,7 @@ var net = require('net')
, protocol = require('./protocol') , protocol = require('./protocol')
, dns = require('dns') , dns = require('dns')
, createPacketBuffer = protocol.createPacketBuffer , createPacketBuffer = protocol.createPacketBuffer
, compressPacketBuffer = protocol.compressPacketBuffer
, parsePacket = protocol.parsePacket , parsePacket = protocol.parsePacket
, states = protocol.states , states = protocol.states
, debug = protocol.debug , debug = protocol.debug
@ -30,6 +31,7 @@ function Client(isServer) {
this.encryptionEnabled = false; this.encryptionEnabled = false;
this.cipher = null; this.cipher = null;
this.decipher = null; this.decipher = null;
this.compressionThreshold = -1;
this.packetsToParse = {}; this.packetsToParse = {};
this.on('newListener', function(event, listener) { this.on('newListener', function(event, listener) {
var direction = this.isServer ? 'toServer' : 'toClient'; var direction = this.isServer ? 'toServer' : 'toClient';
@ -153,18 +155,38 @@ Client.prototype.write = function(packetId, params) {
packetId = packetId[1]; packetId = packetId[1];
} }
// TODO: Which comes first, encryption or compression?
var finishWriting = function(buffer) {
debug("writing packetId " + packetId + " (0x" + packetId.toString(16) + ")");
debug(params);
var out = this.encryptionEnabled ? new Buffer(this.cipher.update(buffer), 'binary') : buffer;
this.socket.write(out);
return true;
}
var buffer = createPacketBuffer(packetId, this.state, params, this.isServer); var buffer = createPacketBuffer(packetId, this.state, params, this.isServer);
debug("writing packetId " + packetId + " (0x" + packetId.toString(16) + ")"); if(this.compressionThreshold != -1 && buffer.length > this.compressionThreshold) {
debug(params); compressPacketBuffer(buffer, finishWriting);
var out = this.encryptionEnabled ? new Buffer(this.cipher.update(buffer), 'binary') : buffer; } else {
this.socket.write(out); finishWriting(buffer);
return true; }
}; };
Client.prototype.writeRaw = function(buffer, shouldEncrypt) { Client.prototype.writeRaw = function(buffer, shouldEncrypt) {
if (shouldEncrypt === null) { if (shouldEncrypt === null) {
shouldEncrypt = true; shouldEncrypt = true;
} }
var out = (shouldEncrypt && this.encryptionEnabled) ? new Buffer(this.cipher.update(buffer), 'binary') : buffer;
this.socket.write(out); var finishWriting = function(buffer) {
var out = (shouldEncrypt && this.encryptionEnabled) ? new Buffer(this.cipher.update(buffer), 'binary') : buffer;
this.socket.write(out);
};
if(this.compressionThreshold != -1 && buffer.length > this.compressionThreshold) {
compressPacketBuffer(buffer, finishWriting);
} else {
finishWriting(buffer);
}
}; };

View file

@ -1,5 +1,6 @@
var assert = require('assert'); var assert = require('assert');
var util = require('util'); var util = require('util');
var zlib = require('zlib');
var STRING_MAX_LENGTH = 240; var STRING_MAX_LENGTH = 240;
var SRV_STRING_MAX_LENGTH = 32767; var SRV_STRING_MAX_LENGTH = 32767;
@ -58,6 +59,9 @@ var packets = {
success: {id: 0x02, fields: [ success: {id: 0x02, fields: [
{ name: "uuid", type: "string" }, { name: "uuid", type: "string" },
{ name: "username", type: "string" } { name: "username", type: "string" }
]},
compress: { id: 0x03, fields: [
{ name: "threshold", type: "varint"}
]} ]}
}, },
toServer: { toServer: {
@ -1408,6 +1412,19 @@ function createPacketBuffer(packetId, state, params, isServer) {
return buffer; return buffer;
} }
function compressPacketBuffer(buffer, callback) {
var dataLength = buffer.length;
var packetLength = dataLength + sizeOfVarInt(dataLength);
var data = zlib.deflateRaw(buffer, function(compressedBuffer) {
var size = sizeOfVarInt(packetLength) + sizeOfVarInt(packetLength) + compressedBuffer.length;
var packetBuffer = new Buffer(size);
var offset = writeVarInt(packetLength, packetBuffer, 0);
offset = writeVarInt(dataLength, packetBuffer, offset);
writeVarInt(compressedBuffer, packetBuffer, offset);
callback(packetBuffer);
});
}
function parsePacket(buffer, state, isServer, packetsToParse) { function parsePacket(buffer, state, isServer, packetsToParse) {
if (state == null) state = states.PLAY; if (state == null) state = states.PLAY;
var cursor = 0; var cursor = 0;
@ -1484,6 +1501,7 @@ module.exports = {
sessionVersion: 13, sessionVersion: 13,
parsePacket: parsePacket, parsePacket: parsePacket,
createPacketBuffer: createPacketBuffer, createPacketBuffer: createPacketBuffer,
compressPacketBuffer: compressPacketBuffer,
STRING_MAX_LENGTH: STRING_MAX_LENGTH, STRING_MAX_LENGTH: STRING_MAX_LENGTH,
packetIds: packetIds, packetIds: packetIds,
packetNames: packetNames, packetNames: packetNames,