diff --git a/README.md b/README.md index 8b53ab5..029deb6 100644 --- a/README.md +++ b/README.md @@ -160,11 +160,13 @@ Games List * Fortress Forever (fortressforever) * Flashpoint (flashpoint) [[Separate Query Port](#separate-query-port)] * Frontlines: Fuel of War (ffow) [[Separate Query Port](#separate-query-port)] +* FiveM (fivem) * Garry's Mod (garrysmod) * Ghost Recon: Advanced Warfighter (graw) [[Separate Query Port](#separate-query-port)] * Ghost Recon: Advanced Warfighter 2 (graw2) [[Separate Query Port](#separate-query-port)] * Giants: Citizen Kabuto (giantscitizenkabuto) [[Separate Query Port](#separate-query-port)] * Global Operations (globaloperations) [[Separate Query Port](#separate-query-port)] +* Geneshift (geneshift) * GoldenEye: Source (ges) * Gore (gore) [[Separate Query Port](#separate-query-port)] * Gunman Chronicles (gunmanchronicles) @@ -173,7 +175,7 @@ Games List * Halo (halo) * Halo 2 (halo2) * Heretic 2 (heretic2) [[Separate Query Port](#separate-query-port)] -* Hexen World (hexenworld) [[Separate Query Port](#separate-query-port)] +* Hexen 2 (hexen2) [[Separate Query Port](#separate-query-port)] * The Hidden: Source (hidden) * Hidden and Dangerous 2 (had2) [[Separate Query Port](#separate-query-port)] * Homefront (homefront) diff --git a/games.txt b/games.txt index edaf57e..05d713f 100644 --- a/games.txt +++ b/games.txt @@ -120,6 +120,7 @@ farcry2|Far Cry|ase|port_query=14001 fortressforever|Fortress Forever|valve flashpoint|Flashpoint|gamespy1|port=2302,port_query_offset=1 ffow|Frontlines: Fuel of War|ffow|port=5476,port_query_offset=2 +fivem|FiveM|fivem|port=30120 garrysmod|Garry's Mod|valve graw|Ghost Recon: Advanced Warfighter|gamespy2|port_query=15250 graw2|Ghost Recon: Advanced Warfighter 2|gamespy2|port_query=16250 diff --git a/lib/HexUtil.js b/lib/HexUtil.js new file mode 100644 index 0000000..c819589 --- /dev/null +++ b/lib/HexUtil.js @@ -0,0 +1,22 @@ +class HexUtil { + static debugDump(buffer) { + let hexLine = ''; + let chrLine = ''; + let out = ''; + for(let i = 0; i < buffer.length; i++) { + const sliced = buffer.slice(i,i+1); + hexLine += sliced.toString('hex')+' '; + let chr = sliced.toString(); + if(chr < ' ' || chr > '~') chr = ' '; + chrLine += chr+' '; + if(hexLine.length > 60 || i === buffer.length - 1) { + out += hexLine + '\n'; + out += chrLine + '\n'; + hexLine = chrLine = ''; + } + } + return out; + } +} + +module.exports = HexUtil; diff --git a/lib/index.js b/lib/index.js index ffb9553..6bd7f01 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,6 @@ const dgram = require('dgram'), - TypeResolver = require('./typeresolver'); + TypeResolver = require('./typeresolver'), + HexUtil = require('./HexUtil'); const activeQueries = []; @@ -7,7 +8,10 @@ const udpSocket = dgram.createSocket('udp4'); udpSocket.unref(); udpSocket.bind(21943); udpSocket.on('message', (buffer, rinfo) => { - if(Gamedig.debug) console.log(rinfo.address+':'+rinfo.port+" <--UDP "+buffer.toString('hex')); + if(Gamedig.debug) { + console.log(rinfo.address+':'+rinfo.port+" <--UDP"); + console.log(HexUtil.debugDump(buffer)); + } for(const query of activeQueries) { if( query.options.address !== rinfo.address diff --git a/protocols/core.js b/protocols/core.js index b88a167..7a733a4 100644 --- a/protocols/core.js +++ b/protocols/core.js @@ -2,7 +2,8 @@ const EventEmitter = require('events').EventEmitter, dns = require('dns'), net = require('net'), async = require('async'), - Reader = require('../lib/reader'); + Reader = require('../lib/reader'), + HexUtil = require('../lib/HexUtil'); class Core extends EventEmitter { constructor() { @@ -193,27 +194,6 @@ class Core extends EventEmitter { } return false; } - debugBuffer(buffer) { - let out = ''; - let out2 = ''; - for(let i = 0; i < buffer.length; i++) { - const sliced = buffer.slice(i,i+1); - out += sliced.toString('hex')+' '; - let chr = sliced.toString(); - if(chr < ' ' || chr > '~') chr = ' '; - out2 += chr+' '; - if(out.length > 60) { - console.log(out); - console.log(out2); - out = out2 = ''; - } - } - console.log(out); - console.log(out2); - } - - - _tcpConnect(c) { if(this.tcpSocket) return c(this.tcpSocket); @@ -234,7 +214,10 @@ class Core extends EventEmitter { const writeHook = socket.write; socket.write = (...args) => { - if(this.debug) console.log(address+':'+port+" TCP--> "+args[0].toString('hex')); + if(this.debug) { + console.log(address+':'+port+" TCP-->"); + console.log(HexUtil.debugDump(args[0])); + } writeHook.apply(socket,args); }; @@ -246,7 +229,10 @@ class Core extends EventEmitter { }); socket.on('data', (data) => { if(!this.tcpCallback) return; - if(this.debug) console.log(address+':'+port+" <--TCP "+data.toString('hex')); + if(this.debug) { + console.log(address+':'+port+" <--TCP"); + console.log(HexUtil.debugDump(data)); + } received = Buffer.concat([received,data]); if(this.tcpCallback(received)) { clearTimeout(this.tcpTimeoutTimer); @@ -294,7 +280,10 @@ class Core extends EventEmitter { if(typeof buffer === 'string') buffer = Buffer.from(buffer,'binary'); - if(this.debug) console.log(this.options.address+':'+this.options.port_query+" UDP--> "+buffer.toString('hex')); + if(this.debug) { + console.log(this.options.address+':'+this.options.port_query+" UDP-->"); + console.log(HexUtil.debugDump(buffer)); + } this.udpSocket.send(buffer,0,buffer.length,this.options.port_query,this.options.address); } _udpResponse(buffer) { diff --git a/protocols/fivem.js b/protocols/fivem.js new file mode 100644 index 0000000..438b986 --- /dev/null +++ b/protocols/fivem.js @@ -0,0 +1,9 @@ +class FiveM extends require('./quake2') { + constructor() { + super(); + this.sendHeader = 'getinfo xxx'; + this.responseHeader = 'infoResponse'; + } +} + +module.exports = FiveM;