ID:264333
 
Code:
world
IsBanned(key,address)
.=..()
if(!islist(.)) .=list("Login"=1,"desc")
if(multikeyCheck(address))
.["Login"] = 0
.["desc"] = "Multikeying has been disabled. Please log out with your other key before logging in with this one."

var
canMultikey = FALSE
excuseHost = FALSE
proc
multikeyCheck(var/address)
if(!address || canMultikey) return FALSE
if(excuseHost && isHost(address)) return FALSE
for(var/client/C)
if(C.address == address) return TRUE
return FALSE
isHost(var/address)
if(!address || world.address == address || address == "localhost")
return TRUE
return FALSE


Problem description:

When I host in DreamDaemon, it doesn't stop me from multikeying, but when I host from my server, it doesn't allow ANY clients to connect. Why? I'm using CaptFalcon33035's IsBanned() snippet at http://www.byond.com/members/Jtgibson/forum?id=180&view=0
world/IsBanned() doesn't work on the host.
<small>(Dunno why, but so much of TRUE and FALSE actually hurts my eyes a little bit. Guess I'm too used to the actual values.)</small>

Now, I realize that wasn't written by you, but I'm going to say it anyway and assume you're unaware of it as well. That's not precisely how to use world/IsBanned(); first, the Login 'parameter' is meant to only ever be used by setting it to 1 to allow a banned user to still login. It is not necessary to use it, and setting it to 0 will have no effect; the way the proc works is, if it returns a true value (this includes the value of a list, naturally), then the user IsBanned (or at least considered so) and not allowed to login.
Additionally, IsBanned() is never called for the host when he connects*, unless he he connects from "outside" in a roundabout way (by using his external IP address to connect, also granting him that address). While on that subject, a host's IP will also never be set to a word such as "localhost" as far as I'm aware, only the IP 127.0.0.1 in that case, which is what the system translates it to when you try to connect through it anyway. While on that subject, it'd be a little better turn that isHost() proc into a #define; it's a quick check which's return value can be just used immediately, it doesn't really warrant a new proc.

*: This does make it harder to test IsBanned() overrides and stuff, and makes so you can't prevent host multikeying in this manner. Maybe someone should ask for it to be changed.

So to clarify, IsBanned() works like this:
world/IsBanned()
return 1 //player considered banned: deny entry
return "poo" //deny entry
return new /obj //deny entry
return new /list ; return list() //deny entry
return list("desc" = "GTFO!") //deny entry and show a message

return 0 //player isn't banned: allow entry
return null //allow entry

return list("Login=1") //player is considered banned, but allow him entry anyway, even if he's pager-banned


I'm not entirely sure on why that code will specifically cause the world to reject everyone (do they get the multikey message?), but the little cleaning up that should be done to it should have the side effect of solving that anyway.
In response to Kaioken
So I could just do this...
var/list/OnlineAdds = list()
client/New()
..()
ClientAdds += address
client/Del()
..()
ClientAdds -= address

world/IsBanned()
if(address in OnlineAdds) return TRUE
else return FALSE

..and it'll still do the same thing? (minus the host of course)
In response to Mizukouken Ketsu
No, you're not using the arguments in IsBanned().
In response to Andre-g1
I'm afraid I don't get what you mean by "you're not using the arguments in IsBanned()". Would that be better? If not, please clarify?
var/list/OnlineAdds = list()
var/list/Banned_Keys = list()
var/list/Banned_IPs = list()
client/New()
..()
OnlineAdds += address //messed up on the list name lol
client/Del()
..()
OnlineAdds -= address //messed up on the list name lol

world/IsBanned(key,address) //<-- that?
if(address in OnlineAdds || address in Banned_IPs || key in Banned_Keys) return TRUE
return FALSE
In response to Mizukouken Ketsu
Yes, exactly that.
In response to Andre-g1
Alright! Thanks! :D
In response to Mizukouken Ketsu
Yes, after you fix the compilation error as Andre said. But you'd want to let the player know why he can't connect and all (otherwise, he might be deluded into thinking the game or his internet connection is down, he was banned, or something else, and it's common courtesy to at least leave a message before kicking someone off anyway :P).

With IsBanned() you could have it like this:
world/IsBanned(k,addr)
for(var/client/C)
if(C.address = addr)
return list(desc="You're already logged into this game on another key. Please log out first if you wish to connect on this one.")

Mind that much already does the job (though you need to add return ..() or keybans and similar ones are rendered disabled). Annoyingly though, you have to farm this to client/New() in order to block the host from doing this, but then again you have to add different, extra checks for that anyway, so might as well do it separately.
#define is_host_address(A) (!A || world.address == A || A == "127.0.0.1" || A == world.internet_address)

#define Is_Host(C) (world.host == C.key || is_host_address(C.address))

var
host_logged_in = 0
host_multikeying_allowed = 0

client/New()
if(Is_Host(src))
if(host_logged_in && !host_multikeying_allowed)
src << "Sorry, host multikeying is currently disabled. We thank you for your cooperation. \n\
Now, DISAPPEAR!

del src
host_logged_in = 1
return ..()

client/Del()
if(Is_Host(src)) host_logged_in = 0
..()


EDIT: Forgot to actually include the "host-block-toggle" part in the code, hehe.
In response to Kaioken
The host is a server so nobody's going to have its IP lol Unless someone logs into the game FROM the server itself of course. Which should never happen in my case. Plus I could care less if the host can multikey. As far as I'm concerned, it'll be an added benefit for him since his server is 24/7 with virtually no lag :)
In response to Mizukouken Ketsu
Heh, yeah it wouldn't be a problem with a remote host, but I covered that for the sake of completion. The fact IsBanned() isn't called for the host or 'executor' does make it more annoying to test, I think I'm going to <s>whine</s> suggest changing that. Though you could manually call it for testing, but meh.
In response to Kaioken
Okay well, for some reason, it's allowing multikeying with me and a couple other people I tested it out on... I host the game on the server, and when I log on with one key, then the other, it doesn't prevent my other key. Nor does it prevent anyone else's second key from connecting. Why's that?
In response to Kaioken
I'm not sure why I made the thing a list in the first place, either. It probably has something to do with me skipping down the reference to the parameters of the list that world.IsBanned() returns. As for the procedure completely disregarding the host, I had no knowledge of that whatsoever, but it can't be changed now--there could be a good amount of games that abuse this fact. A bit flag should work some wonders, though.

var/const/isBannedHostCheck = // TRUE / FALSE


As to why it restricts all clients, that is truly weird. I don't see any issue there at all.