ID:195053
 
This is a simple function that acquires a list of servers in datum format from a specified hub entry. From there, you can display the servers in the game or compile data from them or do whatever you'd like. The format for displaying server data is at the bottom.

The ideal purpose is to provide a list of servers that players can join from within a game itself.

Please report any issues you find with it.

//Title: Server Listing
//Credit to: Foomer
//Contributed by: Foomer


// ACQUIRING A LIST OF SERVERS
/***********************************************************************
Demo function: This will give you a list of servers being hosted for
the specified game. If there are no servers being hosted, it will say so.
***********************************************************************/


// Example address: "Abra.Castle"

mob/verb/ViewServers(address as text)

if(src.key == "Guest")
src << "You must be logged in to BYOND to view servers."
return

// Attempt to get a list of servers from that address. If no address
// was provided, then we'll search for Abra.Castle by default, since it
// usually has some servers to show.
var/list/servers = get_servers(address)

// Servers found, display a list of servers for that address.
if(servers)
//src << "Servers found for [address]:"

for(var/server/S in servers)
S.Display(src)

src << ""

// No servers.
else
src << "No servers found."



/***********************************************************************
The get_servers() function will scan the hub page of the specified
server and find any available servers for it. It will then create
a series of server datums for each server, fill in the appropriate
information for them, and return the list of server datums.
***********************************************************************/


proc/get_servers(author, game)
if(!author)
CRASH("No author specified")
return

// Get the hub page for the game.
var/address[]
if(!game)
address = world.Export("http://www.byond.com/games/[author]?format=text")
else
address = world.Export("http://www.byond.com/games/[author]/[game]?format=text")

// Web address not found.
if(!address)
CRASH("Web address not found: [address]")
return

// No such hub entry on BYOND servers.
if(address["CONTENT-LENGTH"] == "305")
CRASH("No such hub entry: [address]")
return

// Acquire the content of the hub page in text format, and then
// import the contents of the address into a savefile.
var/text = file2text(address["CONTENT"])
var/savefile/savefile = new()
savefile.ImportText("/", text)

// Create a list of servers.
var/list/servers = list()

// Open up the "world" directory in the savefile.
for(var/directory in savefile.dir)
savefile.cd = "/[directory]"

// Loop through the server subdirectories in the savefile.
for(var/subdirectory in savefile.dir)

// If this subdirectory is not a number, then its not a server.
if(!text2num(subdirectory))
continue

savefile.cd = "/[directory]/[subdirectory]"

// Create a new server datum for this server listing.
var/server/server = new()
server.url = savefile["url"]
server.status = savefile["status"]
server.users = savefile["users"]

// Add this completed server datum to the list.
servers += server

// Send a list of server datums back to the user.
return servers



/***********************************************************************
The server datum contains the url, status and list of users who are
currently playing on any given server. When a new server is created,
this information should be provided as arguments for the new proc.

To display server information to a mob or client, use Display(M). You
can adjust the formatting of the output to suit your game.
***********************************************************************/


server
var
url
status
list/users = list()


// Create a new server with the specified information.
New(new_url, new_status, list/new_users)
if(!new_url)
src.url = new_url

if(new_status)
src.status = new_status

if(new_users)
for(var/user in new_users)
users += user
return


// Display the server datum to M, which may be a mob or a client.
proc/Display(mob/M)

// If its not a proper recipient, abort the display.
if(!ismob(M) && !istype(M, /client))
return 0

// If its a mob, make sure it has a client before displaying to them.
if(ismob(M))
if(!M.client)
return 0

// Display the server status and how many players there are.
M << "<b><a href='[url]'>Server: [src.status]</a></b>"
if(users.len)
M << "[users.len] player\s playing."
else
M << "No players."
return
I haven't read through the whole code yet but I may have spotted a mistake, where you check to see if the source of the verb's key is equal to Guest, You did ("If(src.key=="Guest")") wheras all BYOND guest keys have a certain number after the word of Guest.. so it would never be true, unless a Key was specially made with the alias guest.

Anyhow,

mob
verb
CheckGuest()
if(copytext(key,1,6)=="Guest" && isnum(text2num(copytext(key,7,0))))
src << "Elooo Mr.Guest"
else
src << "Howdy, [key]"


Probally tons of other ways to do this.

Time to read the rest :P
In response to Haywire
Sounds good. The new Guest system didn't exist when I created the original snippet. This is how little changes end up breaking old games.