Add support for rFactor (2.0.10)

This commit is contained in:
mmorrison 2019-02-04 01:11:28 -06:00
parent 0ac80cc139
commit 81750805f6
12 changed files with 103 additions and 54 deletions

View file

@ -250,6 +250,7 @@ Games List
* Red Orchestra 2 (redorchestra2) * Red Orchestra 2 (redorchestra2)
* Redline (redline) * Redline (redline)
* Return to Castle Wolfenstein (rtcw) * Return to Castle Wolfenstein (rtcw)
* rFactor (rfactor)
* Ricochet (ricochet) * Ricochet (ricochet)
* Rise of Nations (riseofnations) * Rise of Nations (riseofnations)
* Rune (rune) * Rune (rune)
@ -430,6 +431,9 @@ as well: `--debug`, `--pretty`, `--socketTimeout 5000`, etc.
Changelog Changelog
--- ---
### 2.0.10
Added support for rFactor
### 2.0.9 ### 2.0.9
Added support for Vice City: Multiplayer Added support for Vice City: Multiplayer

View file

@ -1,29 +1,5 @@
# id | pretty name for readme | protocol | options | extra # id | pretty name for readme | protocol | options | extra
#### TODO:
# cube1|Cube 1|cube|port=28786,port_query_offset=1
# assaultcube|Assault Cube|cube|port_query=28764
# cube2|Cube 2: Sauerbraten|cube|port=28785,port_query_offset=1
# bloodfrontier|Blood Frontier|cube
# arcasimracing|Arca Sim Racing|rfactor|port=34397,port_query_offset=-100
# rfactor|rFactor|rfactor|port=34397,port_query_offset=-100
# bfris|BFRIS|bfris|port=44001
# freelancer|Freelancer|freelancer|port_query=2302
# gr|Ghost Recon|ghostrecon|port=2346,port_query_offset=2
# gtr2|GTR2|gtr2|port=34297,port_query_offset=1
# haze|Haze|haze
# plainsight|Plain Sight|plainsight
# redfaction|Red Faction|redfaction|port_query=7755
# savage|Savage|savage|port_query=11235
# savage2|Savage 2|savage2|port_query=11235
# teeworlds|Teeworlds|teeworlds|port=8303
# tribes|Tribes 1: Starsiege|tribes|port_query=28001
# tribes2|Tribes 2|tribes2|port_query=28000
# worldinconflict|World in Conflict|worldinconflict
7d2d|7 Days to Die|valve|port=26900,port_query_offset=1 7d2d|7 Days to Die|valve|port=26900,port_query_offset=1
ageofchivalry|Age of Chivalry|valve|port=27015 ageofchivalry|Age of Chivalry|valve|port=27015
aoe2|Age of Empires 2|ase|port_query=27224 aoe2|Age of Empires 2|ase|port_query=27224
@ -218,6 +194,7 @@ redorchestraost|Red Orchestra: Ostfront 41-45|gamespy1|port=7757,port_query_offs
redorchestra2|Red Orchestra 2|valve|port=7777,port_query=27015 redorchestra2|Red Orchestra 2|valve|port=7777,port_query=27015
redline|Redline|gamespy1|port_query=25252 redline|Redline|gamespy1|port_query=25252
rtcw|Return to Castle Wolfenstein|quake3|port_query=27960 rtcw|Return to Castle Wolfenstein|quake3|port_query=27960
rfactor|rFactor|rfactor|port=34397,port_query_offset=-100
ricochet|Ricochet|valve|port=27015 ricochet|Ricochet|valve|port=27015
riseofnations|Rise of Nations|gamespy1|port_query=6501 riseofnations|Rise of Nations|gamespy1|port_query=6501
rune|Rune|gamespy1|port=7777,port_query_offset=1 rune|Rune|gamespy1|port=7777,port_query_offset=1

View file

@ -11,7 +11,7 @@
], ],
"main": "lib/index.js", "main": "lib/index.js",
"author": "Michael Morrison", "author": "Michael Morrison",
"version": "2.0.9", "version": "2.0.10",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/sonicsnes/node-gamedig.git" "url": "https://github.com/sonicsnes/node-gamedig.git"

View file

@ -99,6 +99,21 @@ class Core extends EventEmitter {
// because lots of servers prefix with spaces to try to appear first // because lots of servers prefix with spaces to try to appear first
state.name = (state.name || '').trim(); state.name = (state.name || '').trim();
if (typeof state.players === 'number') {
const num = state.players;
state.players = [];
for (let i = 0; i < num; i++) {
state.players.push({});
}
}
if (typeof state.bots === 'number') {
const num = state.bots;
state.bots = [];
for (let i = 0; i < num; i++) {
state.bots.push({});
}
}
if (!('connect' in state)) { if (!('connect' in state)) {
state.connect = '' state.connect = ''
+ (state.gameHost || this.options.host || this.options.address) + (state.gameHost || this.options.host || this.options.address)

View file

@ -26,7 +26,7 @@ class GeneShift extends Core {
state.raw.country = found[1]; state.raw.country = found[1];
state.name = found[4]; state.name = found[4];
state.map = found[5]; state.map = found[5];
state.raw.numplayers = parseInt(found[6]); state.players = parseInt(found[6]);
state.maxplayers = parseInt(found[7]); state.maxplayers = parseInt(found[7]);
// fields[8] is unknown? // fields[8] is unknown?
state.raw.rules = found[9]; state.raw.rules = found[9];
@ -40,10 +40,6 @@ class GeneShift extends Core {
state.raw.mercs = !!parseInt(found[17]); state.raw.mercs = !!parseInt(found[17]);
// fields[18] is unknown? listen server? // fields[18] is unknown? listen server?
state.raw.version = found[19]; state.raw.version = found[19];
for(let i = 0; i < state.raw.numplayers; i++) {
state.players.push({});
}
} }
} }

View file

@ -12,9 +12,7 @@ class Jc2mp extends Gamespy3 {
async run(state) { async run(state) {
await super.run(state); await super.run(state);
if(!state.players.length && parseInt(state.raw.numplayers)) { if(!state.players.length && parseInt(state.raw.numplayers)) {
for(let i = 0; i < parseInt(state.raw.numplayers); i++) { state.players = parseInt(state.raw.numplayers);
state.players.push({});
}
} }
} }
} }

View file

@ -59,9 +59,7 @@ class Minecraft extends Core {
}); });
} }
} }
while(state.players.length < json.players.online) { state.players = json.players.online;
state.players.push({});
}
} }
varIntBuffer(num) { varIntBuffer(num) {

View file

@ -17,12 +17,9 @@ class MumblePing extends Core {
state.raw.versionMinor = reader.uint(1); state.raw.versionMinor = reader.uint(1);
state.raw.versionPatch = reader.uint(1); state.raw.versionPatch = reader.uint(1);
reader.skip(8); reader.skip(8);
state.raw.numplayers = reader.uint(4); state.players = reader.uint(4);
state.maxplayers = reader.uint(4); state.maxplayers = reader.uint(4);
state.raw.allowedbandwidth = reader.uint(4); state.raw.allowedbandwidth = reader.uint(4);
for(let i = 0; i < state.raw.numplayers; i++) {
state.players.push({});
}
} }
} }

View file

@ -35,10 +35,7 @@ class OpenTtd extends Core {
state.password = !!reader.uint(1); state.password = !!reader.uint(1);
state.maxplayers = reader.uint(1); state.maxplayers = reader.uint(1);
state.raw.numplayers = reader.uint(1); state.players = reader.uint(1);
for (let i = 0; i < state.raw.numplayers; i++) {
state.players.push({});
}
state.raw.numspectators = reader.uint(1); state.raw.numspectators = reader.uint(1);
state.map = reader.string(); state.map = reader.string();
state.raw.map_width = reader.uint(2); state.raw.map_width = reader.uint(2);

75
protocols/rfactor.js Normal file
View file

@ -0,0 +1,75 @@
const Core = require('./core');
class Rfactor extends Core {
constructor() {
super();
//this.byteorder = 'be';
}
async run(state) {
const buffer = await this.udpSend('rF_S',b => b);
const reader = this.reader(buffer);
state.raw.gamename = this.readString(reader, 8);
state.raw.fullUpdate = reader.uint(1);
state.raw.region = reader.uint(2);
state.raw.ip = reader.part(4);
state.raw.size = reader.uint(2);
state.raw.version = reader.uint(2);
state.raw.versionRaceCast = reader.uint(2);
state.gamePort = reader.uint(2);
state.raw.queryPort = reader.uint(2);
state.raw.game = this.readString(reader, 20);
state.name = this.readString(reader, 28);
state.map = this.readString(reader, 32);
state.raw.motd = this.readString(reader, 96);
state.raw.packedAids = reader.uint(2);
state.raw.ping = reader.uint(2);
state.raw.packedFlags = reader.uint(1);
state.raw.rate = reader.uint(1);
state.players = reader.uint(1);
state.maxplayers = reader.uint(1);
state.raw.bots = reader.uint(1);
state.raw.packedSpecial = reader.uint(1);
state.raw.damage = reader.uint(1);
state.raw.packedRules = reader.uint(2);
state.raw.credits1 = reader.uint(1);
state.raw.credits2 = reader.uint(2);
this.logger.debug(reader.offset());
state.raw.time = reader.uint(2);
state.raw.laps = reader.uint(2) / 16;
reader.skip(3);
state.raw.vehicles = reader.string();
state.password = !!(state.raw.packedSpecial & 2);
state.raw.raceCast = !!(state.raw.packedSpecial & 4);
state.raw.fixedSetups = !!(state.raw.packedSpecial & 16);
const aids = [
'TractionControl',
'AntiLockBraking',
'StabilityControl',
'AutoShifting',
'AutoClutch',
'Invulnerability',
'OppositeLock',
'SteeringHelp',
'BrakingHelp',
'SpinRecovery',
'AutoPitstop'
];
state.raw.aids = [];
for (let offset = 0; offset < aids.length; offset++) {
if (state.packedAids && (1 << offset)) {
state.raw.aids.push(aids[offset]);
}
}
}
// Consumes bytesToConsume, but only returns string up to the first null
readString(reader, bytesToConsume) {
return reader.string(bytesToConsume).replace(/\0.*$/g,'');
}
}
module.exports = Rfactor;

View file

@ -70,9 +70,7 @@ class Samp extends Core {
} }
} }
if (!gotPlayerData) { if (!gotPlayerData) {
for(let i = 0; i < state.raw.numplayers; i++) { state.players = state.raw.numplayers;
state.players.push({});
}
} }
} }
readString(reader,lenBytes) { readString(reader,lenBytes) {

View file

@ -51,14 +51,8 @@ class Starmade extends Core {
if(typeof data[3] === 'number') state.raw.version = data[3].toFixed(7).replace(/0+$/, ''); if(typeof data[3] === 'number') state.raw.version = data[3].toFixed(7).replace(/0+$/, '');
if(typeof data[4] === 'string') state.name = data[4]; if(typeof data[4] === 'string') state.name = data[4];
if(typeof data[5] === 'string') state.raw.description = data[5]; if(typeof data[5] === 'string') state.raw.description = data[5];
if(typeof data[7] === 'number') state.raw.numplayers = data[7]; if(typeof data[7] === 'number') state.players = data[7];
if(typeof data[8] === 'number') state.maxplayers = data[8]; if(typeof data[8] === 'number') state.maxplayers = data[8];
if('numplayers' in state.raw) {
for(let i = 0; i < state.raw.numplayers; i++) {
state.players.push({});
}
}
} }
} }