parent $body
parent $interaction
parent $mail_ui
parent $command_aliases
parent $bad_commands
parent $user_data
parent $set_ui
parent $has_settings
parent $help_ui
parent $has_messages
object $user
var $root child_index 47
var $root owners [$user]
var $root fertile 0
var $has_commands commands [["@quit", 'quit_cmd], ["i?nventory", 'inventory_cmd], ["@title *", 'title_cmd], ["@add-name-alias|@ana *", 'add_name_alias_cmd], ["@del-name-alias|@dna *", 'del_name_alias_cmd], ["@rename * to *", 'rename_cmd], ["@time *", 'time_cmd], ["@audit *", 'audit_cmd], ["@who *", 'who_cmd], ["@del-command-a?lias|@dca?lias *", 'del_command_alias_cmd], ["@command-a?liases|@ca?liases *", 'command_aliases_cmd], ["@wrap *", 'wrap_cmd], ["@prompt *", 'prompt_cmd], ["@password *", 'password_cmd], ["@idle", 'idle_cmd], ["@add-command-a?lias|@aca?lias *", 'add_command_alias_cmd], ["@login-watch *", 'watch_logins_cmd], ["@com?mands *", 'commands_cmd], ["@age *", 'age_cmd], ["@status", 'status_cmd], ["@spawn *", 'spawn_cmd], ["@rehash?-commands", 'rehash_cmd], ["@name-aliase?s|@na *", 'name_aliases_cmd], ["@news", 'news_cmd], ["@remember *", 'remember_cmd], ["@remembered *", 'remembered_cmd], ["@forget *", 'forget_cmd], ["@whereis|@where-is *", 'whereis_cmd], ["@ways", 'ways_cmd], ["@prose *", 'prose_cmd], ["@describe *", 'describe_cmd], ["@gender *", 'gender_cmd]]
var $has_commands shortcuts []
var $has_verbs verbs #[]
var $location contents []
var $located location $nowhere
var $root inited 1
var $user password "*"
var $user connected_at 0
var $user last_command_at 0
var $user connections []
var $user linelen 0
var $user title 0
var $user email 0
var $user action 0
var $user creation_time 0
var $user home $body_cave
var $user pagelen 0
var $user activity 0
var $user parsers []
var $user filters []
var $user watch_logins 0
var $user tell_traceback 0
var $user last_name 0
var $root dbref 'user
var $user prompt ""
var $root owned [$user]
var $command_aliases command_aliases []
var $mail_list letters #[]
var $mail_list letters_index #[]
var $mail_list senders 1
var $mail_list readers [$core]
var $mail_list notify [$user]
var $mail_list last_letter 0
var $mail_ui subscribed #[[$user, 791485891]]
var $gendered gender $gender_neuter
var $located obvious 1
var $described prose #[]
var $root manager $user
var $root writable [$user]
var $root readable ['parameters, 'methods, 'code]
var $help_interface current_help $
var $help_interface help_dict #[["*", $], ["help", $], ["**", $]]
var $user context 0
var $named name ['uniq, "Generic User Object"]
var $named name_aliases []
var $user_data user_data #[['real_name, [1, "???"]], ['email, [1, "???"]]]
var $old_has_settings setting_templates #[["terminated-tell", 'boolean], ["Content-type", 'string], ["error-syntax-prefix", 'string], ["error-prefix", 'string]]
var $user remembered_places []
var $old_command_environment verb_cache #[]
var $old_command_environment command_cache [["@quit", 'quit_cmd], ["i?nventory", 'inventory_cmd], ["@title *", 'title_cmd], ["@add-name-alias|@ana *", 'add_name_alias_cmd], ["@del-name-alias|@dna *", 'del_name_alias_cmd], ["@rename * to *", 'rename_cmd], ["@time *", 'time_cmd], ["@audit *", 'audit_cmd], ["@who *", 'who_cmd], ["@del-command-a?lias|@dca?lias *", 'del_command_alias_cmd], ["@command-a?liases|@ca?liases *", 'command_aliases_cmd], ["@wrap *", 'wrap_cmd], ["@prompt *", 'prompt_cmd], ["@password *", 'password_cmd], ["@idle", 'idle_cmd], ["@add-command-a?lias|@aca?lias *", 'add_command_alias_cmd], ["@login-watch *", 'watch_logins_cmd], ["@com?mands *", 'commands_cmd], ["@age *", 'age_cmd], ["@prose|@describe *", 'prose_cmd], ["@status", 'status_cmd], ["@spawn *", 'spawn_cmd], ["@rehash?-commands", 'rehash_cmd], ["@name-aliase?s|@na *", 'name_aliases_cmd], ["@news", 'news_cmd], ["@remember *", 'remember_cmd], ["@remembered *", 'remembered_cmd], ["@forget *", 'forget_cmd], ["@whereis|@where-is *", 'whereis_cmd], ["wh?isper * to *", 'whisper_cmd], ["@register-ch?annel|@reg-ch?annel *", 'register_channel_cmd], ["@delete-ch?annel|@del-ch?annel *", 'delete_channel_cmd], ["say *", 'say_cmd], ["to * say *", 'say_to_cmd], ["@paste *", 'paste_cmd], ["page * with *", 'page_cmd], ["emote *", 'emote_cmd], ["strip *", 'strip_cmd], ["@tuned|@ch?annels *", 'channels_cmd], ["repeat *", 'repeat_cmd], ["@tune in|out *", 'tune_channel_cmd], ["on * say *", 'on_subj_cmd], ["vowel?ize *", 'late_vowels_cmd], ["epage * with *", 'page_emote_cmd], ["@m?ail * on *", 'mail_on_cmd], ["@mail-s?end|@ms?end * to *", 'send_to_cmd], ["@mail-sub?scribe|@msub?scribe *", 'subscribe_cmd], ["@mail-unsub?scribe|@munsub?scribe *", 'unsubscribe_cmd], ["@mail-l?ists|@ml?ists *", 'mail_lists_cmd], ["@m?ail * subject|subject:|s *", 'mail_subj_cmd], ["@mail-r?ead|@mr?ead * on *", 'read_cmd], ["@mail-r?ead|@mr?ead *", 'read_cmd], ["@mail-rem?ove|@mrm * from|on *", 'mail_remove_cmd], ["@mail-rem?ove|@mrm *", 'mail_remove_cmd], ["quit", 'old_command_cmd], ["WHO", 'old_command_cmd], ["@create *", 'old_command_cmd], ["@dig *", 'old_command_cmd], ["news", 'old_command_cmd], ["@finger-data|@user-data * my * is|are *", 'data_is_cmd], ["@finger|@user-data *", 'data_cmd], ["@set-finger|@set-user-data * as|to *", 'set_info_cmd], ["@set *", 'set_cmd], ["@add-setting *", 'add_setting_cmd]]
var $old_command_environment shortcuts_cache [["|*", '_interact, ["|", 1]], ["<*", '_interact, ["<", 1]], ["think *", 'think_cmd, [1]], ["%*", 'think_cmd, [1]], ["#*", 'channel_cmd, ["#", 1]], ["\"*", 'say_cmd, ["", 1]], [":*", 'emote_cmd, ["", 1]], ["!*", 'polite_spoof_cmd, [1]], ["''*", 'say_to_cmd, ["to", "", "say", 1]], ["'* *", 'say_to_cmd, ["to", 1, "say", 2]], ["--*", 'page_cmd, ["page", "", "with", 1]], ["-* *", 'page_cmd, ["page", 1, "with", 2]], ["++*", 'page_emote_cmd, ["epage", "", "with", 1]], ["+* *", 'page_emote_cmd, ["epage", 1, "with", 2]], ["]*", 'right_encapsulate_cmd, ["]", 1]], [")*", 'right_encapsulate_cmd, [")", 1]], ["@m?ail", 'mail_on_cmd, [1, "", "on", "me"]]]
var $has_settings settings 0
var $has_settings setting_types #[["terminated-tell", #[['type, "boolean"], ['check, 'is_boolean], ['get, 'get_direct_setting], ['set, 'set_direct_setting], ['del, 'del_direct_setting], ['set_args, ['name, 'definer, 'value, 'style]], ['get_args, ['name, 'definer]]]], ["content-type", #[['type, "string"], ['check, 'is_anything], ['get, 'get_direct_setting], ['set, 'set_direct_setting], ['del, 'del_direct_setting], ['set_args, ['name, 'definer, 'value, 'style]], ['get_args, ['name, 'definer]]]]]
var $has_settings setting_data #[[$user, #[["content-type", "text/plain"]]]]
var $help_ui current_node $help_node_summary
var $help_ui last_visited #[['pos, 1], ['nodes, [$help_node_summary]]]
var $mail_list mail []
var $mail_ui current #[['location, 0], ['list, $user]]
method init_user
.perms(caller(), $root);
password = "*";
connected_at = 0;
last_command_at = 0;
connections = [];
creation_time = time();
parsers = [$command_parser, $verb_parser];
filters = [$ctext_filter];
action = "";
prompt = "";
context = #[];
.set_quota($sys.get_starting('quota));
$user_db.insert(.namef(), this());
.set_readable([]);
.move_to($body_cave);
.
method uninit_user
var conn;
(> .perms(caller(), $root) <);
if (.connected())
(| (.location()).did_disconnect() |);
// and incase any are lying about
for conn in (connections)
(| conn.user_going_away() |);
password = 0;
connections = 0;
(| $user_db.remove(.name()) |);
.
method trusted
return pass() + ($parsers.children());
.
method will_move
arg mover, place;
(> pass(mover, place) <);
if (!(place.has_ancestor($place)))
throw(~perm, "Players can only move into rooms.");
.
method watch_logins
return watch_logins;
.
method connected_at
return connected_at;
.
method last_command_at
return last_command_at;
.
method tell
arg what;
var f;
if (filters) {
for f in (filters)
what = f.filter(what);
}
._tell(what);
.
method set_password
arg str;
var x, num;
.perms(sender(), 'manager);
if (strlen(str) < 5)
throw(~badpasswd, "Passwords must be at least 5 characters long.");
// this is assuming they have alphabetic characters as well (shrug).
// for x in [1 .. strlen(str)] {
// if (str[x] in "1234567890")
// num = num + 1;
// }
// if (num < 2)
// throw(~badpasswd, "Passwords must contain at least 2 numeric characters.");
password = crypt(str);
.
method check_password
arg str;
return crypt(str, substr(password, 1, 2)) == password;
.
method did_move
arg [args];
var loc;
(> pass(@args) <);
loc = .location();
(| loc.look_cmd("look") |);
.
method parsers
.perms(sender(), 'trusts);
return parsers;
.
method add_parser
arg parser, [position];
// adds a new $parser at 'position.
.perms(sender(), 'parser);
// do this in three steps, first make sure the posistion is valid,
// then check for it already, then figure its insert position.
position = [@position, 'first][1];
if (!(position in ['last, 'first]))
throw(~type, "Posistion types must be one of: 'last, 'first.");
// does it exist? If so remove it.
if (parser in parsers)
parsers = setremove(parsers, parser);
// figure position
if (position == 'last)
position = listlen(parsers) + 1;
else if (position == 'first)
position = 1;
parsers = insert(parsers, position, parser);
.
method del_parser
arg parser;
var keepers;
// removes a parser. Cannot remove $command_parser or $verb_parser
keepers = [$command_parser, $verb_parser];
if (!(parser in parsers))
throw(~parsernf, ($data.unparse(parser)) + " is not in the parser list.");
if (parser in keepers)
throw(~twink, ("You must always have " + ($list.map_to_english(keepers, 'namef))) + ".");
parsers = setremove(parsers, parser);
.
method parse_line
arg line;
var result, c;
(> .perms(caller(), $connection) <);
last_command_at = time();
catch any {
result = parsers ? (parsers[1]).parse(this(), line, @sublist(parsers, 2), $null_parser) | 'failed;
if (type(result) == 'list)
return (result[1]).(result[2])(@sublist(result, 3));
switch (result) {
case 'failed:
// try one last time to at least give them an intelligent
// answer...
for c in (($places.coordinate_shortcuts()).keys()) {
if (match_template(c, line))
return .tell(("There is no exit " + line) + " here.");
}
.tell(("I don't understand \"" + ($string.chop(line, (.linelen()) - 22))) + "\".");
case 'ok:
default:
.tell(tostr(result));
}
} with handler {
if (((traceback()[1])[3]) != 'no_traceback)
.tell_traceback(traceback(), line, 0, error());
}
.
method login
arg connection;
var loc;
if ((sender() != this()) || (definer() != caller()))
throw(~perm, "Invalid access to private method.");
.tell((("* * * Login successful (" + (connection.address())) + ") * * *").center(.linelen()));
.tell((("* * Last connection at " + ($time.date(abs(.connected_at())))) + " * *").center(.linelen()));
connected_at = time();
last_command_at = time();
//
loc = .location();
if (loc == $body_cave) {
if ((.home()) != $body_cave)
(| .move_to(.home()) |);
else
(| .move_to($places.place('starting)) |);
} else if ((loc == (.home())) || (loc != $body_cave)) {
(| loc.look_cmd("look") |);
} else {
(| .move_to(.home()) |);
}
(| (.location()).did_connect() |);
(| .login_notify() |);
(| $login_watcher.did_connect() |);
(| $user_db.did_connect() |);
.rehash_command_environment();
.
method login_again
arg connection;
if ((sender() != this()) || (definer() != caller()))
throw(~perm, "Invalid access to private method.");
last_command_at = time();
(| .tell($string.center(((("* * * " + ($integer.n_to_nth(connection in (.connections())))) + " Login successful (") + (connection.addr())) + ") * * *", .linelen())) |) || (| .tell($string.center(((("* * * " + ($integer.n_to_nth(connection in (.connections())))) + " Login successful (") + (connection.address())) + ") * * *", .linelen())) |);
.
method logout
arg connection;
if ((sender() != this()) || (definer() != caller()))
throw(~perm, "Invalid access to private method.");
(| (.location()).did_disconnect() |);
// set this to -last_command so we know they aren't connected
// (and using last command will be last_login)
connected_at = -last_command_at;
// user specific things
if (!($guest in (.parents()))) {
(| $housekeeper.did_disconnect() |);
(| $user_db.last_log_disconnect(this()) |);
} else {
(| $user_db.last_log_disconnect($guest) |);
}
(| $user_db.did_disconnect() |);
(| $login_watcher.did_disconnect() |);
.purge_command_environment();
.
method connections
return connections;
.
method connected
disallow_overrides;
return connections ? 1 | 0;
.
method who_cmd
arg com, [line];
var who, opts, opt, args;
// just the basic who listing
(> .perms(sender(), 'this) <);
who = [];
if (!(line[1])) {
args = [$user_db.connected(), "Connected Users"];
} else if (((line[1])[1]) == "@") {
args = ._who_at_place(substr(line[1], 2));
} else {
args = $parse.options(line[1]);
opts = args[2];
args = args[1];
if (opts) {
for opt in (dict_keys(opts)) {
switch (opt) {
case "p", "programmers":
args = ._who_programmers(args, opts);
break;
case "a", "admins":
args = ._who_admins(args, opts);
break;
case "s", "short":
._who_short();
return;
default:
.tell("Unknown @who option: -" + tostr(opt));
return;
}
}
} else {
args = ._who_is(@line);
}
}
if (!args)
return;
.tell($code.generate_listing(@args));
.
method email
return email || "**no email address**";
.
method quit_cmd
arg dummy;
.perms(sender(), 'parser);
return 'disconnect;
.
method inventory_cmd
arg dummy;
var i;
.perms(sender(), 'parser);
if (.contents()) {
.tell("Carrying:");
for i in (.contents())
.tell(" " + (i.namef()));
} else {
.tell("You are empty-handed.");
}
.
method match_env_nice
arg name, [syntax];
var obj, args, line;
// calls .match_environment() returns nice errors. as well as stopping if it
// breaks. No returns neccessary
syntax = [@syntax, ""][1];
catch any {
obj = .match_environment(name);
} with handler {
switch (error()) {
case ~ambig:
args = (traceback()[1])[3];
line = ("\"" + (args[listlen(args)])) + "\" can match any of: ";
line = line + ($list.map_to_english(args[1], 'namef));
(> $parse.tell_error(line, syntax) <);
case ~objnf:
line = ("Nothing found by the name \"" + ((traceback()[1])[3])) + "\".";
(> $parse.tell_error(line, syntax) <);
default:
line = (traceback()[1])[2];
(> $parse.tell_error(line, syntax) <);
}
}
return obj;
.
method linelen
return linelen || 79;
.
method idle_seconds
return time() - last_command_at;
.
method title
return title || "";
.
method action
// different from activity, returns a more accurate second to second action
if (.connected())
return action || "";
else
return "(asleep)";
.
method fooz
arg time;
connected_at = time;
.
method title_cmd
arg com, str;
.perms(sender(), 'parser);
.tell("Temporary until the real title setup is working");
catch any {
.set_title(str);
} with handler {
$parse.tell_error((traceback()[1])[2]);
}
.tell(("Title Set as: \"" + str) + "\"");
.
method commands_cmd
arg cmd, args;
var obj, coms, c, len, lcoms, scoms, ulen, l, what, a, opts, lines;
// returns all commands in a nice format.
.perms(sender(), 'parser);
args = explode(args);
if (!args) {
what = .ancestors();
.tell("All commands: (prepare to be spammed)");
} else {
what = [.match_env_nice(args[1])];
.tell("Commands on " + ((what[1]).namef('ref)));
}
ulen = .linelen();
for obj in (what) {
if (!((obj.has_ancestor($has_commands)) || (obj.has_ancestor($has_verbs))))
continue;
coms = [];
coms = coms + ((| $list.slice(obj.shortcuts(), 1) |) || []);
coms = coms + ((| $list.slice(obj.commands(), 1) |) || []);
coms = coms + ((| obj.verb_templates() |) || []);
if (coms) {
scoms = [];
lcoms = [];
for c in (coms) {
len = strlen(c) + 2;
if (len > (ulen / 3))
lcoms = [@lcoms, " " + c];
else
scoms = [@scoms, " " + c];
}
lines = ($list.lcolumnize(scoms, ulen)) + ($list.lcolumnize(lcoms, ulen));
for l in (lines)
.tell($string.trim(l, 'right));
.tell(" -=-");
}
if (obj == $has_commands)
break;
}
.
method tell_commands
arg p, ps, pc, space;
var x, a, c;
// called by $builder.commands_cmd
.tell(((((space + "Commands on ") + (p.namef('ref))) + " (") + toliteral(p)) + ")");
pc = ps + pc;
if (!pc) {
.tell(space + " None");
return;
}
for x in [1 .. listlen(pc)] {
a = pad(tostr((pc[x])[1]), 30) + " ";
c = pad(toliteral((pc[x])[2]), 20) + " ";
.tell(((space + " ") + a) + c);
}
.
method set_email
arg email_str;
var syn, email, host;
if (!(.is_writable_by(sender())))
throw(~perm, "Sender is not an owner.");
// kludgy way to check for semi valid email addresses:
email = explode(email_str, "@");
if (listlen(email) < 2)
throw(~invemail, "Invalid email: " + email_str);
// check hostname for at least 1 subnet and a machine name.
host = explode(email[2], ".");
if (listlen(host) < 2)
throw(~invemail, "Invalid hostname: " + (host[1]));
// email is purposefully constructed this way, as at one point it will
// be able to automatically tack on your host, if you do not provide it.
set_var('email, ((email[1]) + "@") + (email[2]));
.
method set_watch_logins
arg value;
// either have a single reference, or: 'none|'all
.perms(sender());
watch_logins = value;
.
method echo_file
arg str;
var con;
for con in (connections)
con.echo_file(str);
.
method set_home
arg obj;
// if (!obj.is_writable_by(sender()))
// return .tell("You do not own " + obj.namef() + ".");
home = obj;
.
method pagelen
return pagelen || 24;
.
method set_pagelen
arg len;
if (!(.is_writable_by(sender())))
throw(~perm, "Sender not an owner.");
if (type(len) != 'integer)
throw(~type, "pagelength must be an integer");
pagelen = len;
.
method set_linelen
arg len;
if (!(.is_writable_by(sender())))
throw(~perm, "Sender not an owner.");
if (type(len) != 'integer)
throw(~type, "Linelength must be an integer");
linelen = len;
.
method name_aliases_cmd
arg com, [obj];
if (!(.is_writable_by(sender())))
throw(~perm, "Sender not owner.");
obj = .match_env_nice((obj[1]) ? obj[1] | (.dbref()));
if (!(obj.has_ancestor($named))) {
.tell(("Object `" + (obj.dbref())) + "' is not a named object.");
throw(~stop, "", 'no_traceback);
}
.tell((("Aliases for " + (obj.namef())) + ": ") + ($list.to_english(obj.name_aliases(), "none")));
.
method activity
var idle;
// different from action, returns a broader version of your doings
if (!(.connected()))
return "asleep";
if (activity)
return activity;
idle = .idle_seconds();
if (idle < 180)
return "";
if (idle < 300)
return "daydreaming";
if (idle < 900)
return "zoned";
else
return "long gone";
.
method add_name_alias_cmd
arg com, [args];
var syn, obj, what;
if (!(.is_writable_by(sender())))
throw(~perm, "Sender not this");
syn = ("`" + com) + " <alias> to <object>' (to <object> is optional)";
args = explode(args[1]);
what = args[1];
obj = .match_env_nice([@args, .dbref(), .dbref()][3]);
if (!what)
$parse.tell_error("You must name an alias.", syn);
if (what in (.name_aliases()))
$parse.tell_error(("You already have the name alias `" + what) + "'");
catch any {
obj.add_name_alias(what);
} with handler {
switch (error()) {
case ~methodnf:
$parse.tell_error((obj.namef('ref)) + " is not a descendant of $xxxxxxxxx", syn);
default:
$parse.tell_error((traceback()[1])[2], syn);
}
}
.tell(((("Name Alias `" + what) + "' added to ") + (obj.namef())) + ".");
.
method modes
return modes;
.
method del_name_alias_cmd
arg com, [args];
var syn, obj, what;
if (!(.is_writable_by(sender())))
throw(~perm, "Sender not this");
syn = ("`" + com) + " <alias> from <object>' (from <object> is optional)";
args = explode(args[1]);
what = args[1];
obj = .match_env_nice([@args, .dbref(), .dbref()][3]);
if (!what)
$parse.tell_error("You must name an alias to delete.", syn);
if (!(what in (.name_aliases())))
$parse.tell_error((((obj.namef('ref)) + " doesn't have the name alias `") + what) + "'");
catch any {
obj.del_name_alias(what);
} with handler {
switch (error()) {
case ~methodnf:
$parse.tell_error((obj.namef('ref)) + " is not a descendant of $matchable", syn);
default:
$parse.tell_error((traceback()[1])[2], syn);
}
}
.tell(((((("Name Alias `" + what) + "' deleted from ") + (obj.namef())) + ", aliases are now: ") + ($list.to_english(.name_aliases()))) + ".");
.
method home
return home || $body_cave;
.
method set_dbref
disallow_overrides;
arg new_dbref;
if ((caller() != $user) && (!(sender() in ($sys.system()))))
throw(~perm, "User dbrefs can only be changed by $user.");
(> pass(new_dbref) <);
.
method rename_cmd
arg com, what, prep, line;
var syn, x, article, name;
if (sender() != this())
throw(~perm, "Sender is not this");
syn = ((com + " <object> ") + prep) + " <newname> [-proper|-unique]";
what = .match_env_nice(what);
if (!(what.has_ancestor($named)))
$parse.tell_error(("Object \"" + ($data.unparse(what))) + "\" is not descended from $named.", syn);
line = explode(line);
article = 'uniq;
for x in [1 .. listlen(line)] {
if ((line[x]) in "-proper") {
article = 'prop;
line = delete(line, x);
break;
}
if ((line[x]) in "-unique") {
article = 'uniq;
line = delete(line, x);
break;
}
}
name = $list.to_string(line);
catch any {
what.set_name(name, article);
} with handler {
$parse.tell_error((traceback()[1])[2], syn);
}
.tell("Name is now: " + (what.name()));
.
method time_cmd
arg command, [args];
var rtime, itime, ptime;
.perms(sender(), 'parser);
// rtime = "Terran Time: " + $time.ltime('12hr, 'ampm) + " " +
$time.ltime();
rtime = "Terran Time: " + ctime();
itime = (("Ilraitheen Time: " + ($dark_time.ilraitheen_time())) + " day ") + tostr($dark_time.day());
ptime = "Paradisical Time: " + ($dark_time.paradise_time());
.tell([rtime, itime, ptime]);
.
method audit_cmd
arg com, [args];
var owner, obj, col, total, line, syntax, loc, size;
if (sender() != this())
throw(~perm, "Sender not this.");
syntax = "";
owner = (args[1]) ? args[1] | "me";
owner = .match_env_nice(owner, syntax);
if (!(owner.owned())) {
.tell(" None");
} else {
col = (.linelen()) / 2;
line = ("Objects owned by " + (owner.namef('ref))) + ":";
.tell((pad(line, col) + pad("bytes", -10)) + " Location");
for obj in (owner.owned()) {
if (!valid(obj)) {
.tell((" ** invalid object (" + toliteral(obj)) + ") **");
continue;
}
line = pad(" " + (obj.namef('xref)), col);
size = $integer.to_english(obj.size());
line = (line + pad(size, -((strlen(size) > 10) ? strlen(size) | 10))) + " ";
loc = (obj.has_ancestor($located)) ? ("[" + ((obj.location()).name())) + "]" | "";
.tell(pad(line + loc, .linelen()));
total = total + (obj.size());
}
}
.tell(("Total usage: " + ($integer.to_english(total))) + " bytes");
size = owner.get_quota();
line = ("Total quota: " + ($integer.to_english(size))) + " bytes ";
line = ((line + "Remaining: ") + ($integer.to_english(size - total))) + " bytes";
.tell(line);
.
method login_notify
// called by .login, set items here that will 'notify' a user of various
// different things, such as new mail, news, etc.
if ($news.new())
.tell("There is new News (use `@news` to read it).");
if ((.last_received_on()) > ((.subscribed())[this()]))
.tell("You have new mail (use `@help mail` to learn about mail).");
.subscribed_cmd("");
.
method _set_watch_logins
arg value;
if (sender() != this())
throw(~perm, "Invalid call to private method");
watch_logins = value;
.
method get_mode
arg mode;
// returns the variable for the mode
if (mode in dict_keys(modes))
return modes[mode];
throw(~modenf, ("Mode \"'" + tostr(mode)) + "\" is not found in the users dictionary");
.
method add_mode
arg mode, setting;
if (!(.is_writable_by(sender())))
throw(~perm, "Sender is not an owner.");
if (type(mode) != 'symbol)
throw(~type, "Modes must be a symbol");
modes = dict_add(modes, mode, setting);
.
method news_cmd
arg [args];
(> .perms(sender(), 'parser) <);
$news.read_vrb("read", "news");
.
method del_mode
arg mode;
if (!(.is_writable_by(sender())))
throw(~perm, "Sender is not an owner.");
if (mode in dict_keys(modes)) {
modes = dict_del(modes, mode);
return;
}
throw(~modenf, "Mode is not in users modes dictionary");
.
method add_command_alias_cmd
arg com, input;
var syn, alias, actual, tmpalias, tmpactual, num;
if (sender() != this())
throw(~perm, "Sender is not this");
input = explode(input, "\"");
// hell, i'll be nice and check for a few possibilities:
syn = com + " \"<alias>\" [to] \"<actual command>\"";
if (listlen(input) < 2)
$parse.tell_error("Not enough arguments (enclose each alias in quotes)", syn);
if (listlen(input) > 3)
$parse.tell_error("Too many arguments (enclose each alias in quotes)", syn);
// sort and get the alias and actual
if (listlen(input) == 3)
input = delete(input, 2);
alias = input[1];
actual = input[2];
// make sure the %foo's match up
tmpalias = alias;
tmpactual = actual;
while ("%" in tmpalias) {
num = tmpalias[("%" in tmpalias) + 1];
if (!toint(num))
$parse.tell_error("referece cards must be integers", syn);
num = "%" + num;
if (!(num in tmpactual))
$parse.tell_error("reference cards to not match up", syn);
tmpalias = strsub(tmpalias, num, "");
tmpactual = strsub(tmpactual, num, "");
}
if ("%" in tmpactual)
$parse.tell_error("reference cards do not match up", syn);
.add_command_alias(alias, actual);
.tell(((("New command alias \"" + alias) + "\" => \"") + actual) + "\" added.");
.
method del_command_alias_cmd
arg com, template;
if (sender() != this())
throw(~perm, "Sender is not this");
template = explode(template, "\"")[1];
catch ~aliasnf {
.del_command_alias(template);
} with handler {
$parse.tell_error(("No command alias is found matching the template \"" + template) + "\".");
}
.tell(("Command alias \"" + template) + "\" deleted.");
.
method command_aliases_cmd
arg com, what;
var aliases, a, line;
if (!what)
what = this();
else
what = .match_env_nice(what);
if ((what != this()) && (!(what.is_writable_by(this()))))
$parse.tell_error("You are not allowed to read the command aliases on " + (what.namef()));
.tell(("--- Command aliases on " + (what.namef('xref))) + ":");
aliases = what.command_aliases();
if (aliases) {
for a in (aliases) {
line = " " + pad(("\"" + (a[1])) + "\"", ((.linelen()) - 10) / 2);
.tell(((line + " => \"") + (a[2])) + "\"");
}
} else {
.tell(" <none>");
}
.tell("---");
.
method _tell
arg what;
var conn, line;
if (type(what) == 'list) {
for line in (what)
._tell(line);
} else {
for conn in (connections)
conn.send(what);
}
.
method add_filter
arg filter, [position];
if ((!(sender().has_ancestor($filters))) && (!(.is_writable_by(sender()))))
throw(~perms, "%O does not have permission to remove filters.", sender());
// do this in three steps, first make sure the posistion is valid,
// then check for it already, then figure its insert position.
position = [@position, 'first][1];
if (!(position in ['last, 'first]))
throw(~type, "Posistion types must be one of: 'last, 'first.");
// does it exist? If so remove it.
if (filter in filters)
filters = setremove(filters, filter);
// figure position
if (position == 'last)
position = listlen(filters) + 1;
else if (position == 'first)
position = 1;
filters = insert(filters, position, filter);
.
method del_filter
arg filter;
if ((!(sender().has_ancestor($filters))) && (!(.is_writable_by(sender()))))
throw(~perms, "%O does not have permission to remove filters.", sender());
if (filters) {
filters = setremove(filters, filter);
return;
} else {
throw(~nofilters, "You do not have any tell filters.");
}
.
method wrap_cmd
arg com, how;
var filters;
.perms(sender(), 'this);
if (!(how in ["on", "off"]))
return .tell("! You can either turn line wrapping `on' or `off'");
filters = .filters();
if (how == "on") {
if (filters && ($wrap_filter in filters))
return .tell("! You already have line wrapping on..");
.add_filter($wrap_filter);
return .tell("Line wrapping turned on.");
} else {
if (filters && (!($wrap_filter in filters)))
return .tell("! You dont have line wrapping turned on.");
.del_filter($wrap_filter);
return .tell("Line wrapping turned off.");
}
.
method filters
.perms(sender());
return filters;
.
method tell_traceback
arg traceback, [args];
var tt, name, eargs, error, str;
// tt = tell_traceback || ['verbose, 0, "! "];
str = [@args, ""][1];
eargs = [@args, 0, 0][2];
error = [@args, 0, 0, 0][3];
tt = ['verbose, -1, "! "];
switch (tt[1]) {
case 'verbose:
traceback = $parse.traceback(traceback, tt[2], tt[3], error);
if (args)
name = (| $list.to_english($list.map(args, 'namef, 'ref)) |);
if (!name)
name = "Object";
.tell(strsub(traceback[1], "%O", name));
.tell(sublist(traceback, 2));
default:
.tell(("! Internal error processing \"" + str) + "\", contact an administrator.");
}
.
method set_tell_traceback
arg which, [lines];
.perms(sender(), 'manager);
if (!(which in ['verbose, 'brief, 'none]))
throw(~type, "Which style must either be 'verbose, 'brief, or 'none.");
if (lines && (type(lines[1]) != 'integer))
throw(~type, "You must specify the max lines as an integer.");
if (!lines)
lines = 0;
else
lines = lines[1];
tell_traceback = [which, lines];
.
method namef
arg [args];
if (!args)
args = [['name]];
// first check for shortcuts, if so re-call this method correctly.
if ((args[1]) == 'nactivity) {
if (.activity())
args = [['name], " (", ['activity], ")"] + sublist(args, 2);
else
args = [['name]] + sublist(args, 2);
}
if ((args[1]) == 'titled) {
if (.title())
args = [['name], ", ", ['title]] + sublist(args, 2);
else
args = [['name]] + sublist(args, 2);
}
return pass(@args);
.
method get_prompt
return prompt;
.
method set_prompt
arg what;
.perms(sender(), 'this);
prompt = what;
.
method prompt_cmd
arg com, [args];
.perms(sender(), 'this);
if (!args)
args = [""];
.set_prompt(args[1]);
.tell(("Prompt set as \"" + (args[1])) + "\"");
.
method password_cmd
arg com, [args];
var syn;
(> .perms(sender(), 'this) <);
syn = com + " <old password> <new password>";
args = explode(@args);
if ((listlen(args) < 2) || (listlen(args) > 2))
$parse.tell_error("Not enough arguments specified (note: passwords cannot contain spaces).", syn);
if (!(.check_password(args[1])))
$parse.tell_error("Sorry.", syn);
catch any {
.set_password(args[2]);
} with handler {
$parse.tell_error((traceback()[1])[2], syn);
}
.tell("Password changed.");
.
method set_title
arg str;
.perms(sender(), 'manager);
if (strlen(str) > 30)
throw(~type, "Titles must be under 30 characters.");
title = str;
.
method watch_logins_cmd
arg com, args;
args = explode(args);
if (!args)
return .tell("You must specify someone to watch (logging in/out).");
if ((args[1]) in ["all", "everybody", "everyone"]) {
.set_watch_logins(1);
.tell("You are now listening to login messages from everybody.");
} else if ((args[1]) in ["none", "noone"]) {
.set_watch_logins(0);
.tell("You are now ignoring login messages.");
} else {
.tell("nothing else on this command is progged yet.");
}
.
method delimited_tell
arg text;
var conn;
// will adjust perms etc later.
for conn in (.connections())
conn.enh_tell([text]);
.
method match_context
arg str;
return context[str];
.
method context
return context;
.
method match_environment
arg str;
var match, gend;
match = (> pass(str) <);
gend = (| match.gender() |);
if (gend)
context = dict_add(context, gend.pronoun('po), match);
return match;
.
method non_terminated_tell
arg text;
var conn;
if (.setting("terminated-tell")) {
for conn in (.connections())
conn.enh_tell([text]);
} else {
.tell(text);
}
.
method set_name
arg new_name, [ignore];
var old_name, part, sname;
(> .perms(sender(), 'manager) <);
// so it doesnt bomb on .set_dbref
if ((.name()) == new_name)
return;
if ($user_db.valid_name(new_name))
old_name = .name();
sname = $string.strip(new_name, $user_db.stripped_characters());
catch any {
pass(new_name);
$user_db.key_changed(old_name, new_name);
.set_dbref(tosym("user_" + sname));
} with handler {
(| pass(old_name) |);
rethrow(error());
}
.
method find_object_nice
arg str, [args];
var match;
catch any {
match = .find_object(str, @args);
} with handler {
.tell("! " + ((traceback()[1])[2]));
throw(~stop, "", 'no_traceback);
}
return match;
.
method find_object
arg str, [args];
var trace, match;
// comprehensive matching method.
// args define what to match.
if (!args)
args = ['environment];
while (args) {
switch (args[1]) {
case 'environment:
match = (| .match_environment(str) |);
case 'user:
match = (| $user_db.find(str) |);
case 'grasp:
match = (| $object.to_dbref(str) |);
}
if (match)
return match;
args = delete(args, 1);
}
throw(~objnf, ("No object found by the reference \"" + str) + "\".");
.
method creation_time
return creation_time;
.
method age_cmd
arg com, user;
var person, time;
.perms(sender(), 'parser);
person = (| $user_db.find(user) |);
if (!person) {
person = (| .match_environment(user) |);
if (!person)
return .tell(("No person can be found by the name \"" + user) + "\".");
}
time = person.creation_time();
.tell(((person.namef()) + " was created on ") + ($time.ldate(time)));
.tell(((((person.gender()).pronoun('psc)) + " is ") + ($time.elapsed(time() - time, 'long))) + " old.");
.
method spawn_cmd
arg com, args;
var syn, new_obj, moved, name, parent, builder;
(> .perms(sender(), 'this) <);
syn = com + " <parent> [named|called] <new object name>";
args = explode(args);
builder = $builder in (.ancestors());
if ("named" in args)
args = setremove(args, "named");
if ("called" in args)
args = setremove(args, "named");
if (!args)
$parse.tell_error("No arguments specified.", syn);
else if ((listlen(args) == 1) && (!builder))
$parse.tell_error("You must specify both the parent object and the name of the new object.", syn);
parent = args[1];
parent = .match_env_nice(parent, syn);
// users shouldn't be creating non VR objs.
if ((!(parent.has_ancestor($thing))) && (!builder)) {
.tell(("Only programmers are allowed to spawn non VR objects (anything which isn't descended from " + ($thing.namef('ref))) + ").");
return;
}
name = sublist(args, 2).to_string();
catch any {
new_obj = parent.spawn();
if (name) {
if (!(new_obj.has_ancestor($named)))
.tell("Object is not descended from $named.");
else
(> new_obj.set_name(name) <);
}
moved = (| new_obj.move_to(this()) |);
.tell(((("Object " + (new_obj.namef('ref))) + " spawned from ") + (parent.namef('ref))) + ".");
} with handler {
$parse.tell_error((traceback()[1])[2], syn);
}
.
method _prose_done
arg text, obj, which;
.perms(sender(), 'this);
(> obj.set_prose(which, text) <);
which = tostr(which);
.tell(((($string.capitalize(which)) + " prose description for ") + (obj.namef('ref))) + " set.");
.
method prose_cmd
arg cmd, args;
var syn, which, obj, prose, long;
(> .perms(sender()) <);
syn = cmd + " [-long|-short] <object>";
args = $parse.options(args);
obj = (args[1]).to_string();
if (args[2]) {
// We'll only take the first flag, too bad.
args = dict_keys(args[2])[1];
long = match_template("l?ong", args);
}
if (long)
which = 'long;
else
which = 'short;
if (!obj)
$parse.tell_error("No object specified.", syn);
obj = .match_env_nice(obj);
if (!(obj.has_ancestor($described)))
$parse.tell_error((obj.namef('ref)) + " is not a describeable object!", syn);
if (!(| obj.perms(this()) |))
$parse.tell_error(("You do not have permission to write the prose description for " + (obj.namef('ref))) + ".", syn);
if (which == 'short)
prose = [.prompt("Enter line for short prose: ")];
else
prose = .read("Enter text for long prose (end with a period or abort with `@abort`):");
if (prose == 'aborted)
return;
if ((prose[1]) == "@abort")
return .tell("Aborted.");
(> obj.set_prose(which, prose) <);
which = tostr(which);
.tell(((($string.capitalize(which)) + " prose description for ") + (obj.namef('ref))) + " set.");
.
method status_cmd
arg com, [args];
var line, s;
(> .perms(sender(), 'this) <);
.tell(((("Name: " + ($motd.server_name())) + ", ") + ($motd.server_title())) + ".");
.tell("Startup time: " + ($time.date($sys.server_info('startup_time))));
.tell((" (" + ($time.to_english(time() - ($sys.server_info('startup_time))))) + " ago)");
.tell("Last backup time: " + ($time.date($sys.server_info('last_backup))));
.tell((" (" + ($time.to_english(time() - ($sys.server_info('last_backup))))) + " ago)");
.tell("Driver: " + ($sys.server_info('driver_version, 'long)));
.tell("Core: " + ($sys.server_info('core_version, 'long)));
s = $sys.status();
.tell(((("Driver execution time: " + ($time.to_english(s[1]))) + " seconds (") + tostr(s[2])) + " microsecs)");
.tell(((("System execution time: " + ($time.to_english(s[3]))) + " seconds (") + tostr(s[4])) + " microsecs)");
.tell(("Max resident set size utilized: " + tostr(s[5])) + " bytes");
.tell("Integral shared text size: " + tostr(s[6]));
.tell("Integral shared memory size: " + tostr(s[7]));
.tell("Integral unshared data size: " + tostr(s[8]));
.tell("Integral unshared stack size: " + tostr(s[9]));
.tell("Page reclaims: " + tostr(s[10]));
.tell("Page Faults: " + tostr(s[11]));
.tell("Number of times swapped: " + tostr(s[12]));
.tell("Block input operations: " + tostr(s[13]));
.tell("Block output operations: " + tostr(s[14]));
.tell("IPC messages sent: " + tostr(s[15]));
.tell("IPC messages received: " + tostr(s[16]));
.tell("Signals delivered: " + tostr(s[17]));
.tell("Voluntary context switches: " + tostr(s[18]));
.tell("In-voluntary context switches: " + tostr(s[19]));
.
method del_command_alias
arg alias;
(> .perms(sender()) <);
(> pass(alias) <);
if ((!(.command_aliases())) && ($command_aliases_parser in (.parsers()))) {
.tell("Removing $command_aliases_parser from your list of parsers.");
.del_parser($command_aliases_parser);
}
.
method add_command_alias
arg alias, actual;
(> .perms(sender()) <);
(> pass(alias, actual) <);
if ((.command_aliases()) && (!($command_aliases_parser in (.parsers())))) {
.tell("Adding $command_aliases_parser to your list of parsers..");
.add_parser($command_aliases_parser, 'first);
}
.
method logout_connection
arg connection;
if ((sender() != this()) || (definer() != caller()))
throw(~perm, "Invalid access to private method.");
.tell($string.center(("* * * " + ($integer.n_to_nth(listlen(.connections()) + 1))) + " Logout sucessful * * *", .linelen()));
.
method tell_ctext
arg ctext, originator;
var output, type;
type = (.setting("content-type")) || "text/plain";
output = ctext.translate_to(type);
.tell(output);
.
method rehash_cmd
arg cmd;
.tell("Rehashing commands in your environment...");
.rehash_command_environment();
.
method description
arg actor, [exclude];
var out, obj, contents, line;
out = (> pass(actor, @exclude) <);
contents = .contents();
line = ((.gender()).pronoun('psc)) + " is ";
out = [@out, (line + ((.activity()) || "awake")) + "."];
if (!contents) {
out = [@out, ((.gender()).pronoun('psc)) + " is holding nothing."];
} else {
out = [@out, ((.gender()).pronoun('psc)) + " is holding:"];
for obj in (contents)
out = [@out, " " + (obj.namef())];
}
return out;
.
method _who_at_place
arg str;
var place, thing, who, args;
(> .perms(sender(), 'this) <);
// This should actually be done with a global place dictionary and
// a local place dictionary for each user.
place = $place.match_descendants(str);
if (!place) {
.tell(("I do not know where \"" + str) + "\" is.");
return 0;
}
who = [];
for thing in (place.contents()) {
if (thing.has_ancestor($user))
who = [@who, thing];
}
if (!who) {
.tell(("Nobody is in " + (place.namef())) + ".");
return 0;
}
args = [who, "Users in " + (place.namef())];
args = [@args, [['namef, 'titled], ['time_poll]]];
args = [@args, ["Name", "Times (idle)"], [1, 1]];
return args;
.
method _who_is
arg [args];
var person, p, who;
(> .perms(sender(), 'this) <);
who = [];
args = ($string.explode_english_list(@args)) || [];
for p in (args) {
catch any {
person = $user_db.find(p);
} with handler {
switch (error()) {
case ~ambig:
.tell(((("The name \"" + p) + "\" can match any of: ") + ($list.to_english($list.map((traceback()[1])[3], 'namef)))) + ".");
default:
.tell(("I don't know who \"" + p) + "\" is.");
}
continue;
}
who = [@who, person];
}
if (!who)
return 0;
return [who, (listlen(who) == 1) ? "User" | "Users"];
.
method _who_programmers
arg args, opts;
var out, progs, p, x, t, all;
(> .perms(sender(), 'this) <);
progs = [];
opts = dict_keys(opts);
all = "all" in opts;
if (args && (!all)) {
for p in (args) {
x = $user_db.find(p);
if (!x)
.tell(("I don't know who \"" + p) + "\" is.");
else
progs = [@progs, x];
}
t = (("Programmer" + listlen(progs)) == 1) ? "" | "s";
} else if (all) {
t = "All Programmers";
progs = $programmer.descendants();
progs = setremove(progs, $admin);
} else {
t = "Connected Programmers";
for p in ($user_db.connected()) {
if (p.has_ancestor($programmer))
progs = [@progs, p];
}
}
if (!progs)
return 0;
return [progs, t];
.
method _who_admins
arg args, opts;
var out, admins, a, x, t, all;
(> .perms(sender(), 'this) <);
admins = [];
opts = dict_keys(opts);
all = "all" in opts;
if (args && (!all)) {
for a in (args) {
x = $user_db.find(a);
if (!x)
.tell(("I don't know who \"" + a) + "\" is.");
else
admins = [@admins, x];
}
t = (("Admin" + listlen(admins)) == 1) ? "" | "s";
} else if (all) {
t = "All Admins";
admins = $sys.admins();
} else {
t = "Connected Admins";
for a in ($user_db.connected()) {
if (a.has_ancestor($admin))
admins = [@admins, a];
}
}
if (!admins)
return 0;
return [admins, t];
.
method _who_short
var user, tmp, who, namestr, total;
(> .perms(sender(), 'this) <);
who = [];
total = listlen($user_db.connected());
.tell((("Currently connected users (total: " + tostr(total)) + ((total == 1) ? " person" | " people")) + "):");
for user in ($user_db.connected()) {
namestr = (((((" " + (user.namef())) + " (") + ($time.elapsed(user.connected_at()))) + " ") + ($time.dhms(user.idle_seconds()))) + ")";
who = [@who, namestr];
if (tmp < (strlen(namestr) + 2))
tmp = strlen(namestr) + 2;
}
.tell($list.columnize(who, (.linelen()) / (tmp + 1), " ", .linelen()));
.
method remember_cmd
arg cmd, str;
if (str == "here") {
.remember_place(.location());
.tell(("Remembering " + ((.location()).name())) + ".");
} else {
// Eventually you may want to remember people for some reason,
// for now just say something vague and maybe they will think
// it did something -B
.tell("Ok.");
}
.
method remember_place
arg place;
(> .perms(sender(), 'this) <);
if (type(place) != 'dbref)
throw(~type, "Place must be submitted as an object.");
// because it is not initialized (and shoudn't be)
if (!remembered_places)
remembered_places = [];
if (place in remembered_places)
return;
remembered_places = [@remembered_places, place];
.
method forget_place
arg place;
(> .perms(sender(), 'this) <);
if (type(place) != 'dbref)
throw(~type, "Place must be submitted as an object.");
remembered_places = setremove(remembered_places, place);
.
method remembered_places
(> .perms(sender(), 'this) <);
return remembered_places || [];
.
method remembered_cmd
arg cmd, str;
var line;
(> .perms(sender(), 'this) <);
if (str != "places") {
.tell("You can only currently remember \"places\".");
return;
}
if (!(.remembered_places()))
return .tell("You do not remember any place.");
// now is a good a time as any...
.validate_remembered_places();
.tell("Remembered Places:");
for line in (((.remembered_places()).map('name)).lcolumnize((.linelen()) - 2))
.tell(" " + line);
.
method forget_cmd
arg cmd, str;
(> .perms(sender(), 'this) <);
if (str == "here") {
.forget_place(.location());
.tell(("Forgetting " + ((.location()).name())) + ".");
} else {
// Eventually you may want to remember people for some reason,
// for now just say something vague and maybe they will think
// it did something -B
.tell("Ok.");
}
.
method idle_time
arg [args];
var idle;
args = [@args, 'dhms][1];
idle = .idle_seconds();
if ((connected_at < 0) || (idle < 30))
return "";
switch (args) {
case 'dhms:
return $time.dhms(idle, 'long);
case 'elapsed:
return $time.elapsed(idle);
case 'seconds:
return idle;
}
.
method connected_time
arg [args];
args = [@args, 'dhms][1];
if (connected_at < 0)
return "Last on: " + ctime(abs(connected_at));
switch (args) {
case 'dhms:
return $time.dhms(time() - connected_at, 'long);
case 'elapsed:
return $time.elapsed(time() - connected_at);
case 'seconds:
return time() - connected_at;
}
.
method whereis_cmd
arg cmd, who;
var user, u;
who = (who && (who.explode_english_list())) || [];
if (who && ((who[1]) == "is"))
who = delete(who, 1);
if (!who)
$parse.tell_error("You must specify somebody.");
for user in [1 .. listlen(who)] {
u = (| $user_db.find(who[user]) |);
if (!u) {
.tell(("I don't know who \"" + (who[user])) + "\" is.");
who = replace(who, user, 0);
} else {
who = replace(who, user, u);
}
}
for user in (who) {
if (user)
.tell(((user.name()) + " is in ") + ((user.location()).name('def)));
}
.
method validate_remembered_places
var place;
(> .perms(sender(), 'this) <);
for place in (remembered_places) {
if (!valid(place))
remembered_places = setremove(remembered_places, place);
}
.
method terminated_tell
return (| (settings[$user])["terminated-tell"] |) || "text/plain";
.
method new_connection
arg addr, port;
var line;
(> .perms(caller(), $connection) <);
connections = connections + [sender()];
if (listlen(connections) == 1)
.login(sender());
else
.login_again(sender());
line = ("CONNECT " + tostr(sender() in connections)) + " (";
line = (line + (((.parents())[1]).dbref())) + ") : ";
line = (((line + (.dbref())) + " <") + (sender().address())) + "> ";
$sys.log(line);
.
method connection_going_away
arg addr, port;
var con, line;
(> .perms(caller(), $connection) <);
con = sender() in connections;
connections = setremove(connections, sender());
if (!connections)
.logout(sender());
else
.logout_connection(sender());
connections = setremove(connections, sender());
line = ("DISCONNECT " + tostr(sender() in connections)) + " (";
line = (line + (((.parents())[1]).dbref())) + ") : ";
line = (((line + (.dbref())) + " <") + (sender().address())) + "> ";
$sys.log(line);
.
method read
arg [args];
var text, output, head, tail;
if (!(.connections()))
return 'not_connected;
if (((.connections())[1]).is_reading())
return 'engaged;
head = [@args, "Now receiving input, enter \".\" to finish or \"@abort\" to abort."][1];
tail = [@args, "** Aborted **; Text thrown away.", "** Aborted **; Text thrown away."][2];
if (head)
.tell(head);
output = ((.connections())[1]).start_reading('multiple);
if ((output == 'aborted) && tail)
.tell(tail);
return output;
.
method read_line
arg [args];
var line, abort_msg, head;
if (!(.connections()))
return 'not_connected;
if (((.connections())[1]).is_reading())
return 'engaged;
head = [@args, ""][1];
abort_msg = [@args, "** Aborted **", "** Aborted **"][2];
if (head)
.tell(head);
line = ((.connections())[1]).start_reading('one);
if ((line == 'aborted) && abort_msg)
.tell(abort_msg);
return line[1];
.
method prompt
arg prompt, [abort_msg];
.non_terminated_tell(prompt);
return (> .read_line("", @abort_msg) <);
.
method short_description
arg actor, [exclude];
var out, obj, contents, line, p, wearing;
out = (> pass(actor, @exclude) <);
contents = .contents();
wearing = .wearing();
p = (.gender()).pronoun('psc);
line = p + " is ";
out = [@out, (line + ((.activity()) || "awake")) + "."];
if (!contents)
out = [@out, p + " is holding nothing."];
else
out = [@out, (p + " is holding ") + (contents.map_to_english('namef))];
if (!wearing)
out = [@out, p + " is wearing nothing!"];
else
out = [@out, (p + " is wearing ") + (wearing.map_to_english('name))];
return out;
.
method ways_cmd
arg cmd;
(> .perms(caller(), 'this) <);
.tell((.location()).visible_exits_formatted(this(), 'long));
.
method describe_cmd
arg cmd, str;
var args, syn, what, desc;
(> .perms(sender(), 'this) <);
syn = cmd + " <what> as <description>";
args = match_template("* as *", str);
if (!args)
$parse.tell_error("You may also use \"@prose\".", syn);
what = .match_env_nice(args[1]);
desc = args[3];
catch any {
what.set_prose('short, [desc]);
} with handler {
.tell((traceback()[1])[2]);
return;
}
.tell(("Short prose description for " + (what.namef('ref))) + " set.");
.
method gender_cmd
arg cmd, gender;
var genders;
(> .perms(sender(), 'this) <);
genders = [$gender_female, $gender_male, $gender_neuter, $gender_plural];
if (!gender) {
.tell(("Syntax: `" + cmd) + " <gender>`");
.tell("Available Genders: " + ((genders.map('name)).to_english()));
.tell(("You are currently a gender of " + ((.gender()).name())) + ".");
} else {
gender = gender in (genders.map('name));
if (!gender) {
.tell("Gender must be one of: " + (genders.to_english()));
} else {
.set_gender(genders[gender]);
.tell(("Gender set to " + ((.gender()).name())) + ".");
.tell(("Pronouns: " + (((((.gender()).pronouns()).values()).sublist(1, 5)).to_english())) + ".");
}
}
.
method content_type
return (| (settings_data[$user])["content-type"] |) || "text/plain";
.