Fix tons of gamespy 3 bugs arising from other server implementations

This commit is contained in:
Michael Morrison 2014-02-01 09:46:34 -06:00
parent 6680c2dfa2
commit 896b707ba9
1 changed files with 84 additions and 52 deletions

View File

@ -1,78 +1,111 @@
var async = require('async');
module.exports = require('./core').extend({ module.exports = require('./core').extend({
init: function() { init: function() {
this._super(); this._super();
this.sessionId = 1; this.sessionId = 1;
this.encoding = 'latin1'; this.encoding = 'latin1';
this.byteorder = 'be'; this.byteorder = 'be';
this.noChallenge = false;
}, },
run: function(state) { run: function(state) {
var self = this; var self = this;
var challenge,packets;
this.sendPacket(9,false,false,false,function(buffer) { async.series([
var reader = self.reader(buffer); function(c) {
reader.skip(5); if(self.noChallenge) return c();
var challenge = parseInt(reader.string()); self.sendPacket(9,false,false,false,function(buffer) {
var reader = self.reader(buffer);
reader.skip(5);
challenge = parseInt(reader.string());
c();
});
},
function(c) {
self.sendPacket(0,challenge,new Buffer([0xff,0xff,0xff,0x01]),true,function(b) {
packets = b;
c();
});
},
function(c) {
// iterate over the received packets
// the first packet will start off with k/v pairs, followed with data fields
// the following packets will only have data fields
var data = {};
self.sendPacket(0,challenge,new Buffer([0xff,0xff,0xff,0x01]),true,function(buffer) { for(var iPacket = 0; iPacket < packets.length; iPacket++) {
var packet = packets[iPacket];
var reader = self.reader(packet);
var reader = self.reader(buffer); if(self.debug) {
console.log("+++"+packet.toString('hex'));
console.log(":::"+packet.toString('ascii'));
}
while(!reader.done()) { if(iPacket == 0) {
var key = reader.string(); while(!reader.done()) {
if(!key) break; var key = reader.string();
var value = reader.string(); if(!key) break;
var value = reader.string();
// reread the next line if we hit the weird ut3 bug
if(value == 'p1073741829') value = reader.string(); // reread the next line if we hit the weird ut3 bug
if(value == 'p1073741829') value = reader.string();
state.raw[key] = value; state.raw[key] = value;
} }
}
while(!reader.done()) {
var mode = reader.string(); var firstMode = true;
if(mode.charCodeAt(0) <= 2) mode = mode.substring(1); while(!reader.done()) {
if(!mode) continue; var mode = reader.string();
var offset = 0; if(mode.charCodeAt(0) <= 2) mode = mode.substring(1);
reader.skip(1); if(!mode) continue;
var offset = 0;
while(!reader.done()) { if(iPacket != 0 && firstMode) offset = reader.uint(1);
var item = reader.string(); reader.skip(1);
if(!item) break; firstMode = false;
if( while(!reader.done()) {
mode == 'player_' var item = reader.string();
|| mode == 'score_' if(!item) break;
|| mode == 'ping_'
|| mode == 'team_' if(
|| mode == 'deaths_' mode == 'player_'
|| mode == 'pid_' || mode == 'score_'
) { || mode == 'ping_'
if(state.players.length <= offset) || mode == 'team_'
state.players.push({}); || mode == 'deaths_'
|| mode == 'pid_'
) {
if(state.players.length <= offset)
state.players.push({});
}
if(mode == 'player_') state.players[offset].name = item;
if(mode == 'score_') state.players[offset].score = parseInt(item);
if(mode == 'ping_') state.players[offset].ping = parseInt(item);
if(mode == 'team_') state.players[offset].team = parseInt(item);
if(mode == 'deaths_') state.players[offset].deaths = parseInt(item);
if(mode == 'pid_') state.players[offset].pid = item;
offset++;
} }
if(mode == 'player_') state.players[offset].name = item;
if(mode == 'score_') state.players[offset].score = item;
if(mode == 'ping_') state.players[offset].ping = item;
if(mode == 'team_') state.players[offset].team = item;
if(mode == 'deaths_') state.players[offset].deaths = item;
if(mode == 'pid_') state.players[offset].pid = item;
offset++;
} }
} }
if('hostname' in state.raw) state.name = state.raw.hostname; if('hostname' in state.raw) state.name = state.raw.hostname;
if('map' in state.raw) state.map = state.raw.map; else if('servername' in state.raw) state.name = state.raw.servername;
if('mapname' in state.raw) state.map = state.raw.mapname;
if(state.raw.password == '1') state.password = true;
if('maxplayers' in state.raw) state.maxplayers = parseInt(state.raw.maxplayers); if('maxplayers' in state.raw) state.maxplayers = parseInt(state.raw.maxplayers);
self.finish(state); self.finish(state);
}
}); ]);
});
}, },
sendPacket: function(type,challenge,payload,assemble,c) { sendPacket: function(type,challenge,payload,assemble,c) {
var self = this; var self = this;
var challengeLength = challenge === false ? 0 : 4; var challengeLength = (this.noChallenge || challenge === false) ? 0 : 4;
var payloadLength = payload ? payload.length : 0; var payloadLength = payload ? payload.length : 0;
var b = new Buffer(7 + challengeLength + payloadLength); var b = new Buffer(7 + challengeLength + payloadLength);
@ -114,8 +147,7 @@ module.exports = require('./core').extend({
} }
list.push(packets[i]); list.push(packets[i]);
} }
var assembled = Buffer.concat(list); c(list);
c(assembled);
return true; return true;
}); });
} }