The following is something I put together this afternoon to try and meet the requirements I set forth in my proposal to *Core-DB-Issues on LambdaMOO. What I think it will do (comments? bugs?) is allow one to set the maximum number of players permitted on the MOO at any one time ($login.maximum_users), and it will boot an idle player if needed to maintain that limit. A player's idle time must exceed $login.maximum_idle (and non-wizardly) in order to be a candidate for this booting. When a player is booted, e receives $login.deferred_msg just before being disconnected. When a player tries to connect but the MOO is full and there isn't anyone suitable to boot, e receives $login.no_room_msg as eir failure message. It is possible that these should come from verbs instead of raw properties, but I couldn't think of any useful substitutions to put in place. The @login:connect used below is, I believe, straight from LambdaCore, with a minor modification to include these new limitations. All wizardly things are, by default, owned by #2. All non-wizardly things are, by default, owned by $hacker. Please send bugs and comments to Blackbriar, at whatever MOO you find him at. [23 February 1993] @property $login.maximum_users 0 "r" #2 @property $login.deferred_msg "" "r" #2 ;$login.deferred_msg = "You have been idle for too long, and someone else wants to connect to the MOO. Come back later." @property $login.no_room_msg "" "r" #2 ;$login.no_room_msg = "There is no room for you on the MOO. Please try again later." @property $login.maximum_idle 3600 "r" #2 @verb $login:can_connect this none this rxd $Hacker @program $login:can_connect "$login:can_connect ( player object )"; "=> 1 if there's room for the player to log in, or is wizardly"; "=> 0 if not."; "=> E_PERM if the verb's not called by $login"; "This verb will handle the booting of an idle player, if such proves necessary."; if (caller != this) "caller must be $login becuse the booting of a player is in here as well"; return E_PERM; endif who = args[1]; if (who.wizard) return 1; elseif (!this.maximum_users) return 1; elseif (length(connected_players()) < this.maximum_users) return 1; else doomed = this:find_bootable_player(); if (doomed == 0) return 0; else this:boot_idle_player(doomed); return 1; endif endif .. @verb $login:find_bootable_player this none this rxd $Hacker @program $login:find_bootable_player "$login:find_bootable_player()"; "=> 0 if there is no player suitable for booting"; "=> player object is there is a player suitable for booting."; "It will return the most idle player, if such exists, who is non-wizardly and who has been idle for longer than $login.maximum_idle seconds."; players = connected_players(); idle_times = {}; for x in (players) idle_times = {@idle_times, idle_seconds(x)}; endfor idlers = $list_utils:reverse($list_utils:sort(players, idle_times)); for x in (idlers) if ((!x.wizard) && (idle_seconds(x) > this.maximum_idle)) return x; endif endfor return 0; .. @verb $login:boot_idle_player this none this rxd #2 @program $login:boot_idle_player "$login:boot_idle_player ( player object )"; "This boots a player who has been idle for too long. The player being booted received the text stored in $login.deferred_msg before being boot_player()'d."; if (caller != this) return E_PERM; endif who = args[1]; who:notify(this.deferred_msg); boot_player(who); .. @program $login:connect you_lose_msg = "Either that player does not exist, or has a different password."; if (caller != #0) return E_PERM; "...caller isn't :do_login_command..."; elseif (!(length(args) in {1, 2})) notify(player, tostr("Usage: ", verb, " ")); elseif (!valid(candidate = this:_match_player(name = strsub(args[1], " ", "_")))) notify(player, you_lose_msg); "...unknown player..."; elseif ((typeof(candidate.password) == STR) && ((length(candidate.password) < 2) || (crypt({@args, ""}[2], candidate.password[1..2]) != candidate.password))) notify(player, you_lose_msg); "...bad password..."; server_log(tostr("FAILED CONNECT: ", args[1], " (", candidate, ") on ", connection_name(player), ($string_utils:connection_hostname(connection_name(player)) in candidate.all_connect_places) ? "" | "******")); elseif ((parent(candidate) == $guest) && (!valid(candidate = candidate:defer()))) notify(player, (candidate == #-2) ? "Sorry, guest characters are not allowed from your site." | "Sorry, all of our guest characters are in use right now."); elseif (!this:can_connect(candidate)) notify(player, this.no_room_msg); else if ((!(name in candidate.aliases)) && (name != tostr(candidate))) notify(player, tostr("Okay,... ", name, " is in use. Logging you in as `", candidate.name, "'")); endif this:record_connection(candidate); return candidate; endif return 0; ..