From f062e03271fb20a82aa1aba3ff6ebe6a8b7a89ad Mon Sep 17 00:00:00 2001 From: Michael Morrison Date: Wed, 10 Jul 2013 07:13:04 -0500 Subject: [PATCH] Improve source protocol to support all available features --- package.json | 3 ++- protocols/core.js | 1 - protocols/gamespy3.js | 4 ++-- protocols/source.js | 52 ++++++++++++++++++++++++++++++++++++++----- reader.js | 6 ++++- 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index f9ce70e..69c9d9a 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dependencies": { "iconv": ">=2.0.6", "bignum": ">=0.6.1", - "async": ">=0.2.9" + "async": ">=0.2.9", + "compressjs": ">=1.0.0" } } diff --git a/protocols/core.js b/protocols/core.js index 57175b3..90d250b 100644 --- a/protocols/core.js +++ b/protocols/core.js @@ -2,7 +2,6 @@ var EventEmitter = require('events').EventEmitter, dns = require('dns'), async = require('async'), Class = require('../Class'), - Bignum = require('bignum'), Reader = require('../reader'); module.exports = Class.extend(EventEmitter,{ diff --git a/protocols/gamespy3.js b/protocols/gamespy3.js index 1ae4469..f624ab4 100644 --- a/protocols/gamespy3.js +++ b/protocols/gamespy3.js @@ -80,7 +80,7 @@ module.exports = require('./core').extend({ id = id & 0x7f; if(last) numPackets = id+1; - packets[id] = buffer; + packets[id] = buffer.slice(16); if(!numPackets || Object.keys(packets).length != numPackets) return; @@ -91,7 +91,7 @@ module.exports = require('./core').extend({ self.error('Missing packet #'+i); return true; } - list.push(packets[i].slice(16)); + list.push(packets[i]); } var assembled = Buffer.concat(list); c(assembled); diff --git a/protocols/source.js b/protocols/source.js index 6b22f93..0fd19a6 100644 --- a/protocols/source.js +++ b/protocols/source.js @@ -1,4 +1,5 @@ -var async = require('async'); +var async = require('async'), + Bzip2 = require('compressjs').Bzip2; module.exports = require('./core').extend({ init: function() { @@ -15,7 +16,7 @@ module.exports = require('./core').extend({ async.series([ function(c) { self.sendPacket( - 0x54,false,new Buffer('Source Engine Query'), + 0x54,false,new Buffer('Source Engine Query\0'), self.goldsrc ? 0x6D : 0x49, function(b) { var reader = self.reader(b); @@ -136,13 +137,54 @@ module.exports = require('./core').extend({ return true; } + var numPackets = 0; var packets = []; + var bzip = false; this.udpSend(b,function(buffer) { var header = buffer.readInt32LE(0); - if(header == -1) return received(buffer.slice(4)); + if(header == -1) { + // full package + return received(buffer.slice(4)); + } + if(header == -2) { + // partial package + var uid = buffer.readUInt32LE(4); + if(!self.goldsrc && uid & 0x80000000) bzip = true; - // partial pack - console.log(buffer); + var id,payload; + if(self.goldsrc) { + id = buffer.readUInt8(8); + numPackets = id & 0x0f; + id = id & 0xf0 >> 4; + payload = buffer.slice(9); + } else { + numPackets = buffer.readUInt8(8); + id = buffer.readUInt8(9); + if(id == 0 && bzip) payload = buffer.slice(20); + else payload = buffer.slice(12); + } + + console.log(id,numPackets); + + packets[id] = payload; + + if(!numPackets || Object.keys(packets).length != numPackets) return; + + // assemble the parts + var list = []; + for(var i = 0; i < numPackets; i++) { + if(!(i in packets)) { + self.error('Missing packet #'+i); + return true; + } + list.push(packets[i]); + } + var assembled = Buffer.concat(list); + var payload = assembled.slice(4); + if(bzip) payload = Bzip2.uncompressFile(payload); + + return received(payload); + } }); } }); diff --git a/reader.js b/reader.js index f27885e..8a3e043 100644 --- a/reader.js +++ b/reader.js @@ -1,4 +1,8 @@ -var Iconv = require('iconv').Iconv; +var Iconv = require('iconv').Iconv, + Bignum = require('bignum'); + + + var Iconv_converters = {}; function getIconv(from) { var to = 'utf-8';