Login Commands (#12)(an instance of Root Class made by The_Mayor)     This provides everything needed by #0:do_login_command. See `help $login' on $core_help for details. VERB SOURCE CODE: ?:
if (caller != #0)
return E_PERM;
else
clist = {};
for i in [0..length(verbs(this)) - 1]
if ((verb_args(this, tostr(i)) == {"any", "none", "any"}) && index((info
= verb_info(this, tostr(i)))[2], "x"))
vname = $string_utils:explode(info[3])[1];
star = index(vname + "*", "*");
clist = {@clist, $string_utils:uppercase(vname[1..star - 1]) + strsub(vname[star..length(vname)],
"*", "")};
endif
endfor
notify(player, "I don't understand that. Valid commands at this point are");
notify(player, " " + $string_utils:english_list(setremove(clist, "?"), "",
" or "));
return 0;
endif
.
wel*come @wel*come:
if (caller != #0)
return E_PERM;
else
msg = this.welcome_message;
version = server_version();
for line in ((typeof(msg) == LIST) ? msg | {msg})
if (typeof(line) == STR)
notify(player, strsub(line, "%v", version));
endif
endfor
this:check_player_db();
this:check_for_shutdown();
"dunno if we really need to see lag here. Dredful 2/16/94";
"this:maybe_print_lag()";
return 0;
endif
.
w*ho @w*ho:
masked = $login.who_masks_wizards ? $wiz_utils:connected_wizards() | {};
if (caller != #0)
return E_PERM;
elseif (!args)
$code_utils:show_who_listing($set_utils:difference(connected_players(), masked))
|| this:notify("No one logged in.");
else
plyrs = listdelete($command_utils:player_match_result($string_utils:match_player(args),
args), 1);
$code_utils:show_who_listing(plyrs, $set_utils:intersection(plyrs, masked));
endif
return 0;
.
co*nnect @co*nnect:
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, "
cr*eate @cr*eate:
if (caller != #0)
return E_PERM;
"... caller isn't :do_login_command()...";
elseif (!this:player_creation_enabled(player))
notify(player, this:registration_string());
"... we've disabled player creation ...";
elseif (length(args) != 2)
notify(player, tostr("Usage: ", verb, "
q*uit @q*uit:
if (caller != #0)
return E_PERM;
else
boot_player(player);
return 0;
endif
.
up*time @up*time:
if (caller != #0)
return E_PERM;
else
notify(player, tostr("The server has been up for ", $time_utils:english_time(time()
- $last_restart_time), "."));
return 0;
endif
.
v*ersion @v*ersion:
if (caller != #0)
return E_PERM;
else
notify(player, tostr("The MOO is currently running version ", server_version(),
" of the LambdaMOO server code."));
return 0;
endif
.
parse_command:
":parse_command(@args) => {verb, args}";
"Given the args from #0:do_login_command,";
" returns the actual $login verb to call and the args to use.";
"Commands available to not-logged-in users should be located on this object and given
the verb_args \"any none any\"";
if (caller != #0)
return E_PERM;
endif
if (!args)
return {this.blank_command, @args};
elseif ((verb = args[1]) && ((verb_args(this, verb) == {"any", "none", "any"}) &&
index(verb_info(this, verb)[2], "x")))
return args;
else
return {this.bogus_command, @args};
endif
.
check_for_shutdown:
when = $shutdown_time - time();
if (when >= 0)
line = "***************************************************************************";
notify(player, "");
notify(player, "");
notify(player, line);
notify(player, line);
notify(player, "****");
notify(player, ("**** WARNING: The server will shut down in " + $time_utils:english_time(when
- (when % 60))) + ".");
for piece in ($generic_editor:fill_string($shutdown_message, 60))
notify(player, "**** " + piece);
endfor
notify(player, "****");
notify(player, line);
notify(player, line);
notify(player, "");
notify(player, "");
endif
.
check_player_db:
if ($player_db.frozen)
line = "***************************************************************************";
notify(player, "");
notify(player, line);
notify(player, "***");
for piece in ($generic_editor:fill_string("The character-name matcher is currently
being reloaded. This means your character name might not be recognized even though
it still exists. Don't panic. You can either wait for the reload to finish or you
can connect using your object number if you remember it (e.g., `connect #1234 yourpassword').",
65))
notify(player, "*** " + piece);
endfor
if (this:player_creation_enabled(player))
notify(player, "*** This also means that character creation is disabled.");
endif
notify(player, "***");
notify(player, line);
notify(player, "");
endif
.
_match_player:
":_match_player(name)";
"This is the matching routine used by @connect.";
"returns either a valid player corresponding to name or $failed_match.";
name = args[1];
if (valid(candidate = $string_utils:literal_object(name)) && is_player(candidate))
return candidate;
endif
".....uncomment this to trust $player_db and have `connect' recognize aliases";
if (valid(candidate = $player_db:find_exact(name)) && is_player(candidate))
return candidate;
endif
".....uncomment this if $player_db gets hosed and you want by-name login";
". for candidate in (players())";
". if (candidate.name == name)";
". return candidate; ";
". endif ";
". endfor ";
".....";
return $failed_match;
.
notify: set_task_perms(caller_perms()); notify(player, args[1]); . tell: "keeps bad things from happening if someone brings this object into a room and talks to it."; return 0; . player_creation_enabled:
"Accepts a player object. If player creation is enabled for that player object,
then return true. Otherwise, return false.";
"Default implementation checks the player's connecting host via $login:blacklisted
to decide.";
if (caller_perms().wizard)
return this.create_enabled && (!this:blacklisted($string_utils:connection_hostname(connection_name(args[1]))));
else
return E_PERM;
endif
.
newt_registration_string registration_string:
return $string_utils:subst(this.(verb), {{"%e", this.registration_address}, {"%%",
"%"}});
.
init_for_core:
if (caller_perms().wizard)
pass();
this.max_connections = 999999;
this.bogus_command = "?";
this.blank_command = "help";
this.create_enabled = 1;
this.registration_address = "";
this.registration_string = "Character creation is disabled.";
this.newt_registration_string = "Your character is temporarily hosed.";
this.welcome_message = {"Welcome to the LambdaCore database.", "", "Type 'connect
wizard' to log in.", "", "You will probably want to change this text, which is stored
in $login.welcome_message."};
this.redlist = this.blacklist = this.graylist = this.spooflist = {{}, {}};
this.who_masks_wizards = 0;
if ("monitor" in properties(this))
delete_property(this, "monitor");
endif
if ("monitor" in verbs(this))
delete_verb(this, "monitor");
endif
if ("special_action" in verbs(this))
set_verb_code(this, "special_action", {});
endif
endif
.
special_action: . blacklisted graylisted redlisted spooflisted:
":blacklisted(hostname) => is hostname on the .blacklist";
":graylisted(hostname) => is hostname on the .graylist";
":redlisted(hostname) => is hostname on the .redlist";
sitelist = this.(this:listname(verb));
if (!caller_perms().wizard)
return E_PERM;
elseif (((hostname = args[1]) in sitelist[1]) || (hostname in sitelist[2]))
return 1;
elseif ($site_db:domain_literal(hostname))
for lit in (sitelist[1])
if ((index(hostname, lit) == 1) && ((hostname + ".")[length(lit) + 1] ==
"."))
return 1;
endif
endfor
else
for dom in (sitelist[2])
if (index(dom, "*"))
"...we have a wildcard; let :match_string deal with it...";
if ($string_utils:match_string(hostname, dom))
return 1;
endif
else
"...tail of hostname ...";
if ((r = rindex(hostname, dom)) && ((("." + hostname)[r] == ".") && (((r
- 1) + length(dom)) == length(hostname))))
return 1;
endif
endif
endfor
endif
return 0;
.
blacklist_add graylist_add redlist_add spooflist_add:
if (!caller_perms().wizard)
return E_PERM;
endif
where = args[1];
lname = this:listname(verb);
which = 1 + (!$site_db:domain_literal(where));
this.(lname)[which] = setadd(this.(lname)[which], where);
return 1;
.
blacklist_remove graylist_remove redlist_remove spooflist_remove:
if (!caller_perms().wizard)
return E_PERM;
endif
where = args[1];
lname = this:listname(verb);
which = 1 + (!$site_db:domain_literal(where));
if (where in this.(lname)[which])
this.(lname)[which] = setremove(this.(lname)[which], where);
return 1;
else
return E_INVARG;
endif
.
listname:
return {"???", "blacklist", "graylist", "redlist", "spooflist"}[1 + index("bgrs",
(args[1] || "?")[1])];
.
record_connection:
":record_connection(plyr) update plyr's connection information";
"to reflect impending login.";
if (!caller_perms().wizard)
return E_PERM;
else
plyr = args[1];
plyr.first_connect_time = min(time(), plyr.first_connect_time);
plyr.previous_connection = {plyr.last_connect_time, $string_utils:connection_hostname(plyr.last_connect_place)};
plyr.last_connect_time = time();
plyr.last_connect_place = cn = connection_name(player);
chost = $string_utils:connection_hostname(cn);
acp = setremove(plyr.all_connect_places, chost);
plyr.all_connect_places = {chost, @acp[1..min(length(acp), 15)]};
if (parent(plyr) != $guest)
$site_db:add(plyr, chost);
endif
endif
.
who(vanilla):
if (caller != #0)
return E_PERM;
elseif (!args)
$code_utils:show_who_listing(connected_players()) || this:notify("No one logged
in.");
else
plyrs = listdelete($command_utils:player_match_result($string_utils:match_player(args),
args), 1);
$code_utils:show_who_listing(plyrs);
endif
return 0;
.
sample_lag:
if (!caller_perms().wizard)
return E_PERM;
endif
while (1)
this.last_lag_sample = now = time();
suspend(15);
lag = (time() - now) - 15;
this.lag_samples = {lag, @this.lag_samples[1..3]};
endwhile
.
is_lagging: return this:current_lag() > this.lag_cutoff; . max_connections:
max = this.max_connections;
if (typeof(max) == LIST)
if (this:is_lagging())
max = max[1];
else
max = max[2];
endif
endif
return max;
.
request_character:
"request_character(player, name, address)";
"return true if succeeded";
if (!caller_perms().wizard)
return E_PERM;
endif
who = args[1];
name = args[2];
address = args[3];
connection = $string_utils:connection_hostname(connection_name(who));
if (reason = $wiz_utils:check_player_request(name, address, connection))
prefix = "";
if (reason[1] == "-")
reason = reason[2..length(reason)];
prefix = "Please";
else
prefix = "Please try again, or, to register another way,";
endif
notify(who, reason);
notify(who, tostr(prefix, " mail to ", $login.registration_address, ","));
notify(who, " with the character name you want.");
return 0;
endif
if (lines = $no_one:eval_d("$local.help.(\"multiple-characters\")")[2])
notify(who, "Remember, in general, only one character per person is allowed.");
notify(who, tostr("Do you already have a ", $network.moo_name, " character? [enter
`yes' or `no']"));
answer = read(who);
if (answer == "yes")
notify(who, "Process terminated *without* creating a character.");
return 0;
elseif (answer != "no")
return notify(who, tostr("Please try again; when you get this question, answer
`yes' or `no'. You answered `", answer, "'"));
endif
notify(who, "For future reference, do you want to see the full policy (from `help
multiple-characters'?");
notify(who, "[enter `yes' or `no']");
if (read(who) == "yes")
for x in (lines)
for y in ($generic_editor:fill_string(x, 70))
notify(who, y);
endfor
endfor
endif
endif
notify(who, tostr("A character named `", name, "' will be created."));
notify(who, tostr("A random password will be generated, and mailed with"));
notify(who, tostr(" an explanatory message to: ", address));
notify(who, "Is this OK? [enter `yes' or `no']");
if (read(who) != "yes")
notify(who, "Process terminated *without* creating a character.");
return 0;
endif
"took out Automatic creation, Dredful 2/16/94";
if ($player_db.frozen)
notify(who, "Sorry, can't create any new players right now. Try again in a few
minutes.");
return 0;
else
$mail_agent:send_message($registration_db.registrar, $registration_db.registrar,
"Player request", {"Player request from " + connection, "", (("@make-player " + name)
+ " ") + address});
$local.request_board:add_req($registration_db.registrar:length_all_msgs());
notify(who, tostr("Request for new character ", name, " email address '", address,
"' accepted."));
notify(who, tostr("Please be patient until the registrar gets around to it."));
notify(who, tostr("If you don't get email within a week, please send regular"));
notify(who, tostr(" email to: ", $login.registration_address, "."));
return 1;
endif
"This is the old stuff, Dredful 2/16/94";
if (!$network.active)
else
new = $wiz_utils:make_player(name, address);
password = new[2];
new = new[1];
notify(who, tostr("Character ", name, " (", new, ") created."));
notify(who, tostr("Mailing password to ", address, "; you should get the mail
very soon."));
notify(who, tostr("If you do not get it, please do NOT request another character."));
notify(who, tostr("Instead, send regular email to ", $login.registration_address,
","));
notify(who, tostr("with the name of the character you requested."));
$mail_agent:send_message(this.owner, $new_player_log, tostr(name, " (", new,
")"), {address, tostr(" Automatically created at request of ", valid(player) ? player.name
| "unconnected player", " from ", connection, ".")});
$wiz_utils:send_new_player_mail(tostr("Someone connected from ", connection,
" at ", ctime(), " requested a character on ", $network.moo_name, " for email address
", address, "."), name, address, new, password);
return 1;
endif
.
req*uest @req*uest:
if (caller != #0)
return E_PERM;
endif
"must be #0:do_login_command";
if (!this.request_enabled)
notify(player, this:registration_string());
elseif ((length(args) != 3) || (args[2] != "for"))
notify(player, tostr("Usage: ", verb, "
h*elp @h*elp:
if (caller != #0)
return E_PERM;
else
msg = this.help_message;
for line in ((typeof(msg) == LIST) ? msg | {msg})
if (typeof(line) == STR)
notify(player, line);
endif
endfor
return 0;
endif
.
maybe_print_lag:
lag = this:current_lag();
if (lag > 1)
lagstr = tostr("approximately ", lag, " seconds");
elseif (lag == 1)
lagstr = "approximately 1 second";
else
lagstr = "low";
endif
notify(player, tostr("The lag is ", lagstr, "; there are ", length(connected_players()),
" players connected."));
.
current_lag:
"estimate current lag as max of most recent sample and average of the rest of the
samples";
thislag = max(0, (time() - this.last_lag_sample) - this.lag_sample_interval);
if (thislag > (60 * 10))
"more than 10 minutes, probably the lag sampler stopped";
return -1;
endif
samples = this.lag_samples;
thislag = max(thislag, samples[1]);
sum = 0;
cnt = 0;
for x in (listdelete(samples, 1))
sum = sum + x;
cnt = cnt + 1;
endfor
return max(thislag, samples[1], sum / cnt);
.
request_character(old):
"request_character(player, name, address)";
"return true if succeeded";
return;
if (!caller_perms().wizard)
return E_PERM;
endif
who = args[1];
name = args[2];
address = args[3];
connection = $string_utils:connection_hostname(connection_name(who));
if (reason = $wiz_utils:check_player_request(name, address, connection))
prefix = "";
if (reason[1] == "-")
reason = reason[2..length(reason)];
prefix = "Please";
else
prefix = "Please try again, or, to register another way,";
endif
notify(who, reason);
notify(who, tostr(prefix, " mail to ", $login.registration_address, ","));
notify(who, " with the character name you want.");
return 0;
endif
if (lines = $no_one:eval_d("$local.help.(\"multiple-characters\")")[2])
notify(who, "Remember, in general, only one character per person is allowed.");
notify(who, tostr("Do you already have a ", $network.moo_name, " character? [enter
`yes' or `no']"));
answer = read(who);
if (answer == "yes")
notify(who, "Process terminated *without* creating a character.");
return 0;
elseif (answer != "no")
return notify(who, tostr("Please try again; when you get this question, answer
`yes' or `no'. You answered `", answer, "'"));
endif
notify(who, "For future reference, do you want to see the full policy (from `help
multiple-characters'?");
notify(who, "[enter `yes' or `no']");
if (read(who) == "yes")
for x in (lines)
for y in ($generic_editor:fill_string(x, 70))
notify(who, y);
endfor
endfor
endif
endif
notify(who, tostr("A character named `", name, "' will be created."));
notify(who, tostr("A random password will be generated, and mailed with"));
notify(who, tostr(" an explanatory message to: ", address));
notify(who, "Is this OK? [enter `yes' or `no']");
if (read(who) != "yes")
notify(who, "Process terminated *without* creating a character.");
return 0;
endif
if (!$network.active)
$mail_agent:send_message(this.owner, $registration_db.registrar, "Player request",
{"Player request from " + connection, ":", "", (("@make-player " + name) + " ") +
address});
notify(who, tostr("Request for new character ", name, " email address '", address,
"' accepted."));
notify(who, tostr("Please be patient until the registrar gets around to it."));
notify(who, tostr("If you don't get email within a week, please send regular"));
notify(who, tostr(" email to: ", $login.registration_address, "."));
elseif ($player_db.frozen)
notify(who, "Sorry, can't create any new players right now. Try again in a few
minutes.");
else
new = $wiz_utils:make_player(name, address);
password = new[2];
new = new[1];
notify(who, tostr("Character ", name, " (", new, ") created."));
notify(who, tostr("Mailing password to ", address, "; you should get the mail
very soon."));
notify(who, tostr("If you do not get it, please do NOT request another character."));
notify(who, tostr("Instead, send regular email to ", $login.registration_address,
","));
notify(who, tostr("with the name of the character you requested."));
$mail_agent:send_message(this.owner, $new_player_log, tostr(name, " (", new,
")"), {address, tostr(" Automatically created at request of ", valid(player) ? player.name
| "unconnected player", " from ", connection, ".")});
$wiz_utils:send_new_player_mail(tostr("Someone connected from ", connection,
" at ", ctime(), " requested a character on ", $network.moo_name, " for email address
", address, "."), name, address, new, password);
return 1;
endif
.
PROPERTY DATA:       welcome_message       newt_registration_string       registration_string       registration_address       create_enabled       bogus_command       blank_command       graylist       blacklist       redlist       who_masks_wizards       max_player_name       spooflist       ignored       max_connections       connection_limit_msg       lag_samples       request_enabled       help_message       last_lag_sample       lag_sample_interval       boot_exceptions       boot_process       lag_cutoff |