Using Discord to pull Server Information using Gamedig

This is used for general discussion that is not necessarily server-related.
Post Reply
User avatar
Vis
New to forums
New to forums
Posts: 1
Joined: Sun Jun 28, 2020 2:28 pm

Using Discord to pull Server Information using Gamedig

Post by Vis » Sun Jun 28, 2020 2:55 pm

Hello there,

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)
	}
}
All of the IPs are pulled from a JSON file that just contains an array of IP addresses (I was using the top 2 servers on Gametracker as examples to ensure it was working):

Code: Select all

[
	"208.103.169.16",
	"208.103.169.12"
]
And you get an output like this:

Image

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!

Post Reply