Skip to content

Commit

Permalink
Add ping_all and type parameter to cb. Ref GH-4
Browse files Browse the repository at this point in the history
  • Loading branch information
deathcap committed Jan 30, 2016
1 parent 1a65286 commit d988b5b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 42 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ only server message of the day description, number of online players, and maximu
If you need to support arbitrarily old versions, but do not mind the slow 1.6.4 response (for example,
if you're sending a batch of ping requests over a long period of time), `ping_fe01` may be a good choice.

## ping_fe
### ping_fe

`ping_fe` sends nothing more than a single 0xfe byte, and only returns `motd`, `playersOnline`, and
`maxPlayers`. No protocol or game version. However it works even on 1.2.5 and 1.3.2. It will also
Expand All @@ -94,7 +94,7 @@ If all you need is the server description, and do not mind the slowness of 1.6.4
`ping_fe`. It is not very useful in most situations, better served by `ping_fe01fa` or `ping_fe01`.


## ping_fefd_udp
### ping_fefd_udp

`ping_fefd_udp` is a multi-step UDP-based query protocol described in 2011 at
https://dinnerbone.com/blog/2011/10/14/minecraft-19-has-rcon-and-query (for Minecraft 1.9 *beta*).
Expand Down Expand Up @@ -135,6 +135,15 @@ On vanilla servers, support can be enabled by setting `enable-query=true` in `se
where GS4 is apparently the "GameSpy4" protocol. Since it is off by default, you'll probably
not need to use `ping_fefd_udp` except in very specialized situations.

### ping_all

`ping_all` sends all of the types of pings, and calls the callback multiple times.
You can get the ping type with the third argument in the callback function.

Note: synchronizing and waiting for each of the pings is currently out of the scope
of this module (see https://github.com/deathcap/node-minecraft-ping/issues/4),
in general it is preferrable to use only one ping type (suggestion: `ping_fe01fa`).

## License

MIT
Expand Down
32 changes: 3 additions & 29 deletions demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,10 @@ if (process.argv.length < 4) {
const host = process.argv[2];
const port = parseInt(process.argv[3]);

mcping.ping_fe01fa({host, port}, function(err, response) {
mcping.ping_all({host, port}, function(err, response, type) {
if (err) {
console.log('ping_fe01fa error',err);
console.log('ping '+type+' error',err);
return;
}
console.log('received ping_fe01fa',response);
console.log('received ping_'+type,response);
});

mcping.ping_fe01({host, port}, function(err, response) {
if (err) {
console.log('ping_fe01 error',err);
return;
}
console.log('received ping_fe01',response);
});

mcping.ping_fe({host, port}, function(err, response) {
if (err) {
console.log('ping_fe error',err);
return;
}
console.log('received ping_fe',response);
});

mcping.ping_fefd_udp({host, port}, function(err, response) {
if (err) {
console.log('ping_fefd_udp error',err);
return;
}
console.log('received ping_fefd_udp',response);
});


32 changes: 21 additions & 11 deletions mcping.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ function ping_fe01fa(options, cb) {
'4a'+ // protocol version (74, last)
'0000'+''+ // hostname TODO
'00000000' // port TODO
,'hex'));
,'hex'),
'fe01fa');
}

// FE01 compatible with 1.3.2 and 1.2.5 (unlike FE01FA), but slow on 1.6.4, although its fast on 1.4.4, 1.5.2, and 1.7.10+
function ping_fe01(options, cb) {
_ping_buffer(options, cb, new Buffer('fe01', 'hex'));
_ping_buffer(options, cb, new Buffer('fe01', 'hex'), 'fe01');
}

// the 2011 beta 1.9 query protocol from https://dinnerbone.com/blog/2011/10/14/minecraft-19-has-rcon-and-query
Expand All @@ -39,23 +40,23 @@ function ping_fefd_udp(options, cb) {

udp.on('error', (err) => {
//console.log(`udp error:\n${err.stack}`);
cb(err, null);
cb(err, null, 'fefd_udp');
udp.close();
});

udp.on('message', (msg, rinfo) => {
//console.log(msg);
//console.log(`udp got: ${msg} from ${rinfo.address}:${rinfo.port}`);
if (state === STARTED) {
cb(new Error('received unexpected packet before sent anything'), null);
cb(new Error('received unexpected packet before sent anything'), null, 'fefd_udp');
return;
} else if (state === SENT_CHALLENGE_REQUEST) {
// challenge token
// 09 challenge type
// 00 00 00 00 id token (sent all zeros)
// xx xx xx xx new challenge token
if (msg[0] != 0x09) {
cb(new Error('unexpected packet received after sent challenge request'), null);
cb(new Error('unexpected packet received after sent challenge request'), null, 'fefd_udp');
return;
}
// challenge token is received as ASCII decimal string, but replied as encoded uint32be
Expand Down Expand Up @@ -101,7 +102,7 @@ function ping_fefd_udp(options, cb) {
// TODO: online players comes last, parse it
//console.log('result',result);
state = DONE;
cb(null, result);
cb(null, result, 'fefd_udp');
}
});

Expand All @@ -119,7 +120,7 @@ function ping_fefd_udp(options, cb) {
udp.bind();
}

function _ping_buffer(options, cb, buffer) {
function _ping_buffer(options, cb, buffer, type) {
const host = options.host;
const port = options.port;
const socket = net.connect(port, host);
Expand All @@ -131,7 +132,7 @@ function _ping_buffer(options, cb, buffer) {
console.log('ended');
});
socket.on('error', (err) => {
cb(err, null);
cb(err, null, type);
});
socket.on('data', (raw) => {
//console.log('data(fe01fa)',raw);
Expand Down Expand Up @@ -163,7 +164,7 @@ function _ping_buffer(options, cb, buffer) {
result.maxPlayers = parseInt(parts[2]);
}
//console.log('result',result);
cb(null, result);
cb(null, result, type);
});
}

Expand All @@ -176,7 +177,7 @@ function ping_fe(options, cb) {
socket.write(new Buffer('fe', 'hex'));
});
socket.on('error', (err) => {
cb(err, null);
cb(err, null, 'fe');
});
socket.on('data', (raw) => {
const string = raw.toString('ucs2');
Expand All @@ -187,13 +188,22 @@ function ping_fe(options, cb) {
result.motd = parts[0];
result.playersOnline = parseInt(parts[1]);
result.maxPlayers = parseInt(parts[2]);
cb(null, result);
cb(null, result, 'fe');
});
}

function ping_all(options, cb) {
ping_fefd_udp(options, cb);
ping_fe01fa(options, cb);
ping_fe01(options, cb);
ping_fe(options, cb);
}

module.exports = {
ping_fefd_udp,
ping_fe01fa,
ping_fe01,
ping_fe,

ping_all,
};

0 comments on commit d988b5b

Please sign in to comment.