ID:2007008
 
(See the best response by Ter13.)
Code:
Boot(mob/PC/M in world)
set category = "GM"
set desc = "Who do you wish to boot?"
if(M == usr) usr << "Can't boot yourself."
else GM_Announce("[usr] Booted [M].");M.Logout()


Problem description:
Right now, this is my code for booting players out of the server

My code has three branches of /mobs, /mob/PC for player characters, /mob/monsters and /mob/spawns; I use the /mob/spawn to create random monsters in a place, allowing me to add rare enemies. My problem is, when I use the Boot verb, it shows not only players, but also monsters and spawns, is there a way to make it so only players will appear as an option for the verb?
Best response
The best way to handle this is to keep a list of players handy.

var
list/connected_players = list()

mob
Login()
connected_players += src
. = ..()
Logout()
connected_players -= src
..()


Provided you are keeping track of your players like the above, you can do something like this:

Boot()
set category = "GM"
set desc = "Kick a player off the server"
var/mob/m = input(usr,"Who do you wish to boot?","Boot \[player]") as null|anything in (connected_players-usr) //show all users who aren't the current person using the verb.
//you should check here to see if the usr is still a GM and is allowed to kick.
//The list prompt can delay functions indefinitely, so if you take away someone's admin while they are in a menu, their actions will still be carried out after they are no longer an admin unless you have a post-prompt check.
if(m&&m.client) //you should also check here to make sure m is eligible for booting.
GM_Announce("[m] was booted") //best to not tell the players who did the booting because this tends to cause players to resent your administration
del m.client //you should never call Logout() manually. Delete the client forcibly to kick them.
I don't have access to my computer at the moment, but does 'world' count as a list, Ter?

Could you do

for(var/mob/M in world-typesof(/mob/monster))
In response to Rushnut
Rushnut wrote:
I don't have access to my computer at the moment, but does 'world' count as a list, Ter?

Could you do

for(var/mob/M in world-typesof(/mob/monster))


Stop and think about the values that typesof() returns and the types of values that are in world.contents for a minute. typesof() returns a series of type paths. world.contents only contains instances. Type paths are not equivalent to instances. All your -typesof() operation does is cost you a metric buttload CPU time doing nothing. It would actually be faster to just iterate through the world contents list in your example, but my approach will be considerably faster and cleaner in any reasonably sized project than any attempt to iterate through world.contents or manipulate it at all.

Also, Rushnut: This might be good for you:

http://www.byond.com/forum/?post=1810538

Basically, filtering through world.contents tends to mean that you are filtering through a list of potentially millions of individual entries.

When you subtract one list from another, each item in the right operand list is searched for inside the left operand list. Then, when it finds the result, it builds a resultant list with each value except the ones found in the right operand list.

The bigger the list, the longer list operations take.

The bigger the list, the longer list iteration takes.

The bigger the list, the longer list accesses take.

world.contents is very likely to be the single biggest list in entire project. As such, there is almost never a solution where searching through, or doing list operations on the world contents list is actually a smart thing to do.
Nono don't misunderstand, I'm not that much of an idiot! I understand the benefits of using contained lists. I actually use a personalized region system personally, which usually covers 25x25 chunks which have four lists on them (Areas, Turfs, Objects, Mobs) which I iterate through, and then I just do for(var/client/C) to find clients.

I was simply only asking as a query.
Thank you for the help.

I thought about making a list at first, but I wanted to avoid it if there was an easier way to filter through types.
I thought about making a list at first, but I wanted to avoid it if there was an easier way to filter through types.

Generally speaking, that's the opposite of what you want to do in all cases.

Memory consumption is sort of a non-issue. If there's something that you will frequently need to pull data from, it is always best to store it somewhere for later.

Building the list takes up a little bit of CPU. Filtering the list takes a lot of CPU the bigger it is and the more per-iteration complexity there is within the loop.

CPU is the bottleneck you are going to run into when working with multiplayer games. Better to get in the good habits early than learn bad habits from the anime game leaked source code drek that promulgates itself around here.