Yesterday I was contacting NFo staff to see if they had any knowledge or information on how to pull public server information (such as Name, IP, current players) via a Discord bot. They didn't have any then, so I went to research to see how I could do it for myself, and now that I've figured it out I figured I'd share it here with you all!
Note: this is using a Discord bot via Discord.JS.
I was reading through the Server queries page on the Valve Developer Community wiki, and went to the Implementations section at the bottom. This contains several implementations of the Server queries protocol in many different languages. There is a module known as GameDig, which is a Node.JS module (like Discord.JS), which is quite simple to use (installation and sample usage is on the GitHub link).
I was able to put together a working script within my bot to pull and display information on Garry's Mod servers (but this can be used for any of the supported games listed there) with the following code:
Code: Select all
const { MessageEmbed, Collection } = require("discord.js")
const Gamedig = require("gamedig")
const servers = new Collection()
function getServerInfo() {
delete require.cache[require.resolve("../serverinfo.json")] // ensure new IPs were not added
let serverInfo = require("../serverinfo.json")
//console.log(serverInfo.length)
for (let i = 0; i < serverInfo.length; i++) {
let ip = serverInfo[i]
//console.log(ip)
// query each IP in the file.
Gamedig.query({
type: "garrysmod",
host: ip,
maxAttempts: 3,
}).then((state) => {
let serverName = state.name
let map = state.map
let players = state.players.length
let maxPlayers = state.maxplayers
servers.set(ip, [serverName, ip, map, players, maxPlayers])
//console.log(servers)
}).catch((error) => {
})
}
return servers
}
getServerInfo()
module.exports = {
name: "serverinfo",
description: "Pulls current server information and displays it in a nice way.",
aliases: ["server", "ip", "gmod", "servers", "ips"],
execute(message, args) {
let embed = new MessageEmbed()
.setAuthor(message.client.user.username)
.setFooter("Copyright © Anonymous Networks")
.setColor("#3498DB")
.setDescription("Anonymous Networks Server Information")
getServerInfo().forEach((val, key, map) => {
//console.log(map.size)
let info = servers.get(key)
embed.addField(`${info[0]} (${info[1]})`,
`Map: ${info[2]} (${info[3]}/${info[4]})`, true)
})
message.channel.send(embed)
}
}
Code: Select all
[
"208.103.169.16",
"208.103.169.12"
]
Ignore any bad things I do in JS, it's not my first language!
This took me some time to figure out how to do this, so I thought it might be helpful to share here if anyone else would like to use this on their Discords!