mirror of
https://github.com/tribufu/node-gamedig
synced 2026-06-01 09:42:41 +00:00
Add eslint (#364)
* Add initial prettier and eslint configs * Modify prettierrc * Run eslint on everything * Actually remove prettier * Fix some eslints * Remove label in gs2 * Update CHANGELOG * Update eslintrc to specify es2021
This commit is contained in:
parent
bff9507189
commit
93a9095d99
67 changed files with 6960 additions and 5211 deletions
|
|
@ -1,161 +1,162 @@
|
|||
import Core from './core.js';
|
||||
|
||||
export default class battlefield extends Core {
|
||||
constructor() {
|
||||
super();
|
||||
this.encoding = 'latin1';
|
||||
}
|
||||
|
||||
async run(state) {
|
||||
await this.withTcp(async socket => {
|
||||
{
|
||||
const data = await this.query(socket, ['serverInfo']);
|
||||
state.name = data.shift();
|
||||
state.raw.numplayers = parseInt(data.shift());
|
||||
state.maxplayers = parseInt(data.shift());
|
||||
state.raw.gametype = data.shift();
|
||||
state.map = data.shift();
|
||||
state.raw.roundsplayed = parseInt(data.shift());
|
||||
state.raw.roundstotal = parseInt(data.shift());
|
||||
|
||||
const teamCount = data.shift();
|
||||
state.raw.teams = [];
|
||||
for (let i = 0; i < teamCount; i++) {
|
||||
const tickets = parseFloat(data.shift());
|
||||
state.raw.teams.push({
|
||||
tickets: tickets
|
||||
});
|
||||
}
|
||||
|
||||
state.raw.targetscore = parseInt(data.shift());
|
||||
state.raw.status = data.shift();
|
||||
|
||||
// Seems like the fields end at random places beyond this point
|
||||
// depending on the server version
|
||||
|
||||
if (data.length) state.raw.ranked = (data.shift() === 'true');
|
||||
if (data.length) state.raw.punkbuster = (data.shift() === 'true');
|
||||
if (data.length) state.password = (data.shift() === 'true');
|
||||
if (data.length) state.raw.uptime = parseInt(data.shift());
|
||||
if (data.length) state.raw.roundtime = parseInt(data.shift());
|
||||
|
||||
const isBadCompany2 = data[0] === 'BC2';
|
||||
if (isBadCompany2) {
|
||||
if (data.length) data.shift();
|
||||
if (data.length) data.shift();
|
||||
}
|
||||
if (data.length) {
|
||||
state.raw.ip = data.shift();
|
||||
const split = state.raw.ip.split(':');
|
||||
state.gameHost = split[0];
|
||||
state.gamePort = split[1];
|
||||
} else {
|
||||
// best guess if the server doesn't tell us what the server port is
|
||||
// these are just the default game ports for different default query ports
|
||||
if (this.options.port === 48888) state.gamePort = 7673;
|
||||
if (this.options.port === 22000) state.gamePort = 25200;
|
||||
}
|
||||
if (data.length) state.raw.punkbusterversion = data.shift();
|
||||
if (data.length) state.raw.joinqueue = (data.shift() === 'true');
|
||||
if (data.length) state.raw.region = data.shift();
|
||||
if (data.length) state.raw.pingsite = data.shift();
|
||||
if (data.length) state.raw.country = data.shift();
|
||||
if (data.length) state.raw.quickmatch = (data.shift() === 'true');
|
||||
}
|
||||
|
||||
{
|
||||
const data = await this.query(socket, ['version']);
|
||||
data.shift();
|
||||
state.raw.version = data.shift();
|
||||
}
|
||||
|
||||
{
|
||||
const data = await this.query(socket, ['listPlayers', 'all']);
|
||||
const fieldCount = parseInt(data.shift());
|
||||
const fields = [];
|
||||
for (let i = 0; i < fieldCount; i++) {
|
||||
fields.push(data.shift());
|
||||
}
|
||||
const numplayers = data.shift();
|
||||
for (let i = 0; i < numplayers; i++) {
|
||||
const player = {};
|
||||
for (let key of fields) {
|
||||
let value = data.shift();
|
||||
|
||||
if (key === 'teamId') key = 'team';
|
||||
else if (key === 'squadId') key = 'squad';
|
||||
|
||||
if (
|
||||
key === 'kills'
|
||||
|| key === 'deaths'
|
||||
|| key === 'score'
|
||||
|| key === 'rank'
|
||||
|| key === 'team'
|
||||
|| key === 'squad'
|
||||
|| key === 'ping'
|
||||
|| key === 'type'
|
||||
) {
|
||||
value = parseInt(value);
|
||||
}
|
||||
|
||||
player[key] = value;
|
||||
}
|
||||
state.players.push(player);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async query(socket, params) {
|
||||
const outPacket = this.buildPacket(params);
|
||||
return await this.tcpSend(socket, outPacket, (data) => {
|
||||
const decoded = this.decodePacket(data);
|
||||
if(decoded) {
|
||||
this.logger.debug(decoded);
|
||||
if(decoded.shift() !== 'OK') throw new Error('Missing OK');
|
||||
return decoded;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
buildPacket(params) {
|
||||
const paramBuffers = [];
|
||||
for (const param of params) {
|
||||
paramBuffers.push(Buffer.from(param,'utf8'));
|
||||
}
|
||||
|
||||
let totalLength = 12;
|
||||
for (const paramBuffer of paramBuffers) {
|
||||
totalLength += paramBuffer.length+1+4;
|
||||
}
|
||||
|
||||
const b = Buffer.alloc(totalLength);
|
||||
b.writeUInt32LE(0,0);
|
||||
b.writeUInt32LE(totalLength,4);
|
||||
b.writeUInt32LE(params.length,8);
|
||||
let offset = 12;
|
||||
for (const paramBuffer of paramBuffers) {
|
||||
b.writeUInt32LE(paramBuffer.length, offset); offset += 4;
|
||||
paramBuffer.copy(b, offset); offset += paramBuffer.length;
|
||||
b.writeUInt8(0, offset); offset += 1;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
decodePacket(buffer) {
|
||||
if(buffer.length < 8) return false;
|
||||
const reader = this.reader(buffer);
|
||||
const header = reader.uint(4);
|
||||
const totalLength = reader.uint(4);
|
||||
if(buffer.length < totalLength) return false;
|
||||
this.logger.debug("Expected " + totalLength + " bytes, have " + buffer.length);
|
||||
|
||||
const paramCount = reader.uint(4);
|
||||
const params = [];
|
||||
for(let i = 0; i < paramCount; i++) {
|
||||
params.push(reader.pascalString(4));
|
||||
const strNull = reader.uint(1);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
}
|
||||
import Core from './core.js'
|
||||
|
||||
export default class battlefield extends Core {
|
||||
constructor () {
|
||||
super()
|
||||
this.encoding = 'latin1'
|
||||
}
|
||||
|
||||
async run (state) {
|
||||
await this.withTcp(async socket => {
|
||||
{
|
||||
const data = await this.query(socket, ['serverInfo'])
|
||||
state.name = data.shift()
|
||||
state.raw.numplayers = parseInt(data.shift())
|
||||
state.maxplayers = parseInt(data.shift())
|
||||
state.raw.gametype = data.shift()
|
||||
state.map = data.shift()
|
||||
state.raw.roundsplayed = parseInt(data.shift())
|
||||
state.raw.roundstotal = parseInt(data.shift())
|
||||
|
||||
const teamCount = data.shift()
|
||||
state.raw.teams = []
|
||||
for (let i = 0; i < teamCount; i++) {
|
||||
const tickets = parseFloat(data.shift())
|
||||
state.raw.teams.push({
|
||||
tickets
|
||||
})
|
||||
}
|
||||
|
||||
state.raw.targetscore = parseInt(data.shift())
|
||||
state.raw.status = data.shift()
|
||||
|
||||
// Seems like the fields end at random places beyond this point
|
||||
// depending on the server version
|
||||
|
||||
if (data.length) state.raw.ranked = (data.shift() === 'true')
|
||||
if (data.length) state.raw.punkbuster = (data.shift() === 'true')
|
||||
if (data.length) state.password = (data.shift() === 'true')
|
||||
if (data.length) state.raw.uptime = parseInt(data.shift())
|
||||
if (data.length) state.raw.roundtime = parseInt(data.shift())
|
||||
|
||||
const isBadCompany2 = data[0] === 'BC2'
|
||||
if (isBadCompany2) {
|
||||
if (data.length) data.shift()
|
||||
if (data.length) data.shift()
|
||||
}
|
||||
if (data.length) {
|
||||
state.raw.ip = data.shift()
|
||||
const split = state.raw.ip.split(':')
|
||||
state.gameHost = split[0]
|
||||
state.gamePort = split[1]
|
||||
} else {
|
||||
// best guess if the server doesn't tell us what the server port is
|
||||
// these are just the default game ports for different default query ports
|
||||
if (this.options.port === 48888) state.gamePort = 7673
|
||||
if (this.options.port === 22000) state.gamePort = 25200
|
||||
}
|
||||
if (data.length) state.raw.punkbusterversion = data.shift()
|
||||
if (data.length) state.raw.joinqueue = (data.shift() === 'true')
|
||||
if (data.length) state.raw.region = data.shift()
|
||||
if (data.length) state.raw.pingsite = data.shift()
|
||||
if (data.length) state.raw.country = data.shift()
|
||||
if (data.length) state.raw.quickmatch = (data.shift() === 'true')
|
||||
}
|
||||
|
||||
{
|
||||
const data = await this.query(socket, ['version'])
|
||||
data.shift()
|
||||
state.raw.version = data.shift()
|
||||
}
|
||||
|
||||
{
|
||||
const data = await this.query(socket, ['listPlayers', 'all'])
|
||||
const fieldCount = parseInt(data.shift())
|
||||
const fields = []
|
||||
for (let i = 0; i < fieldCount; i++) {
|
||||
fields.push(data.shift())
|
||||
}
|
||||
const numplayers = data.shift()
|
||||
for (let i = 0; i < numplayers; i++) {
|
||||
const player = {}
|
||||
for (let key of fields) {
|
||||
let value = data.shift()
|
||||
|
||||
if (key === 'teamId') key = 'team'
|
||||
else if (key === 'squadId') key = 'squad'
|
||||
|
||||
if (
|
||||
key === 'kills' ||
|
||||
key === 'deaths' ||
|
||||
key === 'score' ||
|
||||
key === 'rank' ||
|
||||
key === 'team' ||
|
||||
key === 'squad' ||
|
||||
key === 'ping' ||
|
||||
key === 'type'
|
||||
) {
|
||||
value = parseInt(value)
|
||||
}
|
||||
|
||||
player[key] = value
|
||||
}
|
||||
state.players.push(player)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async query (socket, params) {
|
||||
const outPacket = this.buildPacket(params)
|
||||
return await this.tcpSend(socket, outPacket, (data) => {
|
||||
const decoded = this.decodePacket(data)
|
||||
if (decoded) {
|
||||
this.logger.debug(decoded)
|
||||
if (decoded.shift() !== 'OK') throw new Error('Missing OK')
|
||||
return decoded
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
buildPacket (params) {
|
||||
const paramBuffers = []
|
||||
for (const param of params) {
|
||||
paramBuffers.push(Buffer.from(param, 'utf8'))
|
||||
}
|
||||
|
||||
let totalLength = 12
|
||||
for (const paramBuffer of paramBuffers) {
|
||||
totalLength += paramBuffer.length + 1 + 4
|
||||
}
|
||||
|
||||
const b = Buffer.alloc(totalLength)
|
||||
b.writeUInt32LE(0, 0)
|
||||
b.writeUInt32LE(totalLength, 4)
|
||||
b.writeUInt32LE(params.length, 8)
|
||||
let offset = 12
|
||||
for (const paramBuffer of paramBuffers) {
|
||||
b.writeUInt32LE(paramBuffer.length, offset); offset += 4
|
||||
paramBuffer.copy(b, offset); offset += paramBuffer.length
|
||||
b.writeUInt8(0, offset); offset += 1
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
decodePacket (buffer) {
|
||||
if (buffer.length < 8) return false
|
||||
const reader = this.reader(buffer)
|
||||
reader.uint(4) // header
|
||||
const totalLength = reader.uint(4)
|
||||
if (buffer.length < totalLength) return false
|
||||
this.logger.debug('Expected ' + totalLength + ' bytes, have ' + buffer.length)
|
||||
|
||||
const paramCount = reader.uint(4)
|
||||
const params = []
|
||||
for (let i = 0; i < paramCount; i++) {
|
||||
params.push(reader.pascalString(4))
|
||||
reader.uint(1) // strNull
|
||||
}
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue