Skip to content

Commit

Permalink
comments and restructure
Browse files Browse the repository at this point in the history
  • Loading branch information
kmpm committed Nov 22, 2011
1 parent 2f98756 commit 8950eef
Showing 1 changed file with 167 additions and 123 deletions.
290 changes: 167 additions & 123 deletions mcquery.js
@@ -1,107 +1,10 @@
var dgram = require('dgram'); var dgram = require('dgram');




var CHALLENGE_TYPE=0x09; var CHALLENGE_TYPE=0x09;
var STAT_TYPE=0x00; var STAT_TYPE=0x00;


var counter =0; var counter =0;


function generateToken(){
counter +=1;
return 10000 + counter;

}

function makePacket(type,session, payloadBuffer){
var pLength = typeof(payloadBuffer)==='undefined'? 0 : payloadBuffer.length;
var sLength = typeof(session.sessionToken)==='undefined'? 0: 4;
var b = new Buffer(7 + sLength+pLength);
b.writeUInt8(0xFE, 0);
b.writeUInt8(0xFD, 1);
b.writeUInt8(type, 2);
b.writeUInt32BE(session.idToken, 3);
if(sLength>0){
b.writeUInt32BE(session.sessionToken, 7);
}
if(pLength>0){
payloadBuffer.copy(b, 7+sLength +1);
}
return b;
}


function readPacket(data){
var res = {
type:data.readUInt8(0),
idToken:data.readUInt32BE(1),
};
data = data.slice(5);
if(res.type===CHALLENGE_TYPE){
res.sessionToken=parseInt(data.toString());
}
else if(res.type===STAT_TYPE){
var r = readString(data);
if(r.text !== 'splitnum'){
//basic stat
res.hostname = r.text;
r = readString(data, r.offset);
res.gametype = r.text;

r = readString(data, r.offset);
res.map = r.text;

r = readString(data, r.offset);
res.numplayers = parseInt(r.text);

r = readString(data, r.offset);
res.maxplayers = parseInt(r.text);

res.hostport = data.readUInt16LE(r.offset);
r = readString(data, r.offset +2);
res.hostip = r.text;
}
else {
var offset=r.offset;
res.splitnum = r.text;
res.key_val_start = data.readUInt16LE(offset);offset+=2;
var key;
var value;
while(data.readUInt16LE(offset) !== 256){
r = readString(data, offset); offset=r.offset;
key = r.text;
r = readString(data, offset); offset=r.offset;
value = r.text;
res[key]=value;
}
res.key_val_end = data.readUInt16LE(offset);offset+=2;

r = readString(data, offset); offset=r.offset;
key = r.text;
var players = [];
res[key]=players;
offset+=1;
r=readString(data, offset); offset=r.offset;
while(r.text.length>=1){
players.push(r.text);
r=readString(data, offset); offset=r.offset;
}

}

}
return res;
}

function readString(data, offset){
var o = typeof(offset)==='undefined'? 0: offset;
var start=o+0;
while(data.readUInt8(o)!==0x0){
o+=1;
}
return {text:data.toString('utf-8', start, o), offset:o+1};
}

var Query = module.exports = function Query(){ var Query = module.exports = function Query(){
var socket = dgram.createSocket('udp4'); var socket = dgram.createSocket('udp4');
var m = this; var m = this;
Expand All @@ -115,6 +18,14 @@ var Query = module.exports = function Query(){
deQueue(res); deQueue(res);
}); });


/**
* Start a new session with given host at port
* @param {String} hostname or ip
* @param {Number} port
* @param {function} function(err, session)
*
* @api public
*/
this.startSession = function(host, port, callback){ this.startSession = function(host, port, callback){
var session = {host:host, port:port}; var session = {host:host, port:port};
if (! m.online){ if (! m.online){
Expand All @@ -138,8 +49,58 @@ var Query = module.exports = function Query(){
callback(null, session); callback(null, session);
}); });
} }
} };//end startSession


/**
* Request basic stat information using session
* @param {Object} a session object created by startSession
* @param {funciton} function(err, statinfo)
*
* @api public
*/
this.basic_stat = function(session, callback){
this.send(session, STAT_TYPE, callback);
};//end basic_stat


/**
* Request full stat information using session
* @param {Object} a session object created by startSession
* @param {funciton} function(err, statinfo)
*
* @api public
*/
this.full_stat = function(session, callback){
var b = new Buffer(4);
b.fill(0);
this.send(session, STAT_TYPE, b, function(err, res){
if(err)callback(err);
else{
delete res.type;
delete res.idToken;
delete res.rinfo;
callback(null, res);
}
});
};//end full_stat



/*
* Stop listening for responses
* Clears the requestQueue
*
* @api public
*/
this.close = function(){
socket.close();
m.online=false;
m.requestQueue={};
};//end close

/**
* Add a request to the queue
*/
function addQueue(session, type, callback){ function addQueue(session, type, callback){
var q; var q;
if(typeof(m.requestQueue[session.idToken])==='undefined'){ if(typeof(m.requestQueue[session.idToken])==='undefined'){
Expand All @@ -160,6 +121,10 @@ var Query = module.exports = function Query(){
q[type]={callback:callback, timeout:t}; q[type]={callback:callback, timeout:t};
} }



/**
* Check for requests matching the response given
*/
function deQueue(res){ function deQueue(res){
var key = res.idToken; var key = res.idToken;
if(typeof(m.requestQueue[key])==='undefined'){ if(typeof(m.requestQueue[key])==='undefined'){
Expand All @@ -180,26 +145,9 @@ var Query = module.exports = function Query(){
fn(null, res); fn(null, res);
} }


this.basic_stat = function(session, callback){ /*
this.send(session, STAT_TYPE, callback); * Send a request and put it on the queue
}; */



this.full_stat = function(session, callback){
var b = new Buffer(4);
b.fill(0);
this.send(session, STAT_TYPE, b, function(err, res){
if(err)callback(err);
else{
delete res.type;
delete res.idToken;
delete res.rinfo;
callback(null, res);
}
});
}

this.send = function(session, type, payloadBuffer, callback){ this.send = function(session, type, payloadBuffer, callback){
if(arguments.length===3){ if(arguments.length===3){
callback = arguments[2]; callback = arguments[2];
Expand All @@ -214,14 +162,110 @@ var Query = module.exports = function Query(){
} }
}); });
}; };
};// end Query


this.close = function(){ /*
socket.close(); * Generate a idToken
m.online=false; */
function generateToken(){
counter +=1;
return 10000 + counter;
}


/*
* Create a request packet
* @param {Number} request type
* @param {Object} session information
* @param {Buffer} optional payload
*/
function makePacket(type,session, payloadBuffer){
var pLength = typeof(payloadBuffer)==='undefined'? 0 : payloadBuffer.length;
var sLength = typeof(session.sessionToken)==='undefined'? 0: 4;
var b = new Buffer(7 + sLength+pLength);
b.writeUInt8(0xFE, 0);
b.writeUInt8(0xFD, 1);
b.writeUInt8(type, 2);
b.writeUInt32BE(session.idToken, 3);
if(sLength>0){
b.writeUInt32BE(session.sessionToken, 7);
} }

if(pLength>0){
payloadBuffer.copy(b, 7+sLength +1);
}
return b;
}




}; /*
* Parse a response buffer and return an object
*/
function readPacket(data){
var res = {
type:data.readUInt8(0),
idToken:data.readUInt32BE(1),
};
data = data.slice(5);
if(res.type===CHALLENGE_TYPE){
res.sessionToken=parseInt(data.toString());
}
else if(res.type===STAT_TYPE){
var r = readString(data);
if(r.text !== 'splitnum'){
//basic stat
res.hostname = r.text;
r = readString(data, r.offset);
res.gametype = r.text;

r = readString(data, r.offset);
res.map = r.text;

r = readString(data, r.offset);
res.numplayers = parseInt(r.text);

r = readString(data, r.offset);
res.maxplayers = parseInt(r.text);

res.hostport = data.readUInt16LE(r.offset);
r = readString(data, r.offset +2);
res.hostip = r.text;
}
else {
var offset=r.offset;
res.splitnum = r.text;
res.key_val_start = data.readUInt16LE(offset);offset+=2;
var key;
var value;
while(data.readUInt16LE(offset) !== 256){
r = readString(data, offset); offset=r.offset;
key = r.text;
r = readString(data, offset); offset=r.offset;
value = r.text;
res[key]=value;
}
res.key_val_end = data.readUInt16LE(offset);offset+=2;

r = readString(data, offset); offset=r.offset;
key = r.text;
var players = [];
res[key]=players;
offset+=1;
r=readString(data, offset); offset=r.offset;
while(r.text.length>=1){
players.push(r.text);
r=readString(data, offset); offset=r.offset;
}
}
}
return res;
}//end readPacket




function readString(data, offset){
var o = typeof(offset)==='undefined'? 0: offset;
var start=o+0;
while(data.readUInt8(o)!==0x0){
o+=1;
}
return {text:data.toString('utf-8', start, o), offset:o+1};
}

0 comments on commit 8950eef

Please sign in to comment.