mirror of
https://github.com/gamedig/node-gamedig.git
synced 2024-11-16 16:58:32 +01:00
104 lines
3.2 KiB
JavaScript
104 lines
3.2 KiB
JavaScript
const GameResolver = require('./GameResolver'),
|
|
ProtocolResolver = require('./ProtocolResolver'),
|
|
GlobalUdpSocket = require('./GlobalUdpSocket');
|
|
|
|
const defaultOptions = {
|
|
socketTimeout: 2000,
|
|
attemptTimeout: 10000,
|
|
maxAttempts: 1
|
|
};
|
|
|
|
class QueryRunner {
|
|
constructor() {
|
|
this.udpSocket = new GlobalUdpSocket();
|
|
this.gameResolver = new GameResolver();
|
|
this.protocolResolver = new ProtocolResolver();
|
|
}
|
|
async run(userOptions) {
|
|
for (const key of Object.keys(userOptions)) {
|
|
const value = userOptions[key];
|
|
if (['port'].includes(key)) {
|
|
userOptions[key] = parseInt(value);
|
|
}
|
|
}
|
|
|
|
const {
|
|
port_query: gameQueryPort,
|
|
port_query_offset: gameQueryPortOffset,
|
|
...gameOptions
|
|
} = this.gameResolver.lookup(userOptions.type);
|
|
const attempts = [];
|
|
|
|
if (userOptions.port) {
|
|
if (gameQueryPortOffset) {
|
|
attempts.push({
|
|
...defaultOptions,
|
|
...gameOptions,
|
|
...userOptions,
|
|
port: userOptions.port + gameQueryPortOffset
|
|
});
|
|
}
|
|
if (userOptions.port === gameOptions.port && gameQueryPort) {
|
|
attempts.push({
|
|
...defaultOptions,
|
|
...gameOptions,
|
|
...userOptions,
|
|
port: gameQueryPort
|
|
});
|
|
}
|
|
attempts.push({
|
|
...defaultOptions,
|
|
...gameOptions,
|
|
...userOptions
|
|
});
|
|
} else if (gameQueryPort) {
|
|
attempts.push({
|
|
...defaultOptions,
|
|
...gameOptions,
|
|
...userOptions,
|
|
port: gameQueryPort
|
|
});
|
|
} else if (gameOptions.port) {
|
|
attempts.push({
|
|
...defaultOptions,
|
|
...gameOptions,
|
|
...userOptions,
|
|
port: gameOptions.port + (gameQueryPortOffset || 0)
|
|
});
|
|
} else {
|
|
throw new Error("Could not determine port to query. Did you provide a port or gameid?");
|
|
}
|
|
|
|
if (attempts.length === 1) {
|
|
return await this._attempt(attempts[0]);
|
|
} else {
|
|
const errors = [];
|
|
for (const attempt of attempts) {
|
|
try {
|
|
return await this._attempt(attempt);
|
|
} catch(e) {
|
|
const e2 = new Error('Failed to query port ' + attempt.port);
|
|
e2.stack += "\nCaused by:\n" + e.stack;
|
|
errors.push(e2);
|
|
}
|
|
}
|
|
|
|
const err = new Error('Failed all port attempts');
|
|
err.stack = errors.map(e => e.stack).join('\n');
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
async _attempt(options) {
|
|
if (options.debug) {
|
|
console.log("Running attempt with options:");
|
|
console.log(options);
|
|
}
|
|
const core = this.protocolResolver.create(options.protocol);
|
|
core.options = options;
|
|
core.udpSocket = this.udpSocket;
|
|
return await core.runAllAttempts();
|
|
}
|
|
}
|
|
|
|
module.exports = QueryRunner;
|