Keywords: deny, guest
I know some of you want to keep guests out of your game for specific reasons including ckey-specific save systems, ban avoidance, etc.

So how do we go about this? The best time to check is before the person join the server - when DM checks if the person entering is banned via the host's pagerban - which is at world/IsBanned().

The best part of this is that if the person is not logged in, they cannot download any resources from the server.

//  Guest Denial Snippet
// Made by GhostAnime
// August 4, 2014

IsBanned(key,address,computer_id) // This is called before the person is logged in to the server. It will help save resources from being downloaded if the person is banned as they will be disconnected before the rsc d/l starts
. = ..() // Check if the person is already banned
if(findtext(key, "Guest-", 1, 7)) // If a Guest logs in [NOTE: Does not affect the host. If you want the host to be with a key... well, I'll show you shortly
.["Login"] = 0 // Deny the person from logging in
.["message"] = "Please log in to play []" // A message displayed to the Guest informing why they cannot login.
// There is also .["reason"] which is the reason why the person was pager banned. Not needed here though

Edit: As Pirion mentioned, the message may not be received by the user explaining why they were unable to log in due to the splash screen.

As an alternative for this case, move the check under client/New()


As you may have read above, the host is the exception.

So what do you do if you want to make sure that the host is logged in? You have at least three choices:
(1): Verify if the host/player is logged in at client/Login()


(2) Deny the host from hosting the game:
OpenPort(Port=0) // This is called when the host of the game is attempting to host.
if(! || findtext(, "Guest-", 1, 7)) // If you REALLY want the host to be logged in for hosting,,,
world.log << "Please log in to host this game!"
return 0 // Deny the game from being hosted

.=..() // Allow the game to be hosted if the is set to a non-Guest key
world.log << "The game is \..." // \... surpresses a newline

if(.) // If the hosting was successful. I could have the compact-if() statement [X?Y:Z] here as well. which is like saying if(X){return Y}else{return Z}
world.log << "now hosted on port [.]!"
else // The game did not open the port for whatever reason
world.log << "NOT hosted.\nFailed to open Port [.]"

(3) Alternatively, you could do the check at world/New() and shutdown/delete the world if the host is not logged in.

New(Port=0) // This is called when the game starts.
if(! || findtext(, "Guest-", 1, 7)) // If you REALLY want the host to be logged in for hosting,,,
return ..() // In case you have any world/New() instances
Love it :)
.["message"] doesn't appear on the login splash screen since the client update. The option and messages is disabled if the spash screen is up. This leaves your user in the dark as to why they aren't able to login. Pirion?command=view_post&post=1413072&first_unread=1

Maybe this will be fine in the web client.
In response to Pirion
Ah, I totally forgot about the splash screen :(

I will edit the main topi to reflect this, thank you :)
I recommend altering this code if anybody intends to use the web based client for their game. The web client would make it so people don't need to have BYOND downloaded and, in that case,they would always be a guest. In my project I made the login check to see if the usr is a guest and if they are it just lets them name their character. Of course their key still comes up as Guest-etc so save files don't become an issue. Just another use for this snippet.
That is not the case Halloween. The web client supports login, as has been stated in other threads.
In response to Pirion
I know, what I'm saying is that people without a byond account would still be able to name their character instead of having to go around as Guest-78292003 etc. I know that when I get to take advantage of the web client and invite all my friends I won't ask like this, "Hey play my game... but make an account here first" XP seems shady. That's actually why I am waiting for the web client, sounds even worse like, "Hey play my game... but download this program you don't know about". Just showing another use for checking for guests ^-^
I am not sure it'll be as bad as you expect.

I think it would be a a box that would that looks as though it is meant to be there, that supports creating new accounts (or a links to create an account), many embedded websites have things like this.

We will see once it has been launched though.
In response to Pirion
That is true, I'm sure they'll make it look nice but just in case I know I will leave in the option :P
Two notes: Now we have the connection type for IsBanned -allowing filtering based on client.

The second note I have is that I like to force world.IsBanned() behavior on the host because I like to log it, and may want to verify an external soruce. Therefore, I use the following code to make the call only for the host:

var/list/isBannedChecks = list()

world/IsBanned(key,address,computer_id,connection,localUser=0) //localUser is a custom parameter used for manual calls
. = ..(key,address,computer_id,connection)
world.log << "User '[key]' has attempted to connect. ([key],[address],[computer_id],[connection],[localUser ? "local" : "remote"])"

. = list("Login"=1)

if(.["Login"]==1) isBannedChecks += key


if(!(key in isBannedChecks))
var/list/result = world.IsBanned(key, address, computer_id, connection, 1)
src << "You've been banned. [result["message"]]"
del src
isBannedChecks -= key

Using this, you'd apply the same 'forced login' logic for hosts too.