2014-10-29 08:02:03 +01:00
|
|
|
var async = require('async');
|
|
|
|
|
|
|
|
module.exports = require('./core').extend({
|
|
|
|
init: function() {
|
|
|
|
this._super();
|
|
|
|
this.encoding = 'latin1';
|
|
|
|
},
|
|
|
|
run: function(state) {
|
|
|
|
var self = this;
|
|
|
|
var decoded;
|
|
|
|
|
|
|
|
async.series([
|
|
|
|
function(c) {
|
|
|
|
self.query(['serverInfo'], function(data) {
|
|
|
|
if(self.debug) console.log(data);
|
|
|
|
if(data.shift() != 'OK') return self.fatal('Missing OK');
|
|
|
|
|
|
|
|
state.raw.name = data.shift();
|
|
|
|
state.raw.numplayers = parseInt(data.shift());
|
|
|
|
state.maxplayers = parseInt(data.shift());
|
|
|
|
state.raw.gametype = data.shift();
|
|
|
|
state.map = data.shift();
|
|
|
|
state.raw.roundsplayed = parseInt(data.shift());
|
|
|
|
state.raw.roundstotal = parseInt(data.shift());
|
|
|
|
|
|
|
|
var teamCount = data.shift();
|
|
|
|
state.raw.teams = [];
|
|
|
|
for(var i = 0; i < teamCount; i++) {
|
|
|
|
var tickets = parseFloat(data.shift());
|
|
|
|
state.raw.teams.push({
|
|
|
|
tickets:tickets
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
state.raw.targetscore = parseInt(data.shift());
|
|
|
|
data.shift();
|
|
|
|
state.raw.ranked = (data.shift() == 'true');
|
|
|
|
state.raw.punkbuster = (data.shift() == 'true');
|
|
|
|
state.password = (data.shift() == 'true');
|
|
|
|
state.raw.uptime = parseInt(data.shift());
|
|
|
|
state.raw.roundtime = parseInt(data.shift());
|
|
|
|
if(self.isBadCompany2) {
|
|
|
|
data.shift();
|
|
|
|
data.shift();
|
|
|
|
}
|
|
|
|
state.raw.ip = data.shift();
|
|
|
|
state.raw.punkbusterversion = data.shift();
|
|
|
|
state.raw.joinqueue = (data.shift() == 'true');
|
|
|
|
state.raw.region = data.shift();
|
|
|
|
if(!self.isBadCompany2) {
|
|
|
|
state.raw.pingsite = data.shift();
|
|
|
|
state.raw.country = data.shift();
|
|
|
|
state.raw.quickmatch = (data.shift() == 'true');
|
|
|
|
}
|
|
|
|
|
|
|
|
c();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
function(c) {
|
|
|
|
self.query(['version'], function(data) {
|
|
|
|
if(self.debug) console.log(data);
|
|
|
|
if(data[0] != 'OK') return self.fatal('Missing OK');
|
|
|
|
|
|
|
|
state.raw.version = data[2];
|
|
|
|
|
|
|
|
c();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
function(c) {
|
|
|
|
self.query(['listPlayers','all'], function(data) {
|
|
|
|
if(self.debug) console.log(data);
|
|
|
|
if(data.shift() != 'OK') return self.fatal('Missing OK');
|
|
|
|
|
|
|
|
var fieldCount = parseInt(data.shift());
|
|
|
|
var fields = [];
|
|
|
|
for(var i = 0; i < fieldCount; i++) {
|
|
|
|
fields.push(data.shift());
|
|
|
|
}
|
|
|
|
var numplayers = data.shift();
|
|
|
|
for(var i = 0; i < numplayers; i++) {
|
|
|
|
var player = {};
|
|
|
|
fields.forEach(function(key) {
|
|
|
|
var value = data.shift();
|
|
|
|
|
|
|
|
if(key == 'teamId') key = 'team';
|
|
|
|
else if(key == 'squadId') key = 'squad';
|
|
|
|
|
|
|
|
if(
|
|
|
|
key == 'kills'
|
|
|
|
|| key == 'deaths'
|
|
|
|
|| key == 'score'
|
|
|
|
|| key == 'rank'
|
|
|
|
|| key == 'team'
|
|
|
|
|| key == 'squad'
|
|
|
|
|| key == 'ping'
|
|
|
|
|| key == 'type'
|
|
|
|
) {
|
|
|
|
value = parseInt(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
player[key] = value;
|
|
|
|
});
|
|
|
|
state.players.push(player);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.finish(state);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
]);
|
|
|
|
},
|
|
|
|
query: function(params,c) {
|
|
|
|
var self = this;
|
|
|
|
this.tcpSend(buildPacket(params), function(data) {
|
|
|
|
var decoded = self.decodePacket(data);
|
|
|
|
if(!decoded) return false;
|
|
|
|
c(decoded);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
decodePacket: function(buffer) {
|
|
|
|
if(buffer.length < 8) return false;
|
|
|
|
var reader = this.reader(buffer);
|
|
|
|
var header = reader.uint(4);
|
|
|
|
var totalLength = reader.uint(4);
|
|
|
|
if(buffer.length < totalLength) return false;
|
|
|
|
|
|
|
|
var paramCount = reader.uint(4);
|
|
|
|
var params = [];
|
|
|
|
for(var i = 0; i < paramCount; i++) {
|
|
|
|
var len = reader.uint(4);
|
|
|
|
params.push(reader.string({length:len}));
|
|
|
|
var strNull = reader.uint(1);
|
|
|
|
}
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function buildPacket(params) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
var paramBuffers = [];
|
|
|
|
params.forEach(function(param) {
|
|
|
|
paramBuffers.push(new Buffer(param,'utf8'));
|
|
|
|
});
|
|
|
|
|
|
|
|
var totalLength = 12;
|
|
|
|
paramBuffers.forEach(function(paramBuffer) {
|
|
|
|
totalLength += paramBuffer.length+1+4;
|
|
|
|
});
|
|
|
|
|
|
|
|
var b = new Buffer(totalLength);
|
|
|
|
b.writeUInt32LE(0,0);
|
|
|
|
b.writeUInt32LE(totalLength,4);
|
|
|
|
b.writeUInt32LE(params.length,8);
|
|
|
|
var offset = 12;
|
|
|
|
paramBuffers.forEach(function(paramBuffer) {
|
|
|
|
b.writeUInt32LE(paramBuffer.length, offset); offset += 4;
|
|
|
|
paramBuffer.copy(b, offset); offset += paramBuffer.length;
|
|
|
|
b.writeUInt8(0, offset); offset += 1;
|
|
|
|
});
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|