serverstatus.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { connect } from 'net'
  2. /**
  3. * Retrieves the status of a minecraft server.
  4. *
  5. * @param {string} address The server address.
  6. * @param {number} port Optional. The port of the server. Defaults to 25565.
  7. * @returns {Promise.<Object>} A promise which resolves to an object containing
  8. * status information.
  9. */
  10. export function getStatus(address: string, port: number | string = 25565){
  11. let sanitizedPort: number
  12. if(port == null || port == ''){
  13. sanitizedPort = 25565
  14. }
  15. if(typeof port === 'string'){
  16. sanitizedPort = parseInt(port)
  17. }
  18. return new Promise((resolve, reject) => {
  19. const socket = connect(sanitizedPort, address, () => {
  20. let buff = Buffer.from([0xFE, 0x01])
  21. socket.write(buff)
  22. })
  23. socket.setTimeout(2500, () => {
  24. socket.end()
  25. reject({
  26. code: 'ETIMEDOUT',
  27. errno: 'ETIMEDOUT',
  28. address,
  29. sanitizedPort
  30. })
  31. })
  32. socket.on('data', (data) => {
  33. if(data != null){
  34. let server_info = data.toString().split('\x00\x00\x00')
  35. const NUM_FIELDS = 6
  36. if(server_info != null && server_info.length >= NUM_FIELDS){
  37. resolve({
  38. online: true,
  39. version: server_info[2].replace(/\u0000/g, ''),
  40. motd: server_info[3].replace(/\u0000/g, ''),
  41. onlinePlayers: server_info[4].replace(/\u0000/g, ''),
  42. maxPlayers: server_info[5].replace(/\u0000/g,'')
  43. })
  44. } else {
  45. resolve({
  46. online: false
  47. })
  48. }
  49. }
  50. socket.end()
  51. })
  52. socket.on('error', (err) => {
  53. socket.destroy()
  54. reject(err)
  55. // ENOTFOUND = Unable to resolve.
  56. // ECONNREFUSED = Unable to connect to port.
  57. })
  58. })
  59. }