mirror of
https://github.com/tribufu/node-gamedig
synced 2026-05-18 01:25:51 +00:00
Upgrade syntax of everything to more modern javascript
This commit is contained in:
parent
f8d903b982
commit
69288baebc
43 changed files with 1499 additions and 1521 deletions
74
lib/Class.js
74
lib/Class.js
|
|
@ -1,74 +0,0 @@
|
|||
/* based on Simple JavaScript Inheritance
|
||||
* By John Resig http://ejohn.org/
|
||||
* MIT Licensed.
|
||||
*/
|
||||
|
||||
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
||||
|
||||
// The base Class implementation (does nothing)
|
||||
var Class = function(){};
|
||||
|
||||
// Create a new Class that inherits from this class
|
||||
Class.extend = function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var name = 'Class';
|
||||
var parent = this;
|
||||
var prop = {};
|
||||
if(typeof args[0] == 'string') name = args.shift();
|
||||
if(args.length >= 2) parent = args.shift();
|
||||
prop = args.shift();
|
||||
|
||||
// Copy prototype from the parent object
|
||||
var prototype = {};
|
||||
for(var name in parent.prototype) {
|
||||
prototype[name] = parent.prototype[name];
|
||||
}
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
for(var name in prop) {
|
||||
if(typeof prop[name] == "function" && fnTest.test(prop[name])) {
|
||||
// this is a function that references _super, so we have to wrap it
|
||||
// and provide it with its super function
|
||||
prototype[name] = (function(name, fn){
|
||||
return function() {
|
||||
var tmp = this._super;
|
||||
|
||||
// Add a new ._super() method that is the same method
|
||||
// but on the super-class
|
||||
if(typeof parent.prototype[name] == 'undefined') {
|
||||
if(name == 'init') this._super = parent.prototype.constructor;
|
||||
else this._super = function() { throw new Error('Called _super in method without a parent'); }
|
||||
} else this._super = parent.prototype[name];
|
||||
|
||||
// The method only need to be bound temporarily, so we
|
||||
// remove it when we're done executing
|
||||
var ret = fn.apply(this, arguments);
|
||||
this._super = tmp;
|
||||
|
||||
return ret;
|
||||
};
|
||||
})(name, prop[name]);
|
||||
} else {
|
||||
prototype[name] = prop[name];
|
||||
}
|
||||
}
|
||||
|
||||
// The dummy class constructor
|
||||
function Class() {
|
||||
// All construction is actually done in the init method
|
||||
if(this.init) this.init.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Populate our constructed prototype object
|
||||
Class.prototype = prototype;
|
||||
|
||||
// Enforce the constructor to be what we expect
|
||||
Class.prototype.constructor = Class;
|
||||
|
||||
// And make this class extendable
|
||||
Class.extend = arguments.callee;
|
||||
|
||||
return Class;
|
||||
};
|
||||
|
||||
module.exports = Class;
|
||||
56
lib/index.js
56
lib/index.js
|
|
@ -1,46 +1,48 @@
|
|||
var dgram = require('dgram'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
util = require('util'),
|
||||
dns = require('dns'),
|
||||
TypeResolver = require('./typeresolver');
|
||||
const dgram = require('dgram'),
|
||||
TypeResolver = require('./typeresolver');
|
||||
|
||||
var activeQueries = [];
|
||||
const activeQueries = [];
|
||||
|
||||
var udpSocket = dgram.createSocket('udp4');
|
||||
const udpSocket = dgram.createSocket('udp4');
|
||||
udpSocket.unref();
|
||||
udpSocket.bind(21943);
|
||||
udpSocket.on('message', function(buffer, rinfo) {
|
||||
udpSocket.on('message', (buffer, rinfo) => {
|
||||
if(Gamedig.debug) console.log(rinfo.address+':'+rinfo.port+" <--UDP "+buffer.toString('hex'));
|
||||
for(var i = 0; i < activeQueries.length; i++) {
|
||||
var query = activeQueries[i];
|
||||
for(const query of activeQueries) {
|
||||
if(
|
||||
query.options.address != rinfo.address
|
||||
&& query.options.altaddress != rinfo.address
|
||||
query.options.address !== rinfo.address
|
||||
&& query.options.altaddress !== rinfo.address
|
||||
) continue;
|
||||
if(query.options.port_query != rinfo.port) continue;
|
||||
if(query.options.port_query !== rinfo.port) continue;
|
||||
query._udpResponse(buffer);
|
||||
break;
|
||||
}
|
||||
});
|
||||
udpSocket.on('error', function(e) {
|
||||
udpSocket.on('error', (e) => {
|
||||
if(Gamedig.debug) console.log("UDP ERROR: "+e);
|
||||
});
|
||||
|
||||
Gamedig = {
|
||||
class Gamedig {
|
||||
|
||||
query: function(options,callback) {
|
||||
static query(options,callback) {
|
||||
const promise = new Promise((resolve,reject) => {
|
||||
for (const key of Object.keys(options)) {
|
||||
if (['port_query', 'port'].includes(key)) {
|
||||
options[key] = parseInt(options[key]);
|
||||
}
|
||||
}
|
||||
|
||||
options.callback = (state) => {
|
||||
if (state.error) reject(state.error);
|
||||
else resolve(state);
|
||||
};
|
||||
|
||||
var query;
|
||||
let query;
|
||||
try {
|
||||
query = TypeResolver.lookup(options.type);
|
||||
} catch(e) {
|
||||
process.nextTick(function() {
|
||||
options.callback({error:e.message});
|
||||
process.nextTick(() => {
|
||||
options.callback({error:e});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -63,26 +65,28 @@ Gamedig = {
|
|||
}
|
||||
|
||||
// copy over options
|
||||
for(var i in options) query.options[i] = options[i];
|
||||
for(const key of Object.keys(options)) {
|
||||
query.options[key] = options[key];
|
||||
}
|
||||
|
||||
activeQueries.push(query);
|
||||
|
||||
query.on('finished',function(state) {
|
||||
var i = activeQueries.indexOf(query);
|
||||
query.on('finished',() => {
|
||||
const i = activeQueries.indexOf(query);
|
||||
if(i >= 0) activeQueries.splice(i, 1);
|
||||
});
|
||||
|
||||
process.nextTick(function() {
|
||||
process.nextTick(() => {
|
||||
query.start();
|
||||
});
|
||||
});
|
||||
|
||||
if (callback && callback instanceof Function) {
|
||||
if(callback.length == 2) {
|
||||
if(callback.length === 2) {
|
||||
promise
|
||||
.then((state) => callback(null,state))
|
||||
.catch((error) => callback(error));
|
||||
} else if (callback.length == 1) {
|
||||
} else if (callback.length === 1) {
|
||||
promise
|
||||
.then((state) => callback(state))
|
||||
.catch((error) => callback({error:error}));
|
||||
|
|
@ -92,6 +96,6 @@ Gamedig = {
|
|||
return promise;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Gamedig;
|
||||
|
|
|
|||
145
lib/reader.js
145
lib/reader.js
|
|
@ -1,52 +1,57 @@
|
|||
var Iconv = require('iconv-lite'),
|
||||
const Iconv = require('iconv-lite'),
|
||||
Long = require('long');
|
||||
|
||||
function readUInt64BE(buffer,offset) {
|
||||
var high = buffer.readUInt32BE(offset);
|
||||
var low = buffer.readUInt32BE(offset+4);
|
||||
const high = buffer.readUInt32BE(offset);
|
||||
const low = buffer.readUInt32BE(offset+4);
|
||||
return new Long(low,high,true);
|
||||
}
|
||||
function readUInt64LE(buffer,offset) {
|
||||
var low = buffer.readUInt32LE(offset);
|
||||
var high = buffer.readUInt32LE(offset+4);
|
||||
const low = buffer.readUInt32LE(offset);
|
||||
const high = buffer.readUInt32LE(offset+4);
|
||||
return new Long(low,high,true);
|
||||
}
|
||||
|
||||
function Reader(query,buffer) {
|
||||
this.query = query;
|
||||
this.buffer = buffer;
|
||||
this.i = 0;
|
||||
}
|
||||
class Reader {
|
||||
constructor(query,buffer) {
|
||||
this.query = query;
|
||||
this.buffer = buffer;
|
||||
this.i = 0;
|
||||
}
|
||||
|
||||
Reader.prototype = {
|
||||
offset: function() { return this.i; },
|
||||
skip: function(i) { this.i += i; },
|
||||
string: function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var options = {};
|
||||
if(args.length == 0) {
|
||||
offset() {
|
||||
return this.i;
|
||||
}
|
||||
|
||||
skip(i) {
|
||||
this.i += i;
|
||||
}
|
||||
|
||||
string(...args) {
|
||||
let options = {};
|
||||
if(args.length === 0) {
|
||||
options = {};
|
||||
} else if(args.length == 1) {
|
||||
if(typeof args[0] == 'string') options = { delimiter: args[0] };
|
||||
else if(typeof args[0] == 'number') options = { length: args[0] };
|
||||
} else if(args.length === 1) {
|
||||
if(typeof args[0] === 'string') options = { delimiter: args[0] };
|
||||
else if(typeof args[0] === 'number') options = { length: args[0] };
|
||||
else options = args[0];
|
||||
}
|
||||
|
||||
options.encoding = options.encoding || this.query.encoding;
|
||||
if(options.encoding == 'latin1') options.encoding = 'win1252';
|
||||
if(options.encoding === 'latin1') options.encoding = 'win1252';
|
||||
|
||||
var start = this.i+0;
|
||||
var end = start;
|
||||
const start = this.i+0;
|
||||
let end = start;
|
||||
if(!('length' in options)) {
|
||||
// terminated by the delimiter
|
||||
var delim = options.delimiter || this.query.delimiter;
|
||||
if(typeof delim == 'string') delim = delim.charCodeAt(0);
|
||||
let delim = options.delimiter || this.query.delimiter;
|
||||
if(typeof delim === 'string') delim = delim.charCodeAt(0);
|
||||
while(true) {
|
||||
if(end >= this.buffer.length) {
|
||||
end = this.buffer.length;
|
||||
break;
|
||||
}
|
||||
if(this.buffer.readUInt8(end) == delim) break;
|
||||
if(this.buffer.readUInt8(end) === delim) break;
|
||||
end++;
|
||||
}
|
||||
this.i = end+1;
|
||||
|
|
@ -58,77 +63,85 @@ Reader.prototype = {
|
|||
this.i = end;
|
||||
}
|
||||
|
||||
var out = this.buffer.slice(start, end);
|
||||
var enc = options.encoding;
|
||||
if(enc == 'utf8' || enc == 'ucs2' || enc == 'binary') {
|
||||
let out = this.buffer.slice(start, end);
|
||||
const enc = options.encoding;
|
||||
if(enc === 'utf8' || enc === 'ucs2' || enc === 'binary') {
|
||||
out = out.toString(enc);
|
||||
} else {
|
||||
out = Iconv.decode(out,enc);
|
||||
}
|
||||
return out;
|
||||
},
|
||||
int: function(bytes) {
|
||||
var r = 0;
|
||||
}
|
||||
|
||||
int(bytes) {
|
||||
let r = 0;
|
||||
if(this.remaining() >= bytes) {
|
||||
if(this.query.byteorder == 'be') {
|
||||
if(bytes == 1) r = this.buffer.readInt8(this.i);
|
||||
else if(bytes == 2) r = this.buffer.readInt16BE(this.i);
|
||||
else if(bytes == 4) r = this.buffer.readInt32BE(this.i);
|
||||
if(this.query.byteorder === 'be') {
|
||||
if(bytes === 1) r = this.buffer.readInt8(this.i);
|
||||
else if(bytes === 2) r = this.buffer.readInt16BE(this.i);
|
||||
else if(bytes === 4) r = this.buffer.readInt32BE(this.i);
|
||||
} else {
|
||||
if(bytes == 1) r = this.buffer.readInt8(this.i);
|
||||
else if(bytes == 2) r = this.buffer.readInt16LE(this.i);
|
||||
else if(bytes == 4) r = this.buffer.readInt32LE(this.i);
|
||||
if(bytes === 1) r = this.buffer.readInt8(this.i);
|
||||
else if(bytes === 2) r = this.buffer.readInt16LE(this.i);
|
||||
else if(bytes === 4) r = this.buffer.readInt32LE(this.i);
|
||||
}
|
||||
}
|
||||
this.i += bytes;
|
||||
return r;
|
||||
},
|
||||
uint: function(bytes) {
|
||||
var r = 0;
|
||||
}
|
||||
|
||||
/** @returns {number} */
|
||||
uint(bytes) {
|
||||
let r = 0;
|
||||
if(this.remaining() >= bytes) {
|
||||
if(this.query.byteorder == 'be') {
|
||||
if(bytes == 1) r = this.buffer.readUInt8(this.i);
|
||||
else if(bytes == 2) r = this.buffer.readUInt16BE(this.i);
|
||||
else if(bytes == 4) r = this.buffer.readUInt32BE(this.i);
|
||||
else if(bytes == 8) r = readUInt64BE(this.buffer,this.i).toString();
|
||||
if(this.query.byteorder === 'be') {
|
||||
if(bytes === 1) r = this.buffer.readUInt8(this.i);
|
||||
else if(bytes === 2) r = this.buffer.readUInt16BE(this.i);
|
||||
else if(bytes === 4) r = this.buffer.readUInt32BE(this.i);
|
||||
else if(bytes === 8) r = readUInt64BE(this.buffer,this.i).toString();
|
||||
} else {
|
||||
if(bytes == 1) r = this.buffer.readUInt8(this.i);
|
||||
else if(bytes == 2) r = this.buffer.readUInt16LE(this.i);
|
||||
else if(bytes == 4) r = this.buffer.readUInt32LE(this.i);
|
||||
else if(bytes == 8) r = readUInt64LE(this.buffer,this.i).toString();
|
||||
if(bytes === 1) r = this.buffer.readUInt8(this.i);
|
||||
else if(bytes === 2) r = this.buffer.readUInt16LE(this.i);
|
||||
else if(bytes === 4) r = this.buffer.readUInt32LE(this.i);
|
||||
else if(bytes === 8) r = readUInt64LE(this.buffer,this.i).toString();
|
||||
}
|
||||
}
|
||||
this.i += bytes;
|
||||
return r;
|
||||
},
|
||||
float: function() {
|
||||
var r = 0;
|
||||
}
|
||||
|
||||
float() {
|
||||
let r = 0;
|
||||
if(this.remaining() >= 4) {
|
||||
if(this.query.byteorder == 'be') r = this.buffer.readFloatBE(this.i);
|
||||
if(this.query.byteorder === 'be') r = this.buffer.readFloatBE(this.i);
|
||||
else r = this.buffer.readFloatLE(this.i);
|
||||
}
|
||||
this.i += 4;
|
||||
return r;
|
||||
},
|
||||
part: function(bytes) {
|
||||
var r;
|
||||
}
|
||||
|
||||
part(bytes) {
|
||||
let r;
|
||||
if(this.remaining() >= bytes) {
|
||||
r = this.buffer.slice(this.i,this.i+bytes);
|
||||
} else {
|
||||
r = new Buffer();
|
||||
r = Buffer.from([]);
|
||||
}
|
||||
this.i += bytes;
|
||||
return r;
|
||||
},
|
||||
remaining: function() {
|
||||
}
|
||||
|
||||
remaining() {
|
||||
return this.buffer.length-this.i;
|
||||
},
|
||||
rest: function() {
|
||||
}
|
||||
|
||||
rest() {
|
||||
return this.buffer.slice(this.i);
|
||||
},
|
||||
done: function() {
|
||||
}
|
||||
|
||||
done() {
|
||||
return this.i >= this.buffer.length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Reader;
|
||||
|
|
|
|||
|
|
@ -1,38 +1,37 @@
|
|||
var Path = require('path'),
|
||||
const Path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var protocolDir = Path.normalize(__dirname+'/../protocols');
|
||||
var gamesFile = Path.normalize(__dirname+'/../games.txt');
|
||||
const protocolDir = Path.normalize(__dirname+'/../protocols');
|
||||
const gamesFile = Path.normalize(__dirname+'/../games.txt');
|
||||
|
||||
function parseList(str) {
|
||||
if(!str) return {};
|
||||
var split = str.split(',');
|
||||
var out = {};
|
||||
split.forEach(function(one) {
|
||||
var equals = one.indexOf('=');
|
||||
var key = equals == -1 ? one : one.substr(0,equals);
|
||||
var value = equals == -1 ? '' : one.substr(equals+1);
|
||||
const out = {};
|
||||
for (const one of str.split(',')) {
|
||||
const equals = one.indexOf('=');
|
||||
const key = equals === -1 ? one : one.substr(0,equals);
|
||||
let value = equals === -1 ? '' : one.substr(equals+1);
|
||||
|
||||
if(value === 'true' || value === '') value = true;
|
||||
else if(value === 'false') value = false;
|
||||
else if(!isNaN(value)) value = parseInt(value);
|
||||
|
||||
out[key] = value;
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function readGames() {
|
||||
var lines = fs.readFileSync(gamesFile,'utf8').split('\n');
|
||||
var games = {};
|
||||
const lines = fs.readFileSync(gamesFile,'utf8').split('\n');
|
||||
const games = {};
|
||||
|
||||
lines.forEach(function(line) {
|
||||
for (let line of lines) {
|
||||
// strip comments
|
||||
var comment = line.indexOf('#');
|
||||
if(comment != -1) line = line.substr(0,comment);
|
||||
const comment = line.indexOf('#');
|
||||
if(comment !== -1) line = line.substr(0,comment);
|
||||
line = line.trim();
|
||||
if(!line) return;
|
||||
if(!line) continue;
|
||||
|
||||
var split = line.split('|');
|
||||
const split = line.split('|');
|
||||
|
||||
games[split[0].trim()] = {
|
||||
pretty: split[1].trim(),
|
||||
|
|
@ -40,52 +39,56 @@ function readGames() {
|
|||
options: parseList(split[3]),
|
||||
params: parseList(split[4])
|
||||
};
|
||||
});
|
||||
}
|
||||
return games;
|
||||
}
|
||||
var games = readGames();
|
||||
const games = readGames();
|
||||
|
||||
function createProtocolInstance(type) {
|
||||
type = Path.basename(type);
|
||||
|
||||
var path = protocolDir+'/'+type;
|
||||
const path = protocolDir+'/'+type;
|
||||
if(!fs.existsSync(path+'.js')) throw Error('Protocol definition file missing: '+type);
|
||||
var protocol = require(path);
|
||||
const protocol = require(path);
|
||||
|
||||
return new protocol();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
lookup: function(type) {
|
||||
class TypeResolver {
|
||||
static lookup(type) {
|
||||
if(!type) throw Error('No game specified');
|
||||
|
||||
if(type.substr(0,9) == 'protocol-') {
|
||||
if(type.substr(0,9) === 'protocol-') {
|
||||
return createProtocolInstance(type.substr(9));
|
||||
}
|
||||
|
||||
var game = games[type];
|
||||
const game = games[type];
|
||||
if(!game) throw Error('Invalid game: '+type);
|
||||
|
||||
var query = createProtocolInstance(game.protocol);
|
||||
const query = createProtocolInstance(game.protocol);
|
||||
query.pretty = game.pretty;
|
||||
for(var key in game.options)
|
||||
query.options[key] = game.options[key];
|
||||
for(var key in game.params)
|
||||
query[key] = game.params[key];
|
||||
for(const key of Object.keys(game.options)) {
|
||||
query.options[key] = game.options[key];
|
||||
}
|
||||
for(const key of Object.keys(game.params)) {
|
||||
query[key] = game.params[key];
|
||||
}
|
||||
|
||||
return query;
|
||||
},
|
||||
printReadme: function() {
|
||||
var out = '';
|
||||
for(var key in games) {
|
||||
var game = games[key];
|
||||
}
|
||||
static printReadme() {
|
||||
let out = '';
|
||||
for(const key of Object.keys(games)) {
|
||||
const game = games[key];
|
||||
out += "* "+game.pretty+" ("+key+")";
|
||||
if(game.options.port_query_offset || game.options.port_query)
|
||||
out += " [[Separate Query Port](#separate-query-port)]";
|
||||
if(game.params.doc_notes)
|
||||
out += " [[Additional Notes](#"+game.params.doc_notes+")]"
|
||||
out += " [[Additional Notes](#"+game.params.doc_notes+")]";
|
||||
out += "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = TypeResolver;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue