parent $body parent $interaction parent $input parent $command_aliases parent $bad_commands parent $user_data parent $has_settings parent $settings_ui 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], ["@aliases *", 'aliases_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], ["@who-s?hort|@whos?hort", 'who_short_cmd], ["news", 'news_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], ["@who-a?dmins|@whoa?dmins *", 'who_admins_cmd], ["@add-command-a?lias|@aca?lias *", 'add_command_alias_cmd], ["@who-c?ount|@whoc?ount", 'who_count_cmd], ["@who-p?rogrammers|@whop?rogrammers *", 'who_progs_cmd], ["@login-watch *", 'watch_logins_cmd], ["@com?mands *", 'commands_cmd], ["@age *", 'age_cmd], ["@spawn|@create *", 'spawn_cmd], ["@prose|@describe *", 'prose_cmd], ["@status", 'status_cmd], ["@rehash?-commands", 'rehash_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 0 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 $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 $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 $has_settings setting_templates #[["terminated-tell", 'boolean], ["Content-type", 'string]] method init_user .perms(caller(), $root); password = "*"; connected_at = 0; last_command_at = 0; connections = []; creation_time = time(); parsers = [$command_parser, $verb_parser]; filters = []; action = ""; prompt = ""; context = #[]; .set_quota($sys.user_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($room)) // 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; .perms(caller(), $old_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: .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()); } return 0; . method connection_logged_in arg addr, port; var line; if (caller() != $old_connection) throw(~perm, "Caller is not $old_connection."); connections = connections + [sender()]; if (listlen(connections) == 1) .login(sender()); else .login_again(sender()); line = ("CONNECT " + tostr(sender() in connections)) + ": "; line = (((line + (.dbref())) + " <") + (sender().addr())) + "> "; $sys.log(line); . method connection_logged_out arg addr, port; var con, line; if (caller() != $old_connection) throw(~perm, "Caller is not $old_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 + (.dbref())) + " <") + (sender().addr())) + "> "; $sys.log(line); . method login arg connection; var loc; if ((sender() != this()) || (definer() != caller())) throw(~perm, "Invalid access to private method."); .tell(("* * * Login successful (" + (connection.addr())) + ") * * *"); 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(((("* * * " + ($integer.n_to_nth(connection in (.connections())))) + " Login successful (") + (connection.addr())) + ") * * *"); . method logout arg connection; if ((sender() != this()) || (definer() != caller())) throw(~perm, "Invalid access to private method."); (| (.location()).did_disconnect() |); // 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, [args]; var who, x, person, where, meths, header; // just the basic who listing .perms(sender(), 'parser); who = []; if (!(args[1])) { who = $user_db.connected(); // looks like they want who in a room. } else if (((args[1])[1]) == "@") { where = $room.match_descendants(substr(args[1], 2)); if (!where) $parse.tell_error(("I do not know where \"" + substr(args[1], 2)) + "\" is."); for x in (where.contents()) { if (x.has_ancestor($user)) who = [@who, x]; } if (!who) $parse.tell_error(("Nobody is in " + (where.namef())) + "."); meths = [['namef, 'titled, " (", 'activity, ")"], ['time_poll]]; header = ["Name", "Times (idle)"]; .tell($code.generate_listing(who, "Users in " + (where.namef()), meths, header, [1, 1])); return; } else { // // user, or list of users for x in ($string.explode_english_list(@args)) { catch any { person = $user_db.find(x); } with handler { switch (error()) { case ~ambig: .tell(((("The name \"" + x) + "\" can match any of: ") + ($list.to_english($list.map((traceback()[1])[3], 'namef)))) + "."); default: .tell(("I don't know who \"" + x) + "\" is."); } continue; } who = [@who, person]; } if (!who) return; } .tell($code.generate_listing(who)); . 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 who_short_cmd arg com; var user, tmp, who, namestr, total; if (sender() != this()) throw(~perm, "Sender not this."); who = []; total = listlen($user_db.connected()); .tell((("Currently connected users (total of " + 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 who_admins_cmd arg com, [who]; var admins, admin, title; who = who[1]; // everybody, connected or not if (who == "all") { admins = $sys.admins(); title = "All Admins"; // ok, just the connected ones then } else if (who == "") { title = "All Connected Admins"; admins = []; for admin in ($sys.admins()) { if (admin.connected()) admins = [@admins, admin]; } // hrm, possibly somebody specific } else { admins = [.match_object_nice(who, $admin, 'children)]; } .tell($code.generate_listing(admins, title)); . method who_progs_cmd arg com, [args]; var progs, all_progs, x, title; args = args[1]; if (args) { if (match_begin(args, "all")) { progs = $programmer.descendants(); title = "All Programmers"; } else { title = "Programmer"; progs = [.find_object_nice(args, 'environment, 'user, 'grasp)]; } } else { progs = []; title = "Connected Programmers"; for x in ($programmer.descendants()) { if (x.connected()) progs = [@progs, x]; } } .tell($code.generate_listing(progs, title)); . method who_count_cmd arg com; var len, rz, pz; .perms(sender(), 'parser); len = listlen($user_db.connected()); if (len == 1) { rz = "is"; pz = "person"; } else { rz = "are"; pz = "people"; } .tell(((((("There " + rz) + " currently ") + tostr(len)) + " ") + pz) + " connected."); .tell("Lag is <lag meter will eventually go here>"); . 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 time_poll arg [args]; var idle; if (!(.connected())) return "Last On: " + substr(ctime(last_command_at), 1, 10); if (!args) idle = ((.idle_seconds()) > 10) ? $time.dhms(.idle_seconds(), 'long) | ""; else idle = ((.idle_seconds()) > 10) ? $time.dhms(.idle_seconds()) | ""; return ($time.elapsed(.connected_at())) + (idle ? " " + idle | ""); . 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 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 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>'"; 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]) == "-prop") || (((line[x]) == "-p") || ((line[x]) == "-proper"))) { article = 'prop; line = delete(line, x); break; } if (((line[x]) == "-uniq") || (((line[x]) == "-u") || ((line[x]) == "-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('ref)), col); size = $integer.to_english(obj.size()); line = (line + pad(size, -((strlen(size) > 10) ? strlen(size) | 10))) + " "; loc = (obj.has_ancestor($located)) ? ("[" + ((obj.location()).namef())) + "]" | ""; .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 varous // different things, such as new mail, news, etc. if ($news.new()) .tell("There is new News (use `news' to read it)."); if (.unread()) .tell("You have new mail (use `@Mm?ail on me' to list it)."); .mmail_lists_cmd("", "subscribed"); . 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; .perms(sender(), 'this); if (type(what) == 'list) { for line in (what) ._tell(line); } else { for conn in (connections) conn.tell(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(), 'parser); 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("Old password does not match up.", 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 ((.namef()) == new_name) return; if ($user_db.valid_name(new_name)) old_name = .namef(); 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; if (sender() != this()) throw(~perm, "Sender not this."); syn = ("`" + com) + " <parent> [named|called] <new object name>'"; args = explode(args); builder = !($user in (.parents())); if ((!args) || (((listlen(args) < 1) && builder) || (listlen(args) < 2))) $parse.tell_error("Not enough arguments specified.", syn); args = [@args, ""]; parent = args[1]; parent = .match_env_nice(parent, syn); // users shouldn't be creating non VR objs. if ((!(parent.has_ancestor($thing))) && (!builder)) $parse.tell_error("Parent is not a descendant of a Generic Thing ($thing)."); if (match_begin("named", args[2]) || match_begin("called", args[2])) args = delete(args, 2); name = $list.to_string(sublist(args, 2)); 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; .perms(sender()); syn = ("`" + cmd) + " <object> [long|short]`"; args = explode(args); obj = [@args, ""][1]; which = [@args, "short", "short"][2]; if (!(which in ["short", "long"])) $parse.tell_error("Must either be \"short\" or \"long\" for the prose type.", syn); which = tosym(which); 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) { .prompt("Enter line: ", '_prose_done, obj, which); } else { .tell("Enter text for prose (end with a period or abort with `@abort`):"); .read('_prose_done, obj, which); } . method status_cmd arg com, [args]; var line; (> .perms(sender(), 'this) <); .tell(((($motd.server_name()) + ", ") + ($motd.server_title())) + "."); .tell("Startup time: " + ($time.date($sys.startup_time()))); .tell((" (" + ($time.to_english($sys.uptime()))) + ")"); .tell("Last backup time: " + ($time.date($sys.last_backup()))); .tell("Driver: ColdMUD " + ($sys.version('driver))); .tell("Core: the Cold Dark Core " + ($sys.version('core))); . 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(("* * * " + ($integer.n_to_nth(listlen(.connections()) + 1))) + " Logout sucessful * * *"); . 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(); .