Added server status retrieval and implemented it on UI.

The player count on the landing page is now functional. If the server cannot be reached, the label and value will change to SERVER and OFFLINE, respectively. This behavior can be modified.
This commit is contained in:
Daniel Scalzi 2018-04-15 22:35:14 -04:00
parent 8446af4669
commit 714daace18
No known key found for this signature in database
GPG Key ID: 5CA2F145B63535F9
5 changed files with 99 additions and 4 deletions

View File

@ -6,8 +6,11 @@ const ConfigManager = require(path.join(__dirname, 'assets', 'js', 'configmanage
const DiscordWrapper = require(path.join(__dirname, 'assets', 'js', 'discordwrapper.js')) const DiscordWrapper = require(path.join(__dirname, 'assets', 'js', 'discordwrapper.js'))
const Mojang = require(path.join(__dirname, 'assets', 'js', 'mojang.js')) const Mojang = require(path.join(__dirname, 'assets', 'js', 'mojang.js'))
const AuthManager = require(path.join(__dirname, 'assets', 'js', 'authmanager.js')) const AuthManager = require(path.join(__dirname, 'assets', 'js', 'authmanager.js'))
const ServerStatus = require(path.join(__dirname, 'assets', 'js', 'serverstatus.js'))
const {URL} = require('url')
let mojangStatusListener let mojangStatusListener
let serverStatusListener
// Launch Elements // Launch Elements
let launch_content, launch_details, launch_progress, launch_progress_label, launch_details_text let launch_content, launch_details, launch_progress, launch_progress_label, launch_details_text
@ -86,9 +89,36 @@ document.addEventListener('readystatechange', function(){
document.getElementById('mojang_status_icon').style.color = Mojang.statusToHex(status) document.getElementById('mojang_status_icon').style.color = Mojang.statusToHex(status)
} }
const refreshServerStatus = async function(){
console.log('Refreshing Server Status')
const serv = AssetGuard.resolveSelectedServer(ConfigManager.getGameDirectory())
let pLabel = 'SERVER'
let pVal = 'OFFLINE'
try {
console.log(serv)
const serverURL = new URL('my://' + serv.server_ip)
const servStat = await ServerStatus.getStatus(serverURL.hostname, serverURL.port)
if(servStat.online){
pLabel = 'PLAYERS'
pVal = servStat.onlinePlayers + '/' + servStat.maxPlayers
}
} catch (err) {
console.warn('Unable to refresh server status, assuming offline.')
console.debug(err)
}
document.getElementById('landingPlayerLabel').innerHTML = pLabel
document.getElementById('player_count').innerHTML = pVal
}
refreshMojangStatuses() refreshMojangStatuses()
refreshServerStatus()
// Set refresh rate to once every 5 minutes. // Set refresh rate to once every 5 minutes.
mojangStatusListener = setInterval(refreshMojangStatuses, 300000) mojangStatusListener = setInterval(refreshMojangStatuses, 300000)
serverStatusListener = setInterval(refreshServerStatus, 300000)
} }
}, false) }, false)

View File

@ -421,11 +421,11 @@ class AssetGuard extends EventEmitter {
const servers = distro.servers const servers = distro.servers
for(let i=0; i<servers.length; i++){ for(let i=0; i<servers.length; i++){
if(servers[i].default_selected){ if(servers[i].default_selected){
return servers[i].id return servers[i]
} }
} }
// If no server declares default_selected, default to the first one declared. // If no server declares default_selected, default to the first one declared.
return (servers.length > 0) ? servers[0].id : null return (servers.length > 0) ? servers[0] : null
} }
/** /**

View File

@ -15,7 +15,7 @@ AssetGuard.retrieveDistributionDataSync(ConfigManager.getGameDirectory(), false)
// Resolve the selected server if its value has yet to be set. // Resolve the selected server if its value has yet to be set.
if(ConfigManager.getSelectedServer() == null){ if(ConfigManager.getSelectedServer() == null){
console.log('Determining default selected server..') console.log('Determining default selected server..')
ConfigManager.setSelectedServer(AssetGuard.resolveSelectedServer(ConfigManager.getGameDirectory())) ConfigManager.setSelectedServer(AssetGuard.resolveSelectedServer(ConfigManager.getGameDirectory()).id)
ConfigManager.save() ConfigManager.save()
} }

View File

@ -0,0 +1,65 @@
const net = require('net')
/**
* Retrieves the status of a minecraft server.
*
* @param {string} address The server address.
* @param {number} port Optional. The port of the server. Defaults to 25565.
* @returns {Promise.<Object>} A promise which resolves to an object containing
* status information.
*/
exports.getStatus = function(address, port = 25565){
if(port == null || port == ''){
port = 25565
}
if(typeof port === 'string'){
port = parseInt(port)
}
return new Promise((resolve, reject) => {
const socket = net.connect(port, address, () => {
let buff = new Buffer([0xFE, 0x01])
socket.write(buff)
})
socket.setTimeout(2500, () => {
socket.end()
reject({
code: 'ETIMEDOUT',
errno: 'ETIMEDOUT',
address,
port
})
})
socket.on('data', (data) => {
if(data != null && data != ''){
let server_info = data.toString().split('\x00\x00\x00')
const NUM_FIELDS = 6
if(server_info != null && server_info.length >= NUM_FIELDS){
resolve({
online: true,
version: server_info[2].replace(/\u0000/g, ''),
motd: server_info[3].replace(/\u0000/g, ''),
onlinePlayers: server_info[4].replace(/\u0000/g, ''),
maxPlayers: server_info[5].replace(/\u0000/g,'')
})
} else {
resolve({
online: false
})
}
}
socket.end()
})
socket.on('error', (err) => {
socket.destroy()
reject(err)
// ENOTFOUND = Unable to resolve.
// ECONNREFUSED = Unable to connect to port.
})
})
}

View File

@ -102,7 +102,7 @@
<div id="left"> <div id="left">
<div class="bot_wrapper"> <div class="bot_wrapper">
<div id="content"> <div id="content">
<span class="bot_label">PLAYERS</span> <span class="bot_label" id="landingPlayerLabel">PLAYERS</span>
<span id="player_count">18/100</span> <span id="player_count">18/100</span>
<div class="bot_divider"></div> <div class="bot_divider"></div>
<span class="bot_label">MOJANG STATUS</span> <span class="bot_label">MOJANG STATUS</span>