new obj Inserting httpd_ui.cdc... new object $httpd_ui: $user_interfaces; var $root manager = $httpd_ui; var $command_cache modules = []; var $root flags = ['variables, 'methods, 'code, 'core, 'general_cache]; var $root created_on = 887523264; var $dmi_data descriptions = #[]; var $has_commands shortcuts = #[]; var $has_commands remote = #[]; var $has_commands local = #[["@list-entries", [["@list-entries", "on *", "@list-entries on <descendant of $directories>", 'list_entries_cmd, #[[2, ['descendant, [$directories]]]]]]], ["@add-entry", [["@add-entry", "* to *", "@add-entry <any:+t?arget> to <descendant of $directories>", 'add_entry_cmd, #[[1, ['any_opt, ["t?arget"]]], [3, ['descendant, [$directories]]]]]]], ["@del-entry", [["@del-entry", "* from *", "@del-entry <any> from <descendant of $directories>", 'del_entry_cmd, #[[1, ['any, []]], [3, ['descendant, [$directories]]]]]]]]; var $root inited = 1; var $root managed = [$httpd_ui]; var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"]; public method .list_entries_cmd() { arg cmd, cmdstr, prep, directory; var output, x; output = map x in (directory.entries()) to ($cml_lib.format_tr_tag($cml_lib.format_td_tag(x[1]), $cml_lib.format_td_tag(x[2]))); return $ctext_frob.new_with([("Directory entries for " + directory) + ":", $cml_lib.format_table_tag("25%,75%", @output), $cml_lib.format_sep_tag()]); }; public method .add_entry_cmd() { arg cmd, cmdstr, @args; var name, opt, prep, directory, target; [[[name], [opt]], prep, directory] = args; if ((opt.length()) != 4) return "You must specify the target object via +target."; target = opt[4]; if (!(target = (| $object_lib.to_dbref(target) |))) return "The target must be a valid object."; if (!(target.is($page))) return "The target must be a descendant of $page."; directory.add_entry(name, target); return; }; public method .del_entry_cmd() { arg cmd, cmdstr, @args; var name, prep, directory; [name, prep, directory] = args; catch ~keynf { directory.del_entry(name); sender().tell(((("Entry, '" + name) + "', removed from ") + directory) + "."); } with { sender().tell(((("Entry, '" + name) + "', was not an entry on ") + directory) + "."); } return; }; new obj Inserting help_obj_float.cdc... new object $help_obj_float: $help_obj; var $root manager = $help_obj_float; var $help_node index = $help_index_objects; var $root flags = ['variables, 'methods, 'code, 'core]; var $root created_on = 910069163; var $dmi_data descriptions = #[]; var $has_name name = ['prop, "Float", "Float"]; var $help_node links = #[]; var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["float.ceiling", 1]], ["ceiling"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method calculates the ceiling of the floating point value. The ceiling is the next largest integer, so the ceiling of 5.4 is 6.0."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.floor", 1]], ["floor"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method calculates the floor of the floating point value ", <$format, ["var", [], ["float"], 'do_var]>, ". The floor is the next smallest integer, so the floor of 5.4 is 5.0."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.round", 1]], ["round"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the rounded off value of ", <$format, ["var", [], ["float"], 'do_var]>, " to the nearest integral value."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.round_to", 1]], ["round_to"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ", ", <$format, ["var", [], ["places"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method rounds the value ", <$format, ["var", [], ["float"], 'do_var]>, " off to the given number of places as specified by the argument ", <$format, ["var", [], ["places"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.fractional_part", 1]], ["fractional_part"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the fractional part of a floating point value. The result for 1.234 would be 0.234. The value will always be positive."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.to_integer", 1]], ["to_integer"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the integral value of a floating point number."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.log", 1]], ["log"], 'do_method]>, "(", <$format, ["var", [], ["base"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a base, ", <$format, ["var", [], ["base"], 'do_var]>, ", and a value, ", <$format, ["var", [], ["value"], 'do_var]>, ", this method returns the log of the value in the given base."], 'do_dd]>], 'do_dl]>], #[]]>; var $root inited = 1; var $root managed = [$help_obj_float]; new obj Inserting float.cdc... new object $float: $libraries; var $root manager = $float; var $float powers_of_ten = [10.0, 100.0, 1000.0, 10000.0, 100000.0, 1e+06]; var $root flags = ['variables, 'methods, 'code, 'core]; var $root created_on = 909982362; var $dmi_data descriptions = #[]; var $root inited = 1; var $root help_node = $help_obj_float; var $root managed = [$float]; public method .floor() { arg float; return tofloat(toint(float)); }; public method .ceiling() { arg float; return tofloat(toint(float) + 1); }; public method .round() { arg float; return round(float); }; public method .round_to() { arg float, places; var place_value; if ((places < 1) || (places > 6)) throw(~range, "Second argument must between 1 and 6."); place_value = powers_of_ten[places]; return round(float * place_value) / place_value; }; public method .to_integer() { arg float; return toint(float); }; public method .log() { arg base, value; return log(value) / log(base); }; public method .fractional_part() { arg float; return abs(float - toint(float)); }; new obj Inserting systrust_group.cdc... new object $systrust_group: $core_group; var $root manager = $systrust_group; var $root flags = ['variables, 'methods, 'code, 'core]; var $root created_on = 913800511; var $group group = #[[$scheduler, 1], [$directories, 1]]; var $root inited = 1; var $root managed = [$systrust_group]; maintenance public method $root.__upgrade_handle_var() { arg handle, vref, old, current, new; if (current != old) { // if (handle == 1) { if (type(old) != type(current)) { dblog("ERROR: datatype inconsistency for " + vref + " " + type(old) + " != " + type(current)); } switch (type(current)) { case 'dictionary: return dict_union(new, current); case 'list: return union(new, current); default: return new; } // } } return new; }; update objvar Updating objvar $root<$root>,managed object $root; var $root managed = []; old method Deleting normal method $root.new_descendants() object $root; eval { del_method('new_descendants); }; method flags Changing method $root.list_method() flags from to nooverride object $root; eval { var l; dblog("set_method_flags('list_method, 'public"); catch any { set_method_flags('list_method, ['nooverride ]); } with { for l in ($parse_lib.traceback(traceback())) dblog(l); } }; new method Replacing public method $root.trusts(): nooverride public method $root.trusts(): nooverride { arg obj; var o; for o in (.trusted()) { if (o.has_ancestor($group)) { if (o.includes(obj)) return 1; } else if (o == obj) { return 1; } } return ($systrust_group.includes(obj)) || ($sys.is_system(obj)); }; new method Replacing public method $root.del_var(): nooverride public method $root.del_var(): nooverride { arg name; var n, obj, errs; (caller() == definer()) || (> .perms(sender()) <); (> $sys.touch() <); // try and clear the variable on all of the descendants, before // deleting the variable...since we are root, dont use the standard // hooks as perms may not be right n = tosym("_dclear_var_" + tostr(time())); catch any { add_method([("clear_var('" + name) + ");"], n); for obj in (.descendants()) { (| obj.(n)() |); pause(); } } (| del_method(n) |); // now delete the variable (> del_var(name) <); if ('core in (.flags())) $changelog.log((((("DEL-VAR: " + this()) + ",") + name) + " by ") + sender()); }; new method Replacing public method $root.ancestry(): nooverride public method $root.ancestry(): nooverride { arg gen; var i, out; out = []; if (type(gen) == 'objnum) { for i in (.ancestors()) { if (i.has_ancestor(gen)) out += [i]; } return out; } if (gen != 0) { for i in (.parents()) out = union(out, i.ancestry(gen - 1)); } return out; }; new method Replacing public method $root.initialize(): nooverride public method $root.initialize(): nooverride { var ancestors, pos, len, method, a, def, str, tb; // called by $sys.create() to create a new object. if ((caller() != $sys) && (sender() != this())) throw(~perm, "Caller is not $sys and sender is not this."); if (inited) throw(~perm, "Already initialized."); ancestors = ancestors().reverse(); for a in (ancestors) { refresh(); if (!(method = (| tosym("init_" + tostr(a.objname())) |))) continue; if ((def = (| find_method(method) |))) { if (def != a) { (| (def.manager()).tell(((("Initialization method for " + a) + " in wrong place (") + find_method(method)) + ")") |); } else { catch any { .(method)(); } with { // try and let somebody know they made a boo-boo somewhere str = ((("UNINIT ERROR " + this()) + "<") + def) + ">:"; tb = traceback().fmt_tb(); if (def) { (| (def.manager()).tell(str) |); (| (def.manager()).tell(tb) |); } if ((.manager()) != sender()) { (| sender().tell(str) |); (| sender().tell(tb) |); } (| sender().tell("Continuing init..") |); (| $sys.log_traceback(tb, "** " + str) |); } } } } inited = 1; }; new method Adding root method $root.pass_test() root method $root.pass_test() { return "YYYYYYY"; }; new method Replacing public method $root.debug() public method $root.debug() { arg @stuff; var x, line, mngr, meth, stack, out, ref; stack = stack(); meth = (| (((stack[2])[3]) + "() line ") + ((stack[2])[4]) |); // dont even bother mngr = .manager(); if (!(| mngr.find_method('tell) |)) return; if (sender() != caller()) ref = ((sender() + "<") + caller()) + ">"; else ref = sender(); if (meth) line = ((("DEBUG " + ref) + ".") + meth) + ":"; else line = ("DEBUG " + ref) + ":"; mngr.tell(line); for x in (stuff) { refresh(); mngr.tell(($data_lib.unparse_indent(x)).prefix("DEBUG ")); } }; new method Replacing public method $root.is_writable_by(): nooverride public method $root.is_writable_by(): nooverride { arg obj; var o; for o in (.writers()) { if (o.has_ancestor($group)) { if (o.includes(obj)) return 1; } else if (o == obj) { return 1; } } return $sys.is_system(obj); // return (| obj in .writers() |) || $sys.is_system(obj); }; new method Replacing public method $root.generations(): nooverride public method $root.generations(): nooverride { arg gen; var p, out; out = [this()]; if (gen != 0) { for p in (.parents()) out = union(out, p.generations(gen - 1)); } return out; }; new method Replacing root method $root.change_parents(): nooverride root method $root.change_parents(): nooverride { arg parents; var old_a, old_p, a, obj, new_a, definer, branch, method, str; if (!parents) throw(~noparents, "Objects must have at least 1 parent"); // remember a few things old_a = setremove(ancestors(), this()); old_p = .parents(); branch = (.descendants()) + [this()]; // build the new ancestors list by hand, so we can figure out what is // changing, and uninitialize those ancestors that are going away new_a = []; for obj in (parents) new_a = union(new_a, obj.ancestors()); // uninit any ancestors going away for a in (old_a.set_difference(new_a)) { // call this ancestor's uninit on the obj and all its children method = tosym("uninit_" + (a.objname())); if ((definer = (| find_method(method) |))) { if (definer != a) { // scream madly and run around--everybody should know this str = "UNINIT ERROR: uninit method for " + a; str += (" in wrong place (" + definer) + ")"; (| (definer.manager()).tell(str) |); (| (a.manager()).tell(str) |); (| sender().tell(str) |); continue; } // call the uninit method on this object only catch any { .(method)(); } with { // try and let somebody know they made a boo-boo somewhere str = ((("UNINIT ERROR " + obj) + "<") + this()) + ">:"; (| (.manager()).tell(str) |); (| (.manager()).tell_traceback(traceback()) |); (| sender().tell(str) |); (| sender().tell_traceback(traceback()) |); (| sender().tell("Continuing chparent..") |); } } // cleanup any old obj vars left lying around // if (branch) // $sys.clear_definer_vars(a, branch); $sys.clear_definer_vars(a, [this()]); refresh(); } // make the change (> chparents(parents) <); if ('core in (.flags())) $changelog.log(((((("CHANGE-PARENTS: " + this()) + " from ") + old_p) + " to ") + parents()) + " by "); new_a = setremove(ancestors(), this()); // init anybody new to the family for a in (new_a.set_difference(old_a)) { method = tosym("init_" + (a.objname())); if ((definer = (| find_method(method) |))) { if (definer != a) { // scream madly and run around--everybody should know this // (damn inlaws, can't ever get things right) str = "INIT ERROR: uninit method for " + a; str += (" in wrong place (" + definer) + ")"; (| (definer.manager()).tell(str) |); (| (a.manager()).tell(str) |); (| sender().tell(str) |); continue; } // introduce the new ancestor catch any { .(method)(); } with { // try and let somebody know they made a boo-boo somewhere str = ((("INIT ERROR " + obj) + "<") + this()) + ">:"; (| (.manager()).tell(str) |); (| (.manager()).tell_traceback(traceback()) |); (| sender().tell(str) |); (| sender().tell_traceback(traceback()) |); (| sender().tell("Continuing chparent..") |); } } refresh(); } }; update objvar Updating objvar $sys<$sys>,core_version object $sys; var $sys core_version = "3.0.1999-08-28"; old method Deleting normal method $sys.backup() object $sys; eval { del_method('backup); }; new method Replacing public method $sys.touch() public method $sys.touch() { arg @nocorelock; if ((!nocorelock) && ((sender().has_flag('core)) && (!writable_core))) throw(~perm, sender() + " is a core object, and the core isn't writable. '@set $sys:writable-core = yes' to allow this."); touched = time(); }; new method Replacing public method $sys.configure_core() public method $sys.configure_core() { var list, l, x, t, err, s; if (caller() != $admin) (> .perms(sender()) <); s = sender(); // if there is nothing left to config, leave.. if (configured) { if (!(list = config_set.set_difference(configured.keys()))) return; } else { configured = #[]; } .add_to_system(s); // wait for other things to finish printing messages to them pause(); pause(); // expand on this as we go s.tell(["*" * 78, strfmt("%78{*}c", " Welcome to ColdCore "), "*" * 78]); s.tell(("This is an interactive configuration system which any admin who connects (until it is completed) is sent through. You must complete this configuration before you can do anything else. You can skip a specific question at any time by typing '@skip'. Suggested default values will be enclosed in square brackets. Pressing enter without any value will use the default value.".wrap_lines(78)).mmap('center, 78)); s.tell("*" * 78); // first question please if (!(configured.contains('new_user_class))) { s.tell("What class should new users be created as? Available classes:"); list = filter x in ($user.descendants()) where (('general_cache in (x.flags())) && (x != $guest)); t = .get_new_user_class(); list = map x in (list) to ((list == t) ? (x + " (current class)") : x); s.tell(list.prefix(" ")); while (!l) { refresh(); l = (> s.prompt(("New User Class [" + t) + "] ") <); if (l == "@skip") { s.tell("Skipping.."); break; } if (l) { catch any { l = $object_lib.to_dbref(l); if (!(l in list)) s.tell("Invalid selection, try again."); } with { s.tell(("Invalid selection '" + l) + "'"); continue; } } else { l = t; } .set_setting("new-user-class", $sys, l); configured = configured.add('new_user_class, 1); s.tell("New User Class set to: " + l); } s.tell(["", "You can set this at any time, with the command:"]); s.tell(" @set $sys:new-user-class=" + l); } refresh(); // server name/title if (!(configured.contains('server_name))) { s.tell(["", "---"]); t = $motd.server_name(); l = (> s.prompt(("What is your server name? [" + t) + "] ") <) || t; if (l == "@skip") { s.tell("Skipping.."); } else { $motd.set_setting("server-name", $motd, l); configured = configured.add('server_name, 1); s.tell("Server name set to: " + l); } s.tell(["", "You can set this at any time, with the command:"]); s.tell(" @set $motd:server-name=" + l); } refresh(); if (!(configured.contains('server_title))) { s.tell(["", "---"]); t = $motd.server_title(); l = (> s.prompt(("What is your server title? [" + t) + "] ") <) || t; if (l == "@skip") { s.tell("Skipping.."); } else { $motd.set_setting("server-title", $motd, l); configured = configured.add('server_title, 1); s.tell("Server title set to: " + l); } s.tell(["", "You can set this at any time, with the command:"]); s.tell(" @set $motd:server-title=" + l); } refresh(); if (!(configured.contains('daemons))) { s.tell(["", "---"]); while (1) { refresh(); list = ($daemon.children()).setremove($login_daemon); s.tell("Which network daemons do you want to have automatically startup,"); s.tell("Other than $login_daemon. Available daemons:"); t = filter l in (startup['objects]) where (l.is($daemon)); for l in (list) { if (l in t) s.tell(strfmt(" %20s (auto starting)", l)); else s.tell(" " + l); } l = (> s.prompt(("Auto-Start: [" + (t.join(", "))) + "] ") <); if (l == "@skip") { s.tell("Skipping.."); break; } else if (!l) { s.tell("Using existing daemons: " + (t.join(", "))); configured = configured.add('daemons, 1); break; } else { err = 0; for x in (l.explode_english_list()) { catch any { .set_setting("startup-objects", $sys, "+" + x); s.tell(("Added " + x) + " as a startup daemon."); } with { s.tell(("Unable to add '" + x) + "' as a daemon:"); s.tell("=> " + ((traceback()[1])[2])); err++; } } if (!err) { configured = configured.add('daemons, 1); break; } s.tell("Errors occurred..."); } } s.tell(["", "You can set this at any time, with the command:"]); s.tell(" @set $motd:startup-objects=OBJECTS..."); } // Other things to add: HTTP Virtual Hosting info, // Let them know, if they actually saw anything.. s.tell(["", strfmt("%79{*}c", " Configuration Complete ")]); }; new method Replacing public method $sys.del_from_system() public method $sys.del_from_system() { arg obj; if (!(.is_admin(sender()))) throw(~perm, "Sender is not an admin."); if (!((obj in admins) || (obj in agents))) throw(~perm, "Object is not an agent or admin."); system = setremove(system, obj); }; new method Replacing public method $sys.add_to_system() public method $sys.add_to_system() { arg obj; if (!(.is_admin(sender()))) throw(~perm, "Sender is not an admin."); if (!((obj in admins) || (obj in agents))) throw(~perm, "Object is not an agent or admin."); system = setadd(system, obj); }; new method Replacing driver method $sys.startup() driver method $sys.startup() { arg args; var opt, str, obj, f, ver, firsttime, doinit; set_heartbeat(0); // clean db? if ("-clean" in args) { catch any { dblog("** Cleaning Database.."); (> .clean_database() <); dblog("** Done."); if (dict_contains(startup, 'time)) startup = dict_del(startup, 'time); } with { .log($parse_lib.traceback(traceback())); } doinit = "-init" in args; } else { doinit = ("-init" in args) || (!dict_contains(startup, 'time)); } // init? if (doinit) { catch any { dblog("** Initializing Database.."); (> .init_database() <); dblog("** Done."); } with { .log($parse_lib.traceback(traceback())); } } // done? if ("-quit" in args) { dblog("** Shutting down."); .shutdown(); return; } // make core? if ((opt = find opt in (args) where (opt.match_begin("-makecore=")))) { ver = regexp(args[opt], "-MAKECORE=(.*)$")[1]; dblog(("** Calling .make_core(\"" + ver) + "\").."); .make_core(ver); return; } // Standard startup.. startup = startup.add('time, time()); backup = backup.add('next, time() + (backup['interval])); // In case we're recovering from a backup if (dict_contains(backup, 'started)) backup = dict_del(backup, 'started); catch any { // get back the heartbeat set_heartbeat(startup['heartbeat_interval]); // Bind functions for security for f in (bindings) { catch any bind_function(@f); with dblog((("** Unable to bind function " + (f[1])) + "() to ") + (f[2])); } // tell objects who should know, that we are online if (type(args) != 'list) args = []; for obj in (startup['objects]) { .log(("Calling " + obj) + ".startup()"); catch any (> obj.startup(@args) <); with .log($parse_lib.traceback(traceback())); } } with { .log(("** Startup ERROR at " + ctime()) + ":"); .log(toliteral(traceback())); .log($parse_lib.traceback(traceback(), -1, "")); } }; new method Replacing private method $sys.create() private method $sys.create() { arg parents, name, manager; var new; new = create(parents); catch any { new.initialize(); // niggle the names around... $has_name may have initted the wrong name new.set_objname(name); if ((new.has_ancestor($has_name)) && ((new.name()) == ("#" + (new.objnum())))) { catch ~invname new.set_name(substr(tostr(new), 2)); } // let it manage itself new.change_manager(manager); } with { // Failed to initialize the child; destroy it. $sys.log_traceback(traceback(), ((((("CREATE (" + parents) + ", '") + name) + ", ") + manager) + ")"); (| new.destroy() |); rethrow(error()); } return new; }; new method Replacing private method $sys.clean_database() private method $sys.clean_database() { var obj, p, c, cmd; // cleanup some of $root's messiness for obj in ($root.descendants()) { (| obj.clean_root() |); refresh(); } // purge all command caches for obj in ($command_cache.descendants()) { (| obj.purge_cache() |); refresh(); } // check user info (move'em home etc) for obj in ($user.descendants()) { if ((| (obj.home()) != (obj.location()) |)) (| obj.move_to(obj.home()) |); refresh(); } // validate all locations and location content's for obj in ($physical.descendants()) { (| obj.validate_contents() |); if (obj.has_ancestor($located)) { if ((!valid(obj.location())) || (!(obj in ((obj.location()).contents())))) (| obj.move_to((| obj.home() |) || $lost_and_found) |); } refresh(); } }; new method Replacing public method $sys.server_info() public method $sys.server_info() { arg what, @long; var tmp; switch (what) { case 'up_time: return time() - (startup['time]); case 'startup_time: return startup['time]; case 'server_hostname: return $dns.hostname(""); case 'server_ip: return $dns.ip(""); case 'last_backup: return backup['last]; case 'driver_version: tmp = .version(); return (((((((long ? "Genesis " : "") + (tmp[1])) + ".") + (tmp[2])) + ".") + (tmp[3])) + "-") + ((listlen(tmp) == 3) ? "NEED TO UPGRADE" : (tmp[4])); case 'core_version: return (long ? "ColdCore " : "") + core_version; case 'version: tmp = .version(); return ((((((((("Genesis/" + (tmp[1])) + ".") + (tmp[2])) + ".") + (tmp[3])) + "-") + (tmp[4])) + " ") + "ColdCore/") + core_version; default: throw(~unknown, "Unknown flag."); } }; update objvar Updating objvar $mutex<$root>,flags object $mutex; var $root flags = ['variables, 'methods, 'code, 'core, 'fertile]; add objvar Adding objvar $dmi_data<$root>,credit object $dmi_data; var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"]; old method Deleting normal method $dictionary.nunion() object $dictionary; eval { del_method('nunion); }; new method Adding public method $buffer.bufsub2() public method $buffer.bufsub2() { arg buf, a, b; var i, la, lb, lt; if ((a == b) || ((buflen(a) > buflen(buf)) || ((!a) || (!buf)))) return buf; la = buflen(a); lb = buflen(b); lt = buflen(buf) - la; i = 1; anticipate_assignment(); while ((i < lt) && (i = bufidx(buf, a, i))) { buf = (subbuf(buf, 1, i - 1) + b) + subbuf(buf, i + la); i += lb; } return buf; }; new method Replacing public method $string.decode64() public method $string.decode64() { arg enc_chars; var i, j, k, ints, out_buf, len, num, ob; i = 1; out_buf = `[]; len = enc_chars.length(); while (i < len) { refresh(); ints = [0, 0, 0, 0]; j = 1; while (j <= 4) { if (((enc_chars[i]) in base64str) || ((enc_chars[i]) == "=")) { for k in [1 .. 64] { refresh(); if (strcmp(enc_chars[i], base64str[k]) == 0) { ints = replace(ints, j, (k - 1) % 64); break; } } j++; } i++; } out_buf = out_buf + `[(((ints[1]).shleft(2)) % 256) + ((ints[2]).shright(4)), (((ints[2]).shleft(4)) % 256) + ((ints[3]).shright(2)), (((ints[3]).shleft(6)) % 256) + (ints[4])]; } return buf_to_str(out_buf); }; new method Adding public method $string.index() public method $string.index() { arg @args; return stridx(@args); }; new method Adding public method $string.equals() public method $string.equals() { arg str1, str2; return str1 == str2; }; new method Replacing public method $object_lib.to_dbref() public method $object_lib.to_dbref() { arg obj; var dbref; switch (type(obj)) { case 'string: if (!obj) throw(~invdbref, "Invalid object reference \"\"."); if ((obj[1]) == "$") { obj = obj.subrange(2); dbref = (| lookup(tosym(obj)) |); } else if ((obj[1]) == "#") { obj = substr(obj, 2); if (obj.is_numeric()) dbref = (| toobjnum(toint(obj)) |); else throw(~objnf, ("Cannot find object \"#" + obj) + "\"."); } else { dbref = toint(obj[1]); if (dbref || (obj == "0")) dbref = toobjnum(dbref); else dbref = (| lookup(obj) |); } if (!dbref) { dbref = (obj.replace(" ", "_")).lowercase(); catch ~symbol dbref = tosym(dbref); with throw(~symbol, ("Object reference '" + dbref) + "' is invalid."); dbref = (> lookup(dbref) <); } return dbref; case 'objnum: return obj; default: return (> lookup(obj) <); } }; new method Replacing public method $parse_lib.filter_ctext() public method $parse_lib.filter_ctext() { arg what, @defaults; var dic, output, prop, eff, ctext; dic = #[['receiver, sender()], ['time, 'post], ['formatter, $plain_format]]; if (defaults && (type(defaults[1]) == 'dictionary)) dic = dict_union(dic, defaults[1]); switch (class(what)) { case $ctext_frob: output = (what.set_vars(dic)).format(); case $message_frob: output = what.format(dic); case $filtered_frob: if ((prop = (| sender().default_propagator() |))) what = what.propagate(prop); if (!what) { output = `[]; } else { ctext = (what.message()).to_ctext(dic); for eff in (what.effects()) { if (type(eff) == 'string) ctext = ($ctext_frob.new_with([eff + " "], ctext.vars())).append(ctext); else ctext = $propagator_effects.(eff[1])(ctext, dic, eff.subrange(2)); } ctext = ctext.set_vars(what.sensory()); output = ctext.format(); } default: output = what; } return output; }; update objvar Updating objvar $code_lib<$root>,flags object $code_lib; var $root flags = ['methods, 'variables, 'core, 'code]; new method Adding public method $mail_lib.generate_unique_id() public method $mail_lib.generate_unique_id() { arg message; if (!($mail_lib.has_mail_perms(caller()))) (> message.perms(sender()) <); return crypt(toliteral([message.time(), message.from(), message.recipients(), message.subject(), message.body()]), "POP3").subrange(9); }; new method Replacing public method $foundation.all_edit_types(): nooverride public method $foundation.all_edit_types(): nooverride { var i, l, t; l = []; for i in (.ancestors()) { if (type((| (t = i.get_edit_types()) |)) == 'list) l = union(l, i.get_edit_types()); } return l; }; new method Replacing public method $has_commands.get_command_info() public method $has_commands.get_command_info() { arg type, cmd; var info, a, ainfo; info = []; for a in (ancestors()) { if (a == definer()) break; if ((ainfo = (| a.command_info(type, cmd) |))) info = union(info, ainfo); } return info; }; new method Replacing public method $has_commands.add_command() public method $has_commands.add_command() { arg template, method, @type; var cmd, types, count, x; (> .perms(sender()) <); [(type ?= 'local)] = type; if ("*" in template) throw(~invcmd, "Invalid command, command templates cannot contain \"*\"!."); cmd = (> $command_lib.validate_command_template(template) <); if (!(type in ['local, 'remote])) throw(~type, "Command types can be either 'local or 'remote"); if ('this in (((cmd[2]).values()).slice(1))) type = 'remote; if (type == 'remote) { for x in (((cmd[2]).values()).slice(1)) { if (x == 'this) count++; } if (!count) throw(~add_command, "Command type defined as remote with no <this> argument."); else if (count > 1) throw(~add_command, "More than one <this> argument specified in template."); } if (!get_var(type)) set_var(type, #[]); set_var(type, get_var(type).setadd_elem((cmd[1])[1], [@cmd[1], template, method, cmd[2]])); if (type == 'remote) $remote_cache.add_remote_command((cmd[1])[1], this()); else if ((.command_modules()) || filter x in (parents()) where ('general_cache in (x.flags()))) (| .cache_client_init() |); }; new method Replacing public method $has_name.match_name() public method $has_name.match_name() { arg str; var m, t; if (!str) return 0; if ((m = match_begin(name[2], str))) return m; for t in (templates || []) { if ((m = match_template(str, t))) return m; } return 0; }; new method Replacing public method $has_name.init_has_name() public method $has_name.init_has_name() { var objname; objname = tostr(this()); if ((objname[1]) == "$") objname = substr(objname, 2); name = ['prop, objname, objname]; }; new method Replacing public method $described._edit_prose_callback() public method $described._edit_prose_callback() { arg text, client_data; (> .perms(caller(), $editor_reference) <); catch ~parse .set_prose(text); with return ['failure, ["Error: " + ((traceback()[1])[2])]]; return ['success, ["Description set."]]; }; new method Replacing public method $described.get_description(): nooverride public method $described.get_description(): nooverride { arg @dflags; var flags, f; flags = #[['prose, 1], ['actor, sender()]]; if (dflags && (type(dflags[1]) == 'dictionary)) flags = dict_union(flags, dflags[1]); return .description(flags); }; new method Replacing public method $described.set_prose() public method $described.set_prose() { arg new; (> .perms(sender()) <); if (new != 0) { switch (type(new)) { case 'string, 'list: new = (> $compiler.compile_cml(new) <); case 'frob: // we'll let this pass by unharmed -- potentially dangerous default: throw(~invalid, "Prose can be submitted as CML or Ctext"); } } prose = new; }; add objvar Adding objvar $event_handler<$root>,help_node object $event_handler; var $root help_node = $help_sys_events; new method Replacing public method $event_handler.deregister_event() public method $event_handler.deregister_event() { arg event, update_on; var value, event, src, status; (> .perms(sender()) <); if ((events.contains(update_on)) && ((events[update_on]).contains(event))) { // clean it up first.. (ignore status) [status, src] = (events[update_on])[event]; switch (src) { case 'location: (| loc.unhook_from_event(event) |); case 'this: (| .unhook_from_event(event) |); default: (| src.hook_into_event(event) |); } // now cleanup 'events' value = (events[update_on]).del(event); if (value) events = events.add(update_on, value); else events = events.del(update_on); if (!events) clear_var('events); } }; add objvar Adding objvar $scheduler<$root>,credit object $scheduler; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; new method Replacing public method $compiler._make_tag() public method $compiler._make_tag() { arg token, mode, vars, name, flags, args; var method, class; if (mode == 'fmtname) { if (token != "}") throw(~parse, "Extra ']' encountered."); method = tosym("do_" + (name.strip())); class = $format; } if (mode == 'genname) { if (token != "]") throw(~parse, "Extra '}' encountered."); method = tosym("gen_" + (name.strip())); class = $generator; } catch ~methodnf return (> .(method)(vars, flags, args) <); with return (> [class.new_tag(name, flags, args), vars] <); }; new method Adding public method $compiler.do_web() public method $compiler.do_web() { arg vars, flags, args; if (!(flags.contains("src"))) throw(~parse, "no 'src' flag for {web}"); if (!(flags.contains("name"))) throw(~parse, "no 'name' flag for {web}"); return [$format.new_tag("web", flags, args), vars]; }; new method Adding public method $compiler.gen_random() public method $compiler.gen_random() { arg vars, flags, args; if (!(flags.contains("high"))) throw(~parse, "no high flag for [random]"); return [$generator.new_tag("random", flags, args), vars]; }; new method Replacing public method $compiler.do_table() public method $compiler.do_table() { arg vars, flags, args; if (!(flags.contains("cols"))) throw(~parse, "no 'cols' flag for {table}."); return [$format.new_tag("table", flags, ._kill_spaces(args)), vars]; }; new method Replacing public method $compiler.parse_string_new() public method $compiler.parse_string_new() { arg vars, tokens; var mode, out, word, token, i, tmp, ret; if (!tokens) return [[], vars]; mode = ['spaces, 'plain]; i = 1; out = []; word = ""; while (i <= (tokens.length())) { refresh(); token = tokens[i++]; switch (mode[1]) { case 'spaces: if (token != " ") { i--; mode = mode.subrange(2); } case 'plain: if (!(token in ["{", "["])) { if (token == " ") { // No scatter because .check can throw if ((| (ret = ._check_glue(tokens, i)) |)) { i = ret[1]; mode = [ret[2], @mode]; if (word) out += [word]; word = ""; continue; } } word += token.sed("\\\(.)", "%1", "g"); } else { if (word) out += [word]; word = ""; mode = ['spaces, (token == "{") ? 'fmtname : 'genname, @mode]; } case 'fmtname, 'genname: if (((mode[1]) == 'fmtname) && (token == "quote")) { mode = mode.subrange(2); out += [$format.new_tag("quote", [], [tokens[i++]])]; i++; } else { if (token in glue_table) mode = [mode[1], 'spaces, @mode.subrange(2)]; mode = ['spaces, 'flags, #[], token, @mode]; } case 'flags: if (token in ["}", "]"]) { ret = (> ._make_tag(token, mode[4], vars, mode[3], mode[2], []) <); vars = ret[2]; out += [ret[1]]; mode = mode.subrange(5); } else if (token == "=") { throw(~parse, "Value flag with no key."); } else if (token == ":") { mode = ['spaces, 'args, out, mode[2], @mode.subrange(3)]; out = []; } else if ((| (tokens[i]) == "=" |)) { mode = ['flagvalue, token, @mode]; i++; } else { mode = mode.replace(2, (mode[2]).add(token, 1)); } case 'flagvalue: if (token in ["}", "]", ":"]) { mode = mode.subrange(3); i--; } else if (token == " ") { mode = mode.subrange(3); } else if (!(token in ["[", "{"])) { mode = ['spaces, @(mode.subrange(3)).replace(2, (mode[4]).add(mode[2], token.sed("\\\(.)", "%1", "g")))]; } else { if (word) out += [word]; word = ""; mode = ['spaces, (token == "{") ? 'fmtname : 'genname, 'flagset, @mode.subrange(2)]; } case 'flagset: i--; mode = ['spaces, @(mode.subrange(3)).replace(2, (mode[4]).add(mode[2], out[out.length()]))]; out = out.subrange(1, (out.length()) - 1); case 'args: if (token in ["}", "]"]) { if (word) { out += [word]; word = ""; } ret = ._make_tag(token, mode[5], vars, mode[4], mode[3], out); vars = ret[2]; out = (mode[2]) + [ret[1]]; mode = mode.subrange(6); } else if (token in ["{", "["]) { if (word) out += [word]; word = ""; mode = ['spaces, (token == "{") ? 'fmtname : 'genname, @mode]; } else { if (token == " ") { if ((| (ret = ._check_glue(tokens, i)) |)) { i = ret[1]; mode = [ret[2], @mode]; if (word) out += [word]; word = ""; continue; } } word += token.sed("\\\(.)", "%1", "g"); } } } if (word) out += [word]; while ((mode[1]) == 'spaces) mode = mode.subrange(2); if (mode != ['plain]) throw(~parse, "Unclosed tag."); return [out, vars]; }; new method Adding public method $bs_eval.gen_random() public method $bs_eval.gen_random() { arg vars, flags, args; var range, low, high; // No need to ._eval_ctext() since there are no args. low = toint((| flags.getkey("low") |) || 1); high = toint(flags.getkey("high")); return [[random(high - low) + low], vars]; }; new method Replacing public method $plain_format.do_table() public method $plain_format.do_table() { arg vars, flags, args; var tblinfo, i, ntbinfo, info, width, l, lr, lc, inds, ind, cwidth; tblinfo = (| vars['table_info] |) || 0; width = vars['width]; if (!(| (ntbinfo = flags.getkey("cols")) |)) throw(~flags, "Need column information."); ind = (| abs(toint(flags.getkey("ind"))) |) || 0; info = []; cwidth = width - ind; if ("%" in ntbinfo) { for i in (ntbinfo.explode(",")) info += [toint(cwidth * (toint(i) / 100.0))]; } else { for i in (ntbinfo.explode(",")) info += [toint(i)]; } vars = dict_union(vars, #[['table_info, [info, 0]], ['rinfo, $list.make(info.length(), 0)], ['rcont, $list.make(info.length(), [])]]); [args, vars] = ._eval_ctext(args, vars); vars = tblinfo ? (vars.add('table_info, tblinfo)) : (vars.del('table_info)); vars = vars.add('width, width); return ["\n" + args, vars]; }; new method Replacing public method $ansi_format.weed_ansi() public method $ansi_format.weed_ansi() { arg str; var out; out = str.global_regexp("[\]A[0-9A-LN-Za-ln-z;]+m"); return out; return str.global_regexp("\\\A[0-9A-Ln-z;a-ln-z;]+[a-z]"); }; new method Adding public method $html_format.do_input() public method $html_format.do_input() { arg vars, flags, args; [args, vars] = ._eval_ctext(args, vars); return [(("\n<input " + ((flags.mmap('join, "=")).join(" "))) + ">") + args, vars]; }; new method Replacing public method $html_format.do_web() public method $html_format.do_web() { arg vars, flags, args; [args, vars] = ._eval_ctext(args, vars); return [((((args + "<a href=\"") + (flags.getkey("src"))) + "\">") + (flags.getkey("name"))) + "</a>", vars]; }; new method Adding public method $html_format.do_option() public method $html_format.do_option() { arg vars, flags, args; [args, vars] = ._eval_ctext(args, vars); return [(("\n<option " + ((flags.mmap('join, "=")).join(" "))) + ">") + args, vars]; }; new method Replacing public method $html_format.do_td() public method $html_format.do_td() { arg vars, flags, args; var f, n, c, width, align; c = vars['table_col]; vars = vars.add('table_col, c + 1); width = (| (vars['table_cols])[c] |); f = " " + join(flags.mmap('join, "="), " "); if (!(| flags.getkey("valign") |)) f += " valign=top"; if (width) f += (" width=\"" + width) + "\""; [args, vars] = ._eval_ctext(args, vars); return [((("\n<td " + f) + ">") + args) + "</td>", vars]; }; new method Replacing root method $world.core_world() root method $world.core_world() { .set_setting("realms", $world, "$realm_of_creation"); .set_setting("starting-place", $world, $the_pit); }; update objvar Updating objvar $motd<$motd>,connect_help object $motd; var $motd connect_help = ["Connection Help", "===============", "", " Connecting as a guest: 'guest <name> <email>'", " Example: 'guest John Doe johndoe@domain.com'", "", " Connecting as a user: 'connect <name> <password>'", " Example: 'connect John Doe mypassword'", "", " Quitting (this screen): '@quit' or 'quit'", "", "Connected Users Listing: '@who'", "", " Creating a user: 'create <name> <password> <email@host>'", " Example: 'connect John Doe mypassword johndoe@domain.com'"]; update objvar Updating objvar $motd<$motd>,notes object $motd; var $motd notes = ["", "Due to a disk failure we have reverted to an older copy of the db", "If you had a user but do not now, this is why.", "Sorry!", ""]; new method Adding public method $located.eject(): nooverride public method $located.eject(): nooverride { arg @args; var old, mover, place; [(place ?= $nowhere)] = args; if (!($sys.is_system(sender()))) { if (sender() == location) place = (.has_ancestor($body)) ? ($world.starting_place()) : $nowhere; else throw(~perm, ("Only system objects and " + (.name())) + "'s current location may call .eject()"); } // Don't do anything if we're already here. if (place == location) return; if (!(place.has_ancestor($location))) throw(~type, (place.namef('ref)) + " is not a location."); if (place == this()) throw(~move, "You cannot move something into itself."); if (!valid(location)) location = $nowhere; mover = sender(); // Set location. old = location; location = place; old.del_sender_from_contents(); place.add_sender_to_contents(); // Notify involved parties of completed move, in reverse order. place.did_arrive(mover, old); old.did_leave(mover, place); .did_move(mover, old); }; new method Replacing protected method $command_cache.cache_client_uninit() protected method $command_cache.cache_client_uninit() { var p; if (sender() != this()) (> .perms(sender()) <); if (.is($place)) { for p in (.contents()) { if (p.is($command_cache)) return; } } for p in (([this()] + parents()) + modules) (| p.cache_server_uninit() |); }; new method Replacing public method $command_cache.cache_server_uninit() public method $command_cache.cache_server_uninit() { var user; if (caller() != $command_cache) throw(~perm, "Caller is not of the command subsystem."); // see if anybody still needs us, otherwise purge if (.is_general_cache()) { for user in ($user_db.connected()) { if ((user.has_ancestor(this())) || (this() in (user.command_modules()))) return; } } .purge_cache(); }; new method Replacing public method $command_cache.match_command() public method $command_cache.match_command() { arg str, cmd, args; var command, m, matched, templates, info, cdef, def, cmds, c, p; templates = (matched = []); cmds = #[]; if (dict_contains(commands, cmd)) cmds = #[[this(), commands[cmd]]]; for def in (parents() + modules) { if ((c = def.command_cache()) && dict_contains(c, cmd)) cmds = dict_add(cmds, def, c[cmd]); } if (!cmds) return 0; for def in (cmds) { if ((def[1]) in parents()) p = this(); else p = def[1]; for command in (def[2]) { if (!(info = (command[2]).command_info('local, command[1]))) continue; for cdef in (info) { if ((m = match_template(args, cdef[2])) != 0) matched += [[listlen(m), [str, cmd, @m], p, @sublist(cdef, 3)]]; } templates = union(templates, info.slice(3)); refresh(); } } if (matched) { info = [matched[1]]; matched = delete(matched, 1); for m in (matched) { if ((m[1]) > ((info[1])[1])) info = [m]; else if ((m[1]) == ((info[1])[1])) info += [m]; } return ['command, info]; } if (!templates) return 0; return ['partial, templates]; }; new method Replacing public method $command_cache.cache_client_init() public method $command_cache.cache_client_init() { var p; if (sender() != this()) (> .perms(sender()) <); modules ?= []; for p in (([this()] + parents()) + modules) (| p.cache_server_init() |); }; new method Replacing public method $command_cache.match_remote_command() public method $command_cache.match_remote_command() { arg str, cmd, args; var command, m, matched, templates, info, cdef, def, cmds, c; if (this() != $remote_cache) throw(~perm, "This should only be used on $remote_cache"); templates = (matched = []); if (commands && dict_contains(commands, cmd)) cmds = commands[cmd]; else return 0; for command in (cmds) { if (!(info = (command[2]).command_info('remote, command[1]))) continue; for cdef in (info) { if ((m = match_template(args, cdef[2])) != 0) matched += [[listlen(m), command[2], [str, cmd, @m], @sublist(cdef, 3)]]; } templates = union(templates, info.slice(3)); refresh(); } if (matched) return ['remote, matched]; if (!templates) return 0; return ['partial, templates]; }; add objvar Adding objvar $remote_cache<$command_cache>,shortcuts object $remote_cache; var $command_cache shortcuts = 0; clear objvar Clearing objvar $user_interfaces<$command_cache>,shortcuts object $user_interfaces; old var $command_cache shortcuts; clear objvar Clearing objvar $user_interfaces<$command_cache>,commands object $user_interfaces; old var $command_cache commands; new method Replacing public method $mail_list.set_name() public method $mail_list.set_name() { arg new_name, @args; var old_name; old_name = .name('noarticle); if (new_name && ((new_name[1]) == "*")) new_name = new_name.subrange(2); (> pass(new_name, @args) <); (| $mail_db.key_changed(old_name, new_name) |); }; clear objvar Clearing objvar $mail_ui<$command_cache>,shortcuts object $mail_ui; old var $command_cache shortcuts; clear objvar Clearing objvar $mail_ui<$command_cache>,commands object $mail_ui; old var $command_cache commands; new method Replacing protected method $mail_ui.unsubscribe_cmd() protected method $mail_ui.unsubscribe_cmd() { arg cmdstr, cmd, str; var list, line, mname; (> .perms(caller(), 'command) <); if (!str) return .mail_lists_cmd(); catch ~listnf, ~ambig { list = (> $mail_lib.match_mail_recipient(str) <); } with { if (error() == ~listnf) return (traceback()[1])[2]; else return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + "."; } if (list == this()) return "You cannot unsubscribe yourself."; mname = list.mail_name(); if (!(list in (subscribed.keys()))) return "You are not subscribed to " + mname; .unsubscribe(list); return ("Successfully unsubscribed from " + mname) + "."; }; new method Replacing protected method $mail_ui.parse_mail_recipient_list() protected method $mail_ui.parse_mail_recipient_list() { arg str; var recip, lists; lists = []; for recip in (str.explode_english_list()) { catch ~listnf, ~ambig { recip = (> $mail_lib.match_mail_recipient(recip) <); if (recip.list_is_sendable_by(this())) lists += [recip]; else .tell("You cannot send to " + (recip.mail_name())); } with { if (error() == ~listnf) .tell(("The recipient \"" + recip) + "\" is invalid."); else .tell(((("The list '" + recip) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + "."); } } return lists; }; new method Replacing protected method $mail_ui.next_new_cmd() protected method $mail_ui.next_new_cmd() { arg cmdstr, cmd, str; var mail, list, keys, start; (> .perms(caller(), 'command) <); str = strsed(str, "^ *on +", ""); if (str) { catch any { list = (> $mail_lib.match_mail_recipient(str) <); } with { if (error() == ~ambig) return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + "."; else return (traceback()[1])[2]; } .new_list(list); mail = (| list.mail_list_next((subscribed[list])[2]) |); while (mail && (mail.has_read(this()))) { refresh(); mail = (| list.mail_list_next(mail) |); } if (!mail) return ("No new mail on " + ($mail_lib.mail_name(list))) + "."; .read_mail(mail, list); } else { keys = dict_keys(subscribed); if (!keys) return "You are not subscribed to any lists."; if (!((current['list]) in keys)) current = current.add('list, keys[1]); start = (list = current['list]); while (1) { // anything left on this list? mail = (| list.mail_list_next((subscribed[list])[2]) |); while (mail && (mail.has_read(this()))) { refresh(); mail = (| list.mail_list_next(mail) |); } if (mail) break; // pick a new list catch any list = (> keys[(list in keys) + 1] <); with list = (| keys[1] |); // die? if ((!list) || (list == start)) return "No new mail."; } .new_list(list); .read_mail(mail, list); } }; new method Replacing protected method $mail_ui.reply_cmd() protected method $mail_ui.reply_cmd() { arg cmdstr, cmd, str; var list, msg, args, i, subj, text, recip; (> .perms(caller(), 'command) <); if ((args = match_template(str, "to *"))) str = args[2]; if ((args = match_template(str, "* on *"))) [msg, str, list] = args; else msg = str; if (!list) { list = current['list]; } else { catch ~listnf, ~perm, ~ambig { list = (> $mail_lib.match_mail_recipient(list) <); (> .new_list(list) <); } with { if (error() == ~ambig) return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + "."; else return (traceback()[1])[2]; } } if (!msg) { if (!valid((msg = (| (subscribed[list])[2] |)))) return "No current message to reply to."; } else { catch ~range msg = $mail_lib.range_to_actual($parse_lib.range(msg), current); with return (traceback()[1])[2]; msg = msg[1]; } i = msg in (list.mail()); if (list.is($user)) recip = msg.from(); else recip = list; if (!(recip.is($mail_list))) return (list.namef('ref)) + " is not a valid mail recipient."; .tell(((("Replying to message " + i) + " on ") + (list.mail_name())) + "."); text = msg.body(); if (text == ["", "(no message)", ""]) text = []; text = $mail_lib.indent_reply(text); text = [((("On " + ($time.format("%d-%b-%Y", msg.time()))) + " ") + ((msg.from()).namef('ref))) + " said: "] + text; if (.active_editor()) { .tell("Storing active editor.."); .store_editor(); } subj = msg.subject(); if (!(subj.match_begin("Re:"))) subj = "Re: " + subj; (> .invoke_editor(this(), '_edit_mail_callback, text, ['mail, [recip], subj, i, msg]) <); if (.active_editor()) { .tell(("Editor invoked with " + ((.active_editor()).session_name())) + "."); .tell("Type 'help' for available commands."); } }; new method Replacing protected method $mail_ui.mail_remove_cmd() protected method $mail_ui.mail_remove_cmd() { arg cmdstr, cmd, str; var mail, args, lmail, list, rng, m, x, name, lname, offset, ans; (> .perms(caller(), 'command) <); if ((args = match_template(str, "* on|from *"))) { rng = args[1]; list = args[3]; } else if (!str) { return "You must specify a message and list."; } else { // grr, be hacky args = explode(str); if ((args.length()) > 1) { list = args.last(); if (!(| $mail_lib.match_mail_recipient(list) |)) { rng = str; list = ""; } else { rng = (args.delete(args.length())).join(); } } else { rng = str; list = ""; } } if (!rng) return ("You must specify a message to remove from " + lname) + "."; if (!list) { list = current['list]; ans = (> .prompt(((("Remove mail " + rng) + " from ") + (list.mail_name())) + "? ") <); if (match_regexp(ans, "no|n")) return "Ok, aborting.."; } else { catch ~listnf, ~ambig { list = (> $mail_lib.match_mail_recipient(list) <); } with { if (error() == ~listnf) return (traceback()[1])[2]; else return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + "."; } } lname = list.mail_name(); catch any (> .new_list(list) <); with return (traceback()[1])[2]; if (rng == "$") { mail = (> $mail_lib.range_to_actual(['end, 'single], current) <); } else if (rng && ((rng[1]) == "$")) { catch ~namenf mail = [(> $object_lib.to_dbref(rng) <)]; with return (traceback()[1])[2]; } else { catch ~range mail = (> $mail_lib.range_to_actual($parse_lib.range(rng), current) <); with return (traceback()[1])[2]; } lmail = list.mail(); if ((mail[1]) != (| lmail[1] |)) { offset = (mail[1]) in lmail; lmail = sublist(lmail, offset); offset--; } for m in (mail) { catch ~perm { x = (m in lmail) + offset; name = ((((("#" + x) + " \"") + (m.subject())) + "\" (") + m) + ")"; list.del_mail(m); .tell(((("Removed message " + name) + " from ") + (list.mail_name())) + "."); } with { .tell((traceback()[1])[2]); } } }; new method Replacing protected method $mail_ui.mail_on_cmd() protected method $mail_ui.mail_on_cmd() { arg cmdstr, cmd, str; var args, lmail, mail, rng, start, end, line, list, len, out, m, rows, o, from, subj; (> .perms(caller(), 'command) <); if ((args = match_template(str, "* on *"))) { rng = args[1]; list = args[3]; } else if (match_template(str, "* to *")) { return "Please use the @send command instead."; } else { rng = ""; list = str; } if (!list) { list = current['list]; } else { catch ~listnf, ~perm, ~ambig { list = (> $mail_lib.match_mail_recipient(list) <); (> .new_list(list) <); } with { if (error() == ~ambig) return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + "."; else return (traceback()[1])[2]; } } if (!rng) { mail = list.mail(); end = mail.length(); // minus two for the head and tail rows = (.get_rows()) - 2; if (end > rows) { start = end - rows; mail = sublist(mail, start); } else { start = 1; } rng = (start + "-") + end; } else { catch ~range mail = $mail_lib.range_to_actual($parse_lib.range(rng), current); with return (traceback()[1])[2]; } if (!mail) return "No mail on " + (list.mail_name()); len = (.linelen()) - 36; out = [((("Mail from " + rng) + " on ") + (list.mail_name())) + ":"]; lmail = list.mail(); o = []; for m in (mail) { if (!valid(m)) { list.notify_bad_mail(m); } else { from = $object_lib.get_name(m.from(), 'name); if ((args = regexp(from, "<([^>]+)>"))) from = explode(args[1], "@")[1]; subj = m.subject(); subj = strsed(subj, "^\[[^]]+\] *", ""); o += [$cml_lib.format_tr_tag($cml_lib.format_td_tag((m == (| (subscribed[list])[2] |)) ? "=>" : " "), $cml_lib.format_td_tag(m in lmail), $cml_lib.format_td_tag((m.has_read(this())) ? " " : "!"), $cml_lib.format_td_tag(subj), $cml_lib.format_td_tag(from), $cml_lib.format_td_tag(m.lines()), $cml_lib.format_td_tag($time.format("%d-%h-%Y", m.time())))]; } } return $ctext_frob.new_with((out + [$cml_lib.format_table_tag("5%,5%,2%,50%,17%,5%,15%", o)]) + [$cml_lib.format_sep_tag()]); }; new method Replacing protected method $mail_ui.subscribe_cmd() protected method $mail_ui.subscribe_cmd() { arg cmdstr, cmd, str; var list, mname, l, args, line, len, out; (> .perms(caller(), 'command) <); // this is ugly bad bad args = (> $parse_lib.opt(str, "n?ew") <); if (!(args[1])) { if ("n?ew" in ((args[2]).slice(1))) { out = []; for l in ((subscribed.keys()).setremove(this())) { if ((l.last_received_on()) > ((subscribed[l])[1])) out += [" " + (l.mail_name())]; } if (out) .tell(["New mail on:"] + out); else .tell(["No new mail on the lists you are subscribed to."]); return; } .tell("Currently Subscribed Lists:"); len = (.linelen()) / 3; for l in ((subscribed.keys()).setremove(this())) { if (!valid(l)) { subscribed = dict_del(subscribed, l); } else { line = " " + (l.mail_name()); if ((l.last_received_on()) > ((subscribed[l])[1])) line += " (new mail)"; .tell(line); } } .tell("---"); return; } catch ~listnf, ~ambig { list = $mail_lib.match_mail_recipient(str); } with { if (error() == ~listnf) return (traceback()[1])[2]; else return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + "."; } mname = $mail_lib.mail_name(list); if (list in (subscribed.keys())) return .tell(("You are already subscribed to " + mname) + "."); if (!(list.list_is_readable_by(this()))) return .tell(mname + " is not subscribeable by you."); .subscribe(list); .tell(("Successfully subscribed to " + mname) + "."); }; new method Replacing protected method $mail_ui.mail_lists_cmd() protected method $mail_ui.mail_lists_cmd() { arg @args; var l, output; if (caller() != $mail_ui) (> .perms(caller(), 'command) <); output = map l in (($mail_db.database()).values()) to ($cml_lib.format_tr_tag($cml_lib.format_td_tag(l.mail_name()), $cml_lib.format_td_tag(dict_contains(subscribed, l) ? "[subscribed]" : " "), $cml_lib.format_td_tag((l.list_is_sendable_by(this())) ? "[sendable]" : " "), $cml_lib.format_td_tag((l.list_is_readable_by(this())) ? "[readable]" : " "))); return $ctext_frob.new_with(["All Available Mail Lists:", $cml_lib.format_table_tag("53%,17%,15%,15%", @output), $cml_lib.format_sep_tag()]); }; new method Replacing protected method $mail_ui.mail_read_cmd() protected method $mail_ui.mail_read_cmd() { arg cmdstr, cmd, str; var mail, m, args, opts, lname, list, rng, args, meta; (> .perms(caller(), 'command) <); [args, opts] = (> $parse_lib.opt(str, "m?eta") <); str = args.join(" "); meta = []; if ((m = "m?eta" in (opts.slice(1)))) { if ((opts[m])[3]) meta = [1]; } if ((args = match_template(str, "* on *"))) { rng = args[1]; catch ~listnf, ~ambig { list = (> $mail_lib.match_mail_recipient(args[3]) <); } with { if (error() == ~listnf) { return (traceback()[1])[2]; } else { // error == ~ambig return ((("The list '" + (args[3])) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + "."; } } } else { rng = str; list = current['list]; } catch ~perm (> .new_list(list) <); with return (traceback()[1])[2]; if (((list.mail()).length()) == 0) return ("There is no mail on " + (list.mail_name())) + "."; if (!rng) return ("You must specify a message to read on " + (list.mail_name())) + "."; catch ~range { if (rng == "next") { .read_mail((> list.mail_list_next((subscribed[list])[2]) <), list, @meta); } else if (rng == "prev") { .read_mail((> list.mail_list_prev((subscribed[list])[2]) <), list, @meta); } else { for m in ($mail_lib.range_to_actual($parse_lib.range(rng), current)) .read_mail(m, list, @meta); } } with { return ((("Mail message " + rng) + " does not exist on ") + (list.mail_name())) + "."; } }; new method Replacing root method $location.uninit_location() root method $location.uninit_location() { var obj; for obj in (contents) (| obj.eject() |); }; new method Replacing public method $location.add_sender_to_contents(): nooverride public method $location.add_sender_to_contents(): nooverride { if (caller() != $located) throw(~perm, "Caller is not $located."); if ((sender().location()) != this()) throw(~location, "Sorry, but you're not here."); contents = setadd(contents, sender()); }; add objvar Adding objvar $body<$command_cache>,shortcuts object $body; var $command_cache shortcuts = 0; add objvar Adding objvar $body<$command_cache>,commands object $body; var $command_cache commands = 0; new method Replacing public method $body.pose_cmd() public method $body.pose_cmd() { arg cmdstr, cmd, args; var shortwords, preword_punct_chars, postword_punct_chars, preword_punct_expr, postword_punct_expr, pronouns, ant_pronouns, selfmsg, othersmsg, recips, antecedent, prepunct, postpunct, word, oword, things, who, aliases, msg, cap, name, wname, m, w, quoted, msgdict, posessive, name_expr; (> .perms(caller(), $user, $body) <); args = explode("." + (args.trim())); if (args == ["."]) { (.location()).announce(.name()); return; } // ------------ shortwords = ["a", "an", "the", "to", "for", "out", "of", "on", "at", "and"]; preword_punct_chars = "[\"'`([{]"; postword_punct_chars = "[]})\"',.!?:;]"; // ------------ preword_punct_expr = ("^" + preword_punct_chars) + "+"; postword_punct_expr = postword_punct_chars + "+$"; pronouns = (.gender()).pronouns(); ant_pronouns = $gender_neuter.pronouns(); selfmsg = (othersmsg = (recips = (antecedent = []))); quoted = 0; for word in (args) { if ((m = match_regexp(word, preword_punct_expr))) { prepunct = substr(word, @m[1]); word = substr(word, ((m[1])[2]) + 1); } else { prepunct = ""; } if ((m = match_regexp(word, postword_punct_expr))) { postpunct = substr(word, @m[1]); word = substr(word, 1, ((m[1])[1]) - 1); } else { postpunct = ""; } oword = word; quoted = (quoted + (((prepunct + word).sed("[^\"]+", "", "g")).length())) % 2; if ((!quoted) && ((word.length()) > 0)) { if ((word[1]) == "\\") { oword = (word = word.subrange(2)); } else if (word in shortwords) { // don't match against common short words. } else if (word in ["me", "myself"]) { word = "yourself"; oword = pronouns['pr]; } else if (word == "I") { word = "you"; oword = pronouns['ps]; } else if (word == "my") { word = "your"; oword = pronouns['pp]; } else if (word == "mine") { word = "yours"; oword = pronouns['pq]; } else if (word in [ant_pronouns['ps], "%s"]) { word = ant_pronouns['ps]; oword = antecedent ? [antecedent, word, "you"] : word; } else if (word in [ant_pronouns['po], "%o"]) { word = ant_pronouns['po]; oword = antecedent ? [antecedent, word, "you"] : word; } else if (word in [ant_pronouns['pp], "%p"]) { word = ant_pronouns['pp]; oword = antecedent ? [antecedent, word, "your"] : word; } else if (word in [ant_pronouns['pr], "%r"]) { word = ant_pronouns['pr]; oword = antecedent ? [antecedent, word, ((antecedent.length()) > 1) ? "yourselves" : "yourself"] : word; } else if (word in [ant_pronouns['pq], "%q"]) { word = ant_pronouns['pq]; oword = antecedent ? [antecedent, word, "yours"] : word; } else if ((word[1]) == ".") { // verb to conjugate word = substr(word, 2); if (match_regexp(word, "(ch|sh|s)$")) oword = word + "es"; else if (match_regexp(word, "[^a]y$")) oword = substr(word, 1, strlen(word) - 1) + "ies"; else oword = word + "s"; } else if ((word[1]) == ":") { // a verb for antecedent, to conjugate word = substr(word, 2); if (match_regexp(word, "es$")) oword = substr(word, 1, strlen(word) - 2); else if (match_regexp(word, "ies$")) oword = substr(word, 1, strlen(word) - 3) + "y"; else if (match_regexp(word, "s$")) oword = substr(word, 1, strlen(word) - 1); if ((antecedent.length()) < 2) oword = [antecedent, word, oword]; else word = oword; } else { if ((| substr(word, (word.length()) - 1, 2) |) == "'s") { posessive = "'s"; word = (oword = substr(word, 1, (word.length()) - 2)); } else { posessive = ""; } if (((word[word.length()]) == "*") || (word in ["everyone", "everything"])) { // look for matching things.. if (word in ["everyone", "everything"]) { things = word == "everything"; word = ""; } else if (((word.length()) > 1) && ((word[(word.length()) - 1]) == "*")) { // match things too. word = substr(word, 1, (word.length()) - 2); things = 1; } else { // just match people. things = 0; word = substr(word, 1, (word.length()) - 1); } catch ~ambig, ~objnf { who = [.match_environment(word)]; } with { if ((error() == ~objnf) && word) { who = []; } else { catch ~ambig, ~objnf { who = [(.environment()).match_object(word)]; } with { if (error() == ~ambig) who = (traceback()[1])[3]; else throw(~stop, ("Object '" + word) + "' not found."); } } } who = setremove(who, this()); if (!things) who = filter w in (who) where (w.is($body)); else who = filter w in (who) where (w.is($thing)); if (who) { word = map w in (who) to ((w.name()) + posessive).to_english(); recips = union(recips, who); } else { word = (things ? "nothing" : "nobody") + posessive; } oword = word; posessive = ""; antecedent = who; ant_pronouns = ((antecedent.length()) == 1) ? (((antecedent[1]).gender()).pronouns()) : ($gender_plural.pronouns()); } else if ((| (who = .match_environment((w = word))) |) && (who.is($body))) { // Might be a valid match for a username.. if ((wname = who.name()) == w) { // full name match. Make sure it's capitalized right. word = (oword = wname); recips = setadd(recips, who); antecedent = [who]; ant_pronouns = (who.gender()).pronouns(); } else { aliases = who.name_templates(); aliases = map w in (aliases) to (explode(w, "|")).flatten(); aliases = map w in (aliases) to (strsub(w, "?", "")); if (word in aliases) { word = (oword = wname); recips = setadd(recips, who); antecedent = [who]; ant_pronouns = (who.gender()).pronouns(); } } } word += posessive; oword += posessive; } } quoted = (quoted + ((postpunct.sed("[^\"]+", "", "g")).length())) % 2; selfmsg += [(prepunct + word) + postpunct]; if (type(oword) == 'string) othersmsg += [(prepunct + oword) + postpunct]; else othersmsg += [[oword[1], (prepunct + (oword[2])) + postpunct, (prepunct + (oword[3])) + postpunct]]; refresh(); } msg = ""; cap = 0; for word in (selfmsg) { word = cap ? (" " + (word.capitalize())) : (" " + word); msg += word; cap = match_regexp(word, "[.!?:][^A-Za-z0-9_]*$"); refresh(); } msgdict = #[[this(), (<$ctext_frob, [[("You" + msg) + (cap ? "" : ".")], #[]]>)]]; name = .name(); for w in (recips + [0]) { wname = w ? (w.name()) : 0; cap = 0; msg = ""; name_expr = ((((("( |^)" + preword_punct_chars) + "*(") + ((w.name()).regexp_escape())) + ")('s)?") + postword_punct_chars) + "*( |$)"; for word in (othersmsg) { switch (type(word)) { case 'string: if (w && (wname != "you")) { while ((m = word.match_regexp(name_expr))) { if ((m[4])[1]) word = ((word.subrange(1, ((m[3])[1]) - 1)) + "your") + (word.subrange(((m[4])[1]) + ((m[4])[2]))); else word = ((word.subrange(1, ((m[3])[1]) - 1)) + "you") + (word.subrange(((m[3])[1]) + ((m[3])[2]))); } } word = cap ? (" " + (word.capitalize())) : (" " + word); case 'list: if (w in (word[1])) word = cap ? (" " + ((word[3]).capitalize())) : (" " + (word[3])); else word = cap ? (" " + ((word[2]).capitalize())) : (" " + (word[2])); } msg += word; cap = match_regexp(word, "[.!?:][^A-Za-z0-9_]*$"); refresh(); } msg = (name + msg) + (cap ? "" : "."); msgdict = msgdict.add(w || "general", (<$ctext_frob, [[msg], #[]]>)); } (.location()).announce((<$message_frob, msgdict>)); }; new method Replacing protected method $body.say_cmd() protected method $body.say_cmd() { arg cmdstr, cmd, what; var type, how, idx; (> .perms(caller(), 'command) <); if (what) how = $code_lib.punctuation_type(what); else how = "say"; (.location()).announce((((((.name()) + " ") + how) + "s, \"") + what) + "\""); }; new method Replacing protected method $body.remove_cmd() protected method $body.remove_cmd() { arg cmd, cmdstr, what; (> .perms(caller(), $user, $body) <); what = (> .match_env_nice(what) <); if (!(what.is($wearable_frob))) return ("You are not wearing " + (what.name())) + "."; catch any what = (> what.shed() <); with return (traceback()[1])[2]; return "You remove " + (what.name()); }; new method Replacing protected method $body.parse_interaction_reference() protected method $body.parse_interaction_reference() { arg targets, what, @userdb; var recip, target, msg, out; [(userdb ?= 0)] = userdb; targets = (targets && (targets.explode_list())) || []; if (!targets) { if (!(targets = (| interaction['objs] |))) throw(~stop, ("You must direct your " + what) + " to a target."); out = targets[2]; } else { out = []; for recip in (targets) { target = 0; if (userdb) target = (| $user_db.match_begin(recip) |); if (!target) { catch ~objnf, ~namenf, ~invdbref, ~context, ~ambig target = (> .match_environment(recip) <); with throw(~stop, (traceback()[1])[2]); } if (!(target.is($body))) throw(~stop, (target.namef('ref)) + " is not a valid recipient."); out = setadd(out, target); } } return filter target in (out) where (valid(target)); }; update objvar Updating objvar $robot<$located>,location object $robot; var $located location = $the_pit; add objvar Adding objvar $robot<$command_cache>,shortcuts object $robot; var $command_cache shortcuts = 0; add objvar Adding objvar $robot<$command_cache>,commands object $robot; var $command_cache commands = 0; clear objvar Clearing objvar $command_aliases<$command_cache>,shortcuts object $command_aliases; old var $command_cache shortcuts; clear objvar Clearing objvar $command_aliases<$command_cache>,commands object $command_aliases; old var $command_cache commands; clear objvar Clearing objvar $bad_commands<$command_cache>,shortcuts object $bad_commands; old var $command_cache shortcuts; clear objvar Clearing objvar $bad_commands<$command_cache>,commands object $bad_commands; old var $command_cache commands; update objvar Updating objvar $bad_commands<$bad_commands>,non_supported_cmds object $bad_commands; var $bad_commands non_supported_cmds = #[["quit", "@quit"], ["WHO", "@who"], ["@create", "@new"], ["help", "@help"], ["news", "@news"], ["page", "@page"], ["@gender", "@set gender"], ["uptime", "@status"], ["@alias", "@add-command-alias` or `@add-name-alias"], ["@check", "@monitor"], ["@paranoid", "@monitor"], ["@version", "@status"], ["@lock", "@set lock"], ["@unlock", "@set lock"], ["+com", ["See: `@help Channels`"]], ["tell", "@page"]]; update objvar Updating objvar $bad_commands<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[["@create", [["@create", "*", "@create <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["help", [["help", "*", "help <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["page", [["page", "*", "page <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["who", [["who", "*", "who <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["quit", [["quit", "*", "quit <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["news", [["news", "*", "news <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@gender", [["@gender", "*", "@gender <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["uptime", [["uptime", "*", "uptime <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@alias", [["@alias", "*", "@alias <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@check|@paranoid", [["@check|@paranoid", "*", "@check|@paranoid <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@version", [["@version", "*", "@version <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@lock", [["@lock", "*", "@lock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@unlock", [["@unlock", "*", "@unlock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["+com", [["+com", "*", "+com <any>", 'old_command_cmd, #[[1, ['any, []]]]]]]]; new = #[["@create", [["@create", "*", "@create <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["help", [["help", "*", "help <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["page", [["page", "*", "page <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["who", [["who", "*", "who <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["quit", [["quit", "*", "quit <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["news", [["news", "*", "news <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@gender", [["@gender", "*", "@gender <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["uptime", [["uptime", "*", "uptime <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@alias", [["@alias", "*", "@alias <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@check|@paranoid", [["@check|@paranoid", "*", "@check|@paranoid <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@version", [["@version", "*", "@version <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@lock", [["@lock", "*", "@lock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@unlock", [["@unlock", "*", "@unlock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["+com", [["+com", "*", "+com <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["tell", [["tell", "*", "tell <any>", 'old_command_cmd, #[[1, ['any, []]]]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$bad_commands<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $bad_commands; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); clear objvar Clearing objvar $help_ui<$command_cache>,shortcuts object $help_ui; old var $command_cache shortcuts; clear objvar Clearing objvar $help_ui<$command_cache>,commands object $help_ui; old var $command_cache commands; update objvar Updating objvar $editor_reference<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[["@mcp-upload-session", [["@mcp-upload-session", "*", "@mcp-upload-session <descendant of $editor_session>", 'mcp_upload_cmd, #[[1, ['descendant, [$editor_session]]]]]]], ["@cleanup-sessions|@c-s?essions", [["@cleanup-sessions|@c-s?essions", "", "@cleanup-sessions|@c-s?essions", 'cleanup_sessions, #[]]]], ["@edit", [["@edit", "*", "@edit <any>", 'edit_cmd, #[[1, ['any, []]]]]]]]; new = #[["@mcp-upload-session", [["@mcp-upload-session", "*", "@mcp-upload-session <descendant of $editor_session>", 'mcp_upload_cmd, #[[1, ['descendant, [$editor_session]]]]]]], ["@edit", [["@edit", "*", "@edit <any>", 'edit_cmd, #[[1, ['any, []]]]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$editor_reference<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $editor_reference; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); new method Replacing protected method $editor_reference.reinvoke_editor() protected method $editor_reference.reinvoke_editor() { arg @session; var i, t, name; t = ""; [(session ?= active_editor), (name ?= "")] = session; if (session == 0) return "No session to resume."; bg_sessions ?= []; if (active_editor && ((active_editor != session) || (!(| session.is_resumable() |)))) t = (.store_editor()) + " "; if ((!valid(session)) || (!(session in (bg_sessions + [active_editor])))) { active_editor = 0; return "Invalid session - editor cleared."; } if (!(| session.is_resumable() |)) return "The session is not resumable, you can use '@edit +clean' to remove it"; active_editor = session; bg_sessions = bg_sessions.setremove(active_editor); bg_sessions = filter i in (bg_sessions) where (valid(i)); .add_parser($editor_parser); return [t, ("Resumed editing " + ((.active_editor()).session_name())) + ".", "Type 'help' to list available commands."]; }; new method Replacing public method $editor_reference.cleanup_sessions() public method $editor_reference.cleanup_sessions() { arg @disregard; var out, s; (sender() == $housekeeper) || (> .perms(sender(), this()) <); out = []; for s in (bg_sessions || []) { if (valid(s)) { if (s.cleanup_session()) s.destroy(); else out = setadd(out, s); } } bg_sessions = out; if (valid(active_editor) && (active_editor.cleanup_session())) { active_editor.destroy(); clear_var('active_editor); } return "Clean and invalid sessions cleared."; }; new method Replacing public method $editor_reference.edit_cmd() public method $editor_reference.edit_cmd() { arg cmdstr, com, args; var syn, num, sess, out, type, i, e, bg; (> .perms(caller(), 'command) <); syn = "@edit <object reference> [+type=...]"; args = args.trim(); if (!args) { // list sessions out = []; e = .active_editor(); if (e) { if ($editor_parser in (.parsers())) out += ["** %0 " + (e.session_name())]; else out += [" %0 " + (e.session_name())]; } bg = .background_editor_sessions(); for sess in [1 .. listlen(bg)] out += [((" %" + sess) + " ") + ((bg[sess]).session_name())]; if (out) return ["Editor Sessions:"] + out; return "No editor sessions."; } else if ((args[1]) == "%") { // resume session args = substr(args, 2); if ((!args) || ((args[1]) == " ")) { num = 0; } else { catch ~nonum num = (> args.to_number() <); with return (traceback()[1])[2]; } if (!num) { if (.active_editor()) return .reinvoke_editor(.active_editor(), "%0"); else if (.background_editor_sessions()) sess = (.background_editor_sessions())[1]; else return "No sessions to resume."; } else { if ((listlen((.background_editor_sessions()) || []) < num) || (num < 0)) return ("There is not an editor session %" + num) + "."; sess = (.background_editor_sessions())[num]; } return .reinvoke_editor(sess, "%" + num); } else { args = (> $parse_lib.opt(args, "t?ype", "c?lean") <); if ((i = "c?lean" in ((args[2]).slice(1)))) return .cleanup_sessions(); if ((i = "t?ype" in ((args[2]).slice(1)))) type = ((args[2])[i])[4]; type ?= "any"; catch ~objnf, ~namenf, ~ambig args = replace(args, 1, (> $parse_lib.ref((args[1]).join()) <)); with return (traceback()[1])[2]; return .edit(@args, type); } }; add objvar Adding objvar $channel_ui<$command_cache>,shortcuts object $channel_ui; var $command_cache shortcuts = 0; add objvar Adding objvar $channel_ui<$command_cache>,commands object $channel_ui; var $command_cache commands = 0; clear objvar Clearing objvar $user_info<$command_cache>,shortcuts object $user_info; old var $command_cache shortcuts; clear objvar Clearing objvar $user_info<$command_cache>,commands object $user_info; old var $command_cache commands; clear objvar Clearing objvar $www_preferences<$command_cache>,shortcuts object $www_preferences; old var $command_cache shortcuts; clear objvar Clearing objvar $www_preferences<$command_cache>,commands object $www_preferences; old var $command_cache commands; update objvar Updating objvar $user<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[["@quit", [["@quit", "", "@quit", 'quit_cmd, #[]]]], ["i?nventory", [["i?nventory", "", "i?nventory", 'inventory_cmd, #[]]]], ["@audit", [["@audit", "*", "@audit <any>", 'audit_cmd, #[[1, ['any, []]]]]]], ["@who", [["@who", "*", "@who <any>", 'who_cmd, #[[1, ['any, []]]]]]], ["@del-command-a?lias|@dca?lias", [["@del-command-a?lias|@dca?lias", "*", "@del-command-a?lias|@dca?lias <any>", 'del_command_alias_cmd, #[[1, ['any, []]]]]]], ["@command-a?liases|@ca?liases", [["@command-a?liases|@ca?liases", "*", "@command-a?liases|@ca?liases <any>", 'command_aliases_cmd, #[[1, ['any, []]]]]]], ["@add-command-a?lias|@aca?lias", [["@add-command-a?lias|@aca?lias", "*", "@add-command-a?lias|@aca?lias <any>", 'add_command_alias_cmd, #[[1, ['any, []]]]]]], ["@com?mands", [["@com?mands", "*", "@com?mands <any>", 'commands_cmd, #[[1, ['any, []]]]]]], ["@news", [["@news", "", "@news", 'news_cmd, #[]]]], ["@forget", [["@forget", "*", "@forget <any>", 'forget_cmd, #[[1, ['any, []]]]]]], ["@whereis|@where-is", [["@whereis|@where-is", "*", "@whereis|@where-is <any>", 'whereis_cmd, #[[1, ['any, []]]]]]], ["@password|@passwd", [["@password|@passwd", "*", "@password|@passwd <any>", 'password_cmd, #[[1, ['any, []]]]]]], ["@age", [["@age", "*", "@age <object>", 'age_cmd, #[[1, ['object, []]]]]]], ["@context", [["@context", "", "@context", 'context_cmd, #[]]]], ["@rename", [["@rename", "*", "@rename <any>", 'rename_cmd, #[[1, ['any, []]]]]]], ["@add-writer|@aw", [["@add-writer|@aw", "*", "@add-writer|@aw <any>", 'add_writer_cmd, #[[1, ['any, []]]]]]], ["@del-writer|@dw", [["@del-writer|@dw", "*", "@del-writer|@dw <any>", 'del_writer_cmd, #[[1, ['any, []]]]]]], ["@manage?d", [["@manage?d", "*", "@manage?d <any>", 'managed_cmd, #[[1, ['any, []]]]]]], ["@remember", [["@remember", "* as *", "@remember <object> as <any>", 'remember_cmd, #[[1, ['object, []]], [3, ['any, []]]]]]], ["@remembered", [["@remembered", "*", "@remembered <any>", 'remembered_cmd, #[[1, ['any, []]]]]]], ["discard", [["discard", "*", "discard <object>", 'discard_cmd, #[[1, ['object, []]]]]]], ["@writes", [["@writes", "*", "@writes <object>", 'writes_cmd, #[[1, ['object, []]]]]]], ["@trusted?-by", [["@trusted?-by", "*", "@trusted?-by <object>", 'trusted_by_cmd, #[[1, ['object, []]]]]]], ["@del-trust?ee|@dt", [["@del-trust?ee|@dt", "*", "@del-trust?ee|@dt <object:>", 'del_trustee_cmd, #[[1, ['object_opt, []]]]]]], ["@monitor", [["@monitor", "*", "@monitor <any>", 'monitor_cmd, #[[1, ['any, []]]]]]], ["@ex?amine", [["@ex?amine", "*", "@ex?amine <object:+c?hop>", 'examine_cmd, #[[1, ['object_opt, ["c?hop"]]]]]]], ["@map", [["@map", "", "@map", 'map_cmd, #[]]]], ["@finger|@ustat", [["@finger|@ustat", "*", "@finger|@ustat <user>", 'finger_cmd, #[[1, ['user, []]]]]]], ["@trusts|@trustee?s", [["@trusts|@trustee?s", "*", "@trusts|@trustee?s <object>", 'trusts_cmd, #[[1, ['object, []]]]]]], ["@writers", [["@writers", "*", "@writers <object>", 'writers_cmd, #[[1, ['object, []]]]]]], ["@manager", [["@manager", "*", "@manager <object>", 'manager_cmd, #[[1, ['object, []]]]]]], ["@desc?ribe|@prose", [["@desc?ribe|@prose", "*", "@desc?ribe|@prose <any>", 'description_cmd, #[[1, ['any, []]]]]]], ["l?ook|exam?ine", [["l?ook|exam?ine", "*", "l?ook|exam?ine <any>", 'look_cmd, #[[1, ['any, []]]]]]], ["walk|go", [["walk|go", "*", "walk|go <any>", 'go_cmd, #[[1, ['any, []]]]]]], ["@ant|@add-name-template", [["@ant|@add-name-template", "*", "@ant|@add-name-template <any>", 'add_name_template_cmd, #[[1, ['any, []]]]]]], ["@dnt|@del-name-template", [["@dnt|@del-name-template", "*", "@dnt|@del-name-template <any>", 'del_name_template_cmd, #[[1, ['any, []]]]]]], ["@name-template?s|@template?s", [["@name-template?s|@template?s", "*", "@name-template?s|@template?s <object>", 'name_templates_cmd, #[[1, ['object, []]]]]]], ["@register|@register-name", [["@register|@register-name", "*", "@register|@register-name <any>", 'register_name_cmd, #[[1, ['any, []]]]]]], ["@unregister|@unregister-name", [["@unregister|@unregister-name", "*", "@unregister|@unregister-name <any>", 'unregister_name_cmd, #[[1, ['any, []]]]]]], ["@registered", [["@registered", "", "@registered", 'registered_cmd, #[]]]], ["@page", [["@page", "* with *", "@page <any> with <any>", 'remote_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@paste?-to", [["@paste?-to", "*", "@paste?-to <any>", 'paste_cmd, #[[1, ['any, []]]]]]], ["@new", [["@new", "*", "@new <any>", 'new_cmd, #[[1, ['any, []]]]]]], ["@status|@uptime", [["@status|@uptime", "*", "@status|@uptime <any>", 'status_cmd, #[[1, ['any, []]]]]]], ["@msg?s|@message?s", [["@msg?s|@message?s", "*", "@msg?s|@message?s <any>", 'msg_cmd, #[[1, ['any, []]]]]]], ["@date|@time", [["@date|@time", "*", "@date|@time <any>", 'date_cmd, #[[1, ['any, []]]]]]], ["@set", [["@set", "*", "@set <any>", 'set_cmd, #[[1, ['any, []]]]]]], ["PUEBLOCLIENT", [["PUEBLOCLIENT", "*", "PUEBLOCLIENT <any>", 'pueblo_cmd, #[[1, ['any, []]]]]]], ["@ways|@exits", [["@ways|@exits", "*", "@ways|@exits <any>", 'ways_cmd, #[[1, ['any, []]]]]]], ["@tut?orial", [["@tut?orial", "*", "@tut?orial <any>", 'tutorial_cmd, #[[1, ['any, []]]]]]], ["null", [["null", "*", "null <any>", 'null_cmd, #[[1, ['any, []]]]]]], ["@away", [["@away", "*", "@away <any>", 'away_cmd, #[[1, ['any, []]]]]]], ["@back", [["@back", "", "@back", 'back_cmd, #[]]]], ["@add-trust?ee|@at", [["@add-trust?ee|@at", "*", "@add-trust?ee|@at <object:>", 'add_trustee_cmd, #[[1, ['object_opt, []]]]]]]]; new = #[["@quit", [["@quit", "", "@quit", 'quit_cmd, #[]]]], ["i?nventory", [["i?nventory", "", "i?nventory", 'inventory_cmd, #[]]]], ["@audit", [["@audit", "*", "@audit <any>", 'audit_cmd, #[[1, ['any, []]]]]]], ["@who", [["@who", "*", "@who <any>", 'who_cmd, #[[1, ['any, []]]]]]], ["@del-command-a?lias|@dca?lias", [["@del-command-a?lias|@dca?lias", "*", "@del-command-a?lias|@dca?lias <any>", 'del_command_alias_cmd, #[[1, ['any, []]]]]]], ["@command-a?liases|@ca?liases", [["@command-a?liases|@ca?liases", "*", "@command-a?liases|@ca?liases <any>", 'command_aliases_cmd, #[[1, ['any, []]]]]]], ["@add-command-a?lias|@aca?lias", [["@add-command-a?lias|@aca?lias", "*", "@add-command-a?lias|@aca?lias <any>", 'add_command_alias_cmd, #[[1, ['any, []]]]]]], ["@com?mands", [["@com?mands", "*", "@com?mands <any>", 'commands_cmd, #[[1, ['any, []]]]]]], ["@news", [["@news", "", "@news", 'news_cmd, #[]]]], ["@forget", [["@forget", "*", "@forget <any>", 'forget_cmd, #[[1, ['any, []]]]]]], ["@whereis|@where-is", [["@whereis|@where-is", "*", "@whereis|@where-is <any>", 'whereis_cmd, #[[1, ['any, []]]]]]], ["@password|@passwd", [["@password|@passwd", "*", "@password|@passwd <any>", 'password_cmd, #[[1, ['any, []]]]]]], ["@age", [["@age", "*", "@age <object>", 'age_cmd, #[[1, ['object, []]]]]]], ["@context", [["@context", "", "@context", 'context_cmd, #[]]]], ["@rename", [["@rename", "*", "@rename <any>", 'rename_cmd, #[[1, ['any, []]]]]]], ["@add-writer|@aw", [["@add-writer|@aw", "*", "@add-writer|@aw <any>", 'add_writer_cmd, #[[1, ['any, []]]]]]], ["@del-writer|@dw", [["@del-writer|@dw", "*", "@del-writer|@dw <any>", 'del_writer_cmd, #[[1, ['any, []]]]]]], ["@manage?d", [["@manage?d", "*", "@manage?d <any>", 'managed_cmd, #[[1, ['any, []]]]]]], ["@remember", [["@remember", "* as *", "@remember <object> as <any>", 'remember_cmd, #[[1, ['object, []]], [3, ['any, []]]]]]], ["@remembered", [["@remembered", "*", "@remembered <any>", 'remembered_cmd, #[[1, ['any, []]]]]]], ["discard", [["discard", "*", "discard <object>", 'discard_cmd, #[[1, ['object, []]]]]]], ["@writes", [["@writes", "*", "@writes <object>", 'writes_cmd, #[[1, ['object, []]]]]]], ["@trusted?-by", [["@trusted?-by", "*", "@trusted?-by <object>", 'trusted_by_cmd, #[[1, ['object, []]]]]]], ["@del-trust?ee|@dt", [["@del-trust?ee|@dt", "*", "@del-trust?ee|@dt <object:>", 'del_trustee_cmd, #[[1, ['object_opt, []]]]]]], ["@monitor", [["@monitor", "*", "@monitor <any>", 'monitor_cmd, #[[1, ['any, []]]]]]], ["@ex?amine", [["@ex?amine", "*", "@ex?amine <object:+c?hop>", 'examine_cmd, #[[1, ['object_opt, ["c?hop"]]]]]]], ["@map", [["@map", "", "@map", 'map_cmd, #[]]]], ["@finger|@ustat", [["@finger|@ustat", "*", "@finger|@ustat <user>", 'finger_cmd, #[[1, ['user, []]]]]]], ["@trusts|@trustee?s", [["@trusts|@trustee?s", "*", "@trusts|@trustee?s <object>", 'trusts_cmd, #[[1, ['object, []]]]]]], ["@writers", [["@writers", "*", "@writers <object>", 'writers_cmd, #[[1, ['object, []]]]]]], ["@manager", [["@manager", "*", "@manager <object>", 'manager_cmd, #[[1, ['object, []]]]]]], ["@desc?ribe|@prose", [["@desc?ribe|@prose", "*", "@desc?ribe|@prose <any>", 'description_cmd, #[[1, ['any, []]]]]]], ["l?ook|exam?ine", [["l?ook|exam?ine", "*", "l?ook|exam?ine <any>", 'look_cmd, #[[1, ['any, []]]]]]], ["walk|go", [["walk|go", "*", "walk|go <any>", 'go_cmd, #[[1, ['any, []]]]]]], ["@ant|@add-name-template", [["@ant|@add-name-template", "*", "@ant|@add-name-template <any>", 'add_name_template_cmd, #[[1, ['any, []]]]]]], ["@dnt|@del-name-template", [["@dnt|@del-name-template", "*", "@dnt|@del-name-template <any>", 'del_name_template_cmd, #[[1, ['any, []]]]]]], ["@name-template?s|@template?s", [["@name-template?s|@template?s", "*", "@name-template?s|@template?s <object>", 'name_templates_cmd, #[[1, ['object, []]]]]]], ["@register|@register-name", [["@register|@register-name", "*", "@register|@register-name <any>", 'register_name_cmd, #[[1, ['any, []]]]]]], ["@unregister|@unregister-name", [["@unregister|@unregister-name", "*", "@unregister|@unregister-name <any>", 'unregister_name_cmd, #[[1, ['any, []]]]]]], ["@registered", [["@registered", "", "@registered", 'registered_cmd, #[]]]], ["@page", [["@page", "* with *", "@page <any> with <any>", 'remote_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@paste?-to", [["@paste?-to", "*", "@paste?-to <any>", 'paste_cmd, #[[1, ['any, []]]]]]], ["@new", [["@new", "*", "@new <any>", 'new_cmd, #[[1, ['any, []]]]]]], ["@status|@uptime", [["@status|@uptime", "*", "@status|@uptime <any>", 'status_cmd, #[[1, ['any, []]]]]]], ["@msg?s|@message?s", [["@msg?s|@message?s", "*", "@msg?s|@message?s <any>", 'msg_cmd, #[[1, ['any, []]]]]]], ["@date|@time", [["@date|@time", "*", "@date|@time <any>", 'date_cmd, #[[1, ['any, []]]]]]], ["@set", [["@set", "*", "@set <any>", 'set_cmd, #[[1, ['any, []]]]]]], ["PUEBLOCLIENT", [["PUEBLOCLIENT", "*", "PUEBLOCLIENT <any>", 'pueblo_cmd, #[[1, ['any, []]]]]]], ["@ways|@exits", [["@ways|@exits", "*", "@ways|@exits <any>", 'ways_cmd, #[[1, ['any, []]]]]]], ["@tut?orial", [["@tut?orial", "*", "@tut?orial <any>", 'tutorial_cmd, #[[1, ['any, []]]]]]], ["null", [["null", "*", "null <any>", 'null_cmd, #[[1, ['any, []]]]]]], ["@away", [["@away", "*", "@away <any>", 'away_cmd, #[[1, ['any, []]]]]]], ["@back", [["@back", "", "@back", 'back_cmd, #[]]]], ["@add-trust?ee|@at", [["@add-trust?ee|@at", "*", "@add-trust?ee|@at <object:>", 'add_trustee_cmd, #[[1, ['object_opt, []]]]]]], ["@player-breakdown|@pb|@user-breakdown|@ub", [["@player-breakdown|@pb|@user-breakdown|@ub", "", "@player-breakdown|@pb|@user-breakdown|@ub", 'player_breakdown_cmd, #[]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$user<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $user; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); old method Deleting normal method $user._who_is() object $user; eval { del_method('_who_is); }; old method Deleting normal method $user._who_at_place() object $user; eval { del_method('_who_at_place); }; old method Deleting normal method $user._who_admins() object $user; eval { del_method('_who_admins); }; old method Deleting normal method $user._who_short() object $user; eval { del_method('_who_short); }; old method Deleting normal method $user._who_programmers() object $user; eval { del_method('_who_programmers); }; old method Deleting normal method $user.reap_notified() object $user; eval { del_method('reap_notified); }; new method Adding public method $user._reap__notified() public method $user._reap__notified() { return reap_notified; }; new method Adding protected method $user._who__short() protected method $user._who__short() { arg people, title, @rest; var user, tmp, who, namestr, total; who = []; total = people.length(); .tell((((title + " (total: ") + tostr(total)) + ((total == 1) ? " person" : " people")) + "):"); for user in (people) { // namestr = " " + user.name() + " (" + $time.elapsed(time() // - user.connected_at()) //+ " " + $time.dhms(user.idle_seconds()) + ")"; namestr = (((((" " + (user.name())) + " (") + ($time.dhms(time() - (user.connected_at())))) + "/") + ($time.dhms(user.idle_seconds()))) + ")"; who += [namestr]; if (tmp < ((namestr.length()) + 2)) tmp = (namestr.length()) + 2; } .tell($list.vcolumnize(who, (.linelen()) / (tmp + 1), .linelen())); }; new method Adding public method $user.format_messages() public method $user.format_messages() { arg target, @what; var messages, out, b, branches, m; catch ~methodnf messages = target.all_msgs(); with return [("[" + (target.name())) + " does not have settable messages]"]; out = []; for m in ((messages.keys()).sort()) { branches = messages[m]; if (branches.contains("general")) { out += [(" " + m) + " = "].affix((branches["general"]).uncompile()); branches = dict_del(branches, "general"); } for b in ((branches.keys()).sort()) out += [(((" " + m) + ".") + b) + " = "].affix((branches[b]).uncompile()); } return out; }; new method Replacing protected method $user.login_notify(): forked protected method $user.login_notify(): forked { arg connection, last; var l, sub, out, ans, rtime; sub = .subscribed(); out = []; for l in ((sub.keys()).setremove(this())) { if (valid(l) && ((l.last_received_on()) > ((sub[l])[1]))) out += [l.mail_name()]; } if (out) .tell("<Mail> New mail on lists: " + (out.to_english())); if ((| (.last_received_on()) > (((.subscribed())[this()])[1]) |)) .tell("<Mail> You have new mail (use `@help mail` to learn about mail)"); if (last) .tell("<Login> Last connected at " + ($time.format("%A %B %d %I:%M %p %Y", abs(last)))); rtime = $time.realm_time((.location()).realm(), 'with_season); .tell((("<Login> It is currently " + (rtime[1])) + " in ") + ((rtime[2]).name())); if (failed) { (| .tell(("<Login> ** " + failed) + " failed login attempts **") |); (| clear_var('failed) |); } if (!(.prose('literal))) .tell(["You have not yet set a description for yourself.", "Perhaps you'd like to take a look at the tutorial.", "Type @tutorial to read about how to set a description and more."]); }; new method Replacing protected method $user.description_cmd() protected method $user.description_cmd() { arg cmdstr, cmd, str; var args, obj, desc, long; (> .perms(caller(), 'command) <); if ((args = match_template(str, "* as *"))) { obj = (> .match_env_nice(args[1]) <); desc = ((args[3]).trim()).unquote(); } else { obj = (> .match_env_nice(str) <); if ((desc = .read()) == 'aborted) return; desc = join(desc.flatten()).trim(); } if (!desc) desc = 0; catch any obj.set_prose(desc); with return (traceback()[1])[2]; return ("Description for " + (obj.namef('ref))) + " set."; }; new method Replacing public method $user.set_cmd() public method $user.set_cmd() { arg cmdstr, cmd, args; var who, branch, name, setting, what, def, opts, clear, showdef, syn; (> .perms(caller(), 'command) <); syn = ["Syntax: @set [TARGET:]SETTING=VALUE", "TARGET defaults to yourself, if unspecified."]; if ((what = regexp(args, "^ *\+(clear|c) +(.*)"))) { clear = 1; args = what[2]; } if ((what = regexp(args, "^ *\+(definers|definer|def|d) *= *\$?([a-z0-9_]+) *(.*)"))) { if (!(showdef = (| lookup(tosym(what[2])) |))) return "Invalid definer $" + (what[2]); args = what[3]; } if ((what = regexp(args, "^ *\+(def|definer|definers|d) *(.*)"))) { showdef = 1; args = what[2]; } if ((what = regexp(args, "^([^:=]+): *(.*)$"))) { who = (> .match_env_nice((what[1]).trim()) <); args = (what[2]).trim(); } else { who = this(); } if ((what = regexp(args, "^([\@a-z0-9-]+) *= *(.*)$"))) { name = (what[1]).trim(); args = (what[2]).trim(); } else { name = args; args = ""; } if (!name) return ([("-- Settings on " + (who.namef('ref))) + ":"] + (.format_settings(who, showdef))) + ["---"]; if (!($code_lib.valid_setting_id(name))) return syn + [("** Invalid Setting name \"" + name) + "\""]; setting = args.unquote(); catch any { def = who.setting_definer(name); if (clear) who = who.clear_setting(name, def); else who = who.set_setting(name, def, setting); setting = who.format_setting(name, def, who.get_setting(name, def)); return ["-- Setting changed to:", ((" " + name) + " = ") + setting, "--"]; } with { if (error() == ~perm) return "You are not allowed to change settings on " + (who.namef('ref)); return (traceback()[1])[2]; } }; new method Replacing protected method $user.rename_cmd() protected method $user.rename_cmd() { arg cmdstr, cmd, args; var obj, name, templates, article, old, oldart, oldts, new, t; (> .perms(caller(), 'command) <); args = args.explode_quoted(); if ((listlen(args) > 2) && ((args[2]) == "to")) args = delete(args, 2); if (listlen(args) > 2) args = [args[1], sublist(args, 2).join()]; if ((!args) || (listlen(args) != 2)) return ("Syntax: `" + cmd) + " \"<object>\" [to] \"<newname>\" [+(proper|unique|normal)]`"; obj = (> .match_env_nice(args[1]) <); catch any { name = (> $code_lib.parse_name(sublist(args, 2).join()) <); templates = name[2]; article = (name[1])[2]; name = (name[1])[1]; if ((name[1]) == "$") { if ((obj.is($user)) || (obj.is($place))) { if (!(.is($admin))) return "User and Place objnames can only be changed by administrators."; else (> .check_mojo() <); } name = substr(name, 2); if (!(name.valid_ident())) return "Object names can only contain a-z, 0-9 and the underscore."; name = tosym(name); old = obj.namef('xref); (> obj.set_objname(name) <); return ((("Renamed " + old) + " to ") + obj) + "."; } else { if (!(obj.has_ancestor($has_name))) return ("Object \"" + obj) + "\" cannot have a regular name."; oldart = (obj.name('literal))[1]; oldts = obj.name_templates(); old = ((((" [" + article) + "] \"") + (obj.name())) + "\"") + (templates ? ((" (" + (oldts.to_english())) + ")") : ""); old = ("\"" + (obj.name())) + "\""; obj = (> obj.set_name(name, article) <); new = ("\"" + (obj.name())) + "\""; if (templates) { for t in (templates) obj = (> obj.add_name_template(t) <); new += (" (" + ((obj.name_templates()).to_english())) + ")"; old += (" (" + (oldts.to_english())) + ")"; } if (oldart != ((obj.name('literal))[1])) { old = (("[" + oldart) + "] ") + old; new = (("[" + ((obj.name('literal))[1])) + "] ") + new; } return ((("Renamed " + old) + " to ") + new) + "."; } } with { return (traceback()[1])[2]; } }; new method Replacing protected method $user.rehash_cmd() protected method $user.rehash_cmd() { arg cmdstr, cmd, args; var target, client, opts, client, o; (> .perms(caller(), 'command) <); [args, opts] = args; if ((o = (| "c?lient" in (opts.slice(1)) |))) client = (opts[o])[3]; else if ((o = (| "r?aw" in (opts.slice(1)) |))) client = !((opts[o])[3]); if (args) target = (> .match_env_nice(join(args)) <); else target = this(); catch ~perm { if (client) { .tell(("Rehashing commands on " + (target.namef('ref))) + "..."); target.cache_client_uninit(); target.cache_client_init(); .tell("Done."); } else { .tell(("Rehashing (raw) commands on " + (target.namef('ref))) + "..."); target.rehash_cache(); .tell("Done."); } } with { return "You do not have permission to rehash " + (target.namef('ref)); } }; new method Replacing root method $user.init_user() root method $user.init_user() { var n; password = "*"; connected_at = 0; last_command_at = 0; connections = []; parsers = [$command_parser, $channel_parser]; action = ""; context = #[]; .set_quota($sys.get_starting('quota)); $user_db.insert(.name(), this()); .set_flags([]); .move_to($body_cave); task_connections = #[]; formatter = $plain_format; }; new method Replacing protected method $user.add_writer_cmd() protected method $user.add_writer_cmd() { arg cmdstr, cmd, args; var syn, obj, writer; (> .perms(caller(), 'command) <); args = (args.replace(" to ", " ")).explode(); if ((!args) || ((args.length()) != 2)) (> .tell_error(cmd + " <writer> [to] <object>") <); writer = (> .match_env_nice(args[1]) <); obj = (> .match_env_nice(args[2]) <); catch any { obj.add_writer(writer); return [(("Sucessfully added writer " + (writer.namef('xref))) + " to ") + (obj.namef('xref)), ("New writers list: " + ((((obj.writers('literal)).compress()).mmap('namef, 'xref)).to_english())) + "."]; } with { .tell((traceback()[1])[2]); } }; new method Adding protected method $user._who__programmers() protected method $user._who__programmers() { arg args, all; var out, progs, p, x, t; progs = []; if (args && (!all)) { for p in (args) { x = $user_db.search(p); if (!x) .tell(("I don't know who \"" + p) + "\" is."); else progs += [x]; } t = (("Programmer" + (progs.length())) == 1) ? "" : "s"; } else if (all) { t = "All Programmers"; progs = $programmer.descendants(); progs = progs.setremove($admin); } else { t = "Connected Programmers"; for p in ($user_db.connected()) { if (p.has_ancestor($programmer)) progs += [p]; } } if (!progs) return 0; return [progs, t]; }; new method Adding protected method $user._who__at_place() protected method $user._who__at_place() { arg str; var place, thing, who, args; if (str == "home") place = .home(); else place = (| .match_environment(str) |); // try the place db if (!place) { catch any { place = $place_db.search(str); } with { switch (error()) { case ~ambig: .tell("Several places match that name: " + ((((traceback()[1])[3]).mmap('namef)).to_english())); case ~namenf: .tell(("The place \"" + str) + "\" cannot be located."); return 0; default: .tell((traceback()[1])[2]); return 0; } } } who = []; for thing in (place.contents()) { if (thing.has_ancestor($user)) who += [thing]; } if (!who) { .tell(("Nobody is in " + (place.name())) + "."); return 0; } args = [who, "Users in " + (place.name())]; args = [@args, [['namef, 'titled], ['idle_time]]]; args = [@args, ["Name", "Times (idle)"], [1, 1]]; return args; }; new method Replacing public method $user.match_name() public method $user.match_name() { arg str; var m, n; if (!str) return 0; if ((m = pass(str))) return m; for n in (registered || []) { if ((m = match_begin(n, str))) return m; } return 0; }; new method Replacing root method $user.uninit_user() root method $user.uninit_user() { var conn, name; if (.connected()) (| (.location()).did_disconnect() |); // and incase any are lying about for conn in (connections) (| conn.interface_going_away() |); password = 0; connections = 0; (| $user_db.remove(.name()) |); for name in (registered || []) (| $user_db.remove(name) |); }; new method Adding public method $user.player_breakdown_cmd() public method $user.player_breakdown_cmd() { arg cmdstr, cmd; var admins, programmers, builders, users, total, pstrip, bstrip, strip, names, players; // stuff to strip // users strip = [$guest, $user, $reaper, $no_one, $player, $builder, $storyteller, $programmer, $admin]; // programmers pstrip = [$admin]; // builders bstrip = [$programmer, $admin]; // get number of admins admins = listlen($sys.admins()); names = $sys.admins(); // get number of programmers, minus those that are also admins programmers = $programmer.descendants(); programmers = $list.setremove_all(programmers, pstrip); programmers = $list.setremove_all(programmers, $sys.admins()); names += programmers; programmers = listlen(programmers); // get number of builders builders = $builder.descendants(); builders = $list.setremove_all(builders, $sys.admins()); builders = $list.setremove_all(builders, $programmer.descendants()); builders = $list.setremove_all(builders, strip); names += builders; builders = listlen(builders); // get number of users users = $user.descendants(); users = $list.setremove_all(users, strip); names += users; users = listlen(users); // get total number of players, users counts everybody, even admins total = users; // correct for backwards places like tCD where everybody is a programmer if ((users - ((admins + programmers) + builders)) < 0) users = 0; else users = users - ((admins + programmers) + builders); // break it down sender().tell("--- Player Breakdown ---"); sender().tell(("There are currently " + total) + " total users."); sender().tell((" " + admins) + " admin(s) *"); sender().tell((" " + programmers) + " programmer(s)"); sender().tell((" " + builders) + " builder(s)"); sender().tell((" " + users) + " user(s)"); sender().tell("---"); sender().tell(""); players = (($sys.admins()).mmap('name)).prefix("*"); players += ($list.setremove_all($list.setremove_all($user_db.user_dbrefs(), strip), $sys.admins())).mmap('name); sender().tell($list.columnize(players, 3)); }; new method Replacing protected method $user.date_cmd() protected method $user.date_cmd() { arg @args; var fmt, l, d, out, rtime; fmt = "%I:%M %p"; l = "%25r "; rtime = $time.realm_time((.location()).realm(), 'with_season); out = [strfmt(l, "Server Time:") + ($time.format(fmt + " %A, %B %d %Y %Z"))]; out += [strfmt(l, ((rtime[2]).name()) + " Time:") + (rtime[1])]; return out; }; new method Replacing public method $user.connection_starting() public method $user.connection_starting() { arg addr, port; var line, c; (> .perms(caller(), $connection) <); // shutoff our connection's timeout sender().set_timeout(0); // cleanup our connections list for c in (connections) { if (!valid(c)) connections = setremove(connections, c); } connections = setadd(connections, sender()); if ((connections.length()) == 1) (| .login(sender()) |); else (| .login_again(sender()) |); line = ("CONNECT " + tostr(sender() in connections)) + " ("; line = (line + ((.parents())[1])) + "): "; line = (((line + this()) + " <") + (sender().address())) + "> "; (| $sys.log(line) |); }; new method Replacing public method $user.who_cmd() public method $user.who_cmd() { arg cmdstr, com, args; var who, title, rest, opts, opt, a, all, prog, admin, short, sort, sortorder, s, x, place, results, sortopts, sortmeths; (> .perms(caller(), 'command) <); // just the basic who listing args = ((.get_setting("@who-options", $user)) + " ") + args; [args, opts] = (> $parse_lib.opt(args, "a?ll", "p?rogrammers", "a?dmins", "s?hort", "so?rt") <); for opt in (opts) { switch (opt[1]) { case "a?ll": all = opt[3]; case "p?rogrammers": prog = opt[3]; case "a?dmins": admin = opt[3]; case "s?hort": short = opt[3]; case "so?rt": sort = opt[4]; sortorder = opt[3]; } } args = (args.join()).explode_english_list(); results = []; if (admin && (admin = ._who__admins([], all))) results += [admin]; if (prog && (prog = ._who__programmers([], all))) results += [prog]; if ((!prog) && ((!admin) && (!args))) { results += [[$user_db.connected(), "Connected Users"]]; } else { for a in (args) { if ((a[1]) == "@") { if ((place = ._who__at_place(a.subrange(2)))) results += [place]; args = args.setremove(a); } } if (args && (args = ._who__is(args))) results += [args]; } who = []; for x in (results) who = union(who, x[1]); title = (results.slice(2)).to_english(); rest = ((results.length()) == 1) ? ((results[1]).subrange(3)) : []; if (!who) return "Ack, nobody to list?"; if (sort) { sortopts = ["idle", "connected", "name", "location", "place"]; sortmeths = ['idle_seconds, 'connected_at, 'name, 'location, 'location]; s = filter x in (sortopts) where (match_begin(x, sort)); if ((s.length()) != 1) { .ptell("Unrecognized sort option: " + sort, #[['type, 'command]]); sort = 0; } else { sort = sortmeths[(s[1]) in sortopts]; } } if (sort) { sort = who.mmap(sort); if (type(sort[1]) == 'objnum) sort = sort.mmap('name); who = who.sort(sort); if (!sortorder) who = who.reverse(); } if (short) return ._who__short(who, title, @rest); else .ptell($code_lib.generate_listing(who, title, @rest), #[['type, 'command]]); }; new method Replacing public method $user.parse_line() public method $user.parse_line() { arg line; var parse, c, r, rval; (> .perms(caller(), $connection) <); set_user(); if (away) .tell("You are still marked as being away."); // if we dont set it, it'll act like normal rval = this(); last_command_at = time(); .set_last_command(line.trim()); catch any { task_connections = task_connections.add(task_id(), sender()); parse = parsers ? ((parsers[1]).parse(this(), line, @parsers.subrange(2), $null_parser)) : ['failed]; switch (parse[1]) { case 'action: r = (| (parse[2]).action(@parse[3]) |); if (type(r) in ['list, 'frob, 'string]) .ptell(r, #[['type, 'parser], ['action, parse[3]]]); else .tell(("Invalid registered action '" + (parse[3])) + "'"); case 'error: .tell(parse[2]); case 'match, 'command: r = (> (parse[2]).(parse[3])(@parse.subrange(4)) <); if (type(r) in ['list, 'frob, 'string]) .ptell(r, #[['type, 'parser], ['command, parse[3]]]); else rval = r; case 'failed: for c in (($place_lib.coordinate_shortcuts()).keys()) { if (line.match_template(c)) { .tell(("There is no exit " + line) + " here."); r = 1; } } if (!r) .tell(("I don't understand " + (line.chop((.linelen()) - 22))) + "."); case 'ok: // do nothing, probably a null command default: .tell("Unusual response from the parser: " + toliteral(parse)); } } with { if (error() == ~stop) { if ((traceback()[1])[2]) .tell((traceback()[1])[2]); } else { .tell_traceback(traceback(), @parse); } } catch any task_connections = task_connections.del(task_id()); return rval; }; new method Adding protected method $user._who__admins() protected method $user._who__admins() { arg args, all; var out, admins, a, x, t; admins = []; if (args && (!all)) { for a in (args) { x = $user_db.search(a); if (!x) .tell(("I don't know who \"" + a) + "\" is."); else admins += [x]; } t = (("Admin" + (admins.length())) == 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 += [a]; } } if (!admins) return 0; return [admins, t]; }; new method Adding protected method $user._who__is() protected method $user._who__is() { arg people, @args; var person, p, who, x; who = []; if (type(people) == 'string) people = ($string.explode_english_list(people, @args)) || []; for p in (people) { catch any { person = $user_db.search(p); } with { switch (error()) { case ~ambig: .tell(((("The name \"" + p) + "\" can match any of: ") + ($list.to_english(filter x in ($user_db.users()) where (x.match_begin(p))))) + "."); continue; default: // hack, look for robots.. catch any { person = ($robot.children()).match_object(p); } with { .tell(("I don't know who \"" + p) + "\" is."); continue; } } } who += [person]; } if (!who) return 0; return [who, ((who.length()) == 1) ? "User" : "Users"]; }; new method Replacing protected method $user.password_cmd(): nooverride protected method $user.password_cmd(): nooverride { arg cmdstr, com, args; var syn, c, curr, new, verify; (> .perms(caller(), 'command) <); syn = com + " [<old password> [<new password>]]"; args = explode(args); c = .task_connection(); if (!args) { while (!curr) curr = (> (.prompt("Current Password (@abort to abort): ")).trim() <); } else { curr = args[1]; } if (!(.check_password(curr))) return "Invalid Password"; if (listlen(args) < 2) { while (1) { while (!new) new = (> (.prompt("New Password (@abort to abort): ")).trim() <); while (!verify) verify = (> (.prompt("Retype New Password (@abort to abort): ")).trim() <); if (new == verify) break; .tell("Passwords do not match!"); new = (verify = 0); } } else if (listlen(args) == 2) { new = args[2]; } else { (> .tell_error(syn) <); } catch any .set_password(new); with (> .tell_error(syn, (traceback()[1])[2]) <); .tell("Password changed."); }; new method Replacing protected method $user.audit_cmd() protected method $user.audit_cmd() { arg cmdstr, cmd, args; var who, obj, col, str, out, total, line, syntax, loc, size, full, s, o; (> .perms(caller(), 'command) <); o = (> $parse_lib.opt(args, "f?ull") <); args = (o[1]).join(); full = (| "f?ull" in ((o[2]).slice(1)) |); if (full) full = ((o[2])[full])[3]; who = (| .match_environment(args) |); if (!who) { who = (| $user_db.search(args) |); if (!who) return ("Unable to find \"" + args) + "\"."; } if (full) { col = (.linelen()) / 2; out = [(((("Objects managed by " + (who.namef('ref))) + ":").pad(col)) + ("bytes".pad(-10))) + " Location"]; for obj in (who.managed()) { if (!valid(obj)) { .tell((" ** invalid object (" + toliteral(obj)) + ") **"); continue; } line = (" " + (obj.namef('xref))).pad(col); s = obj.size(); size = s.to_english(); line = (line + (size.pad(-(((size.length()) > 10) ? (size.length()) : 10)))) + " "; loc = (obj.has_ancestor($located)) ? (("[" + ((obj.location()).name())) + "]") : ""; out += [(line + loc).pad(.linelen())]; total += s; } } else { if ((who != this()) && (!(.is($admin)))) return "Only admins can get quota usage information from other users."; out = [("Quota information on " + (who.namef('ref))) + ":"]; for obj in (who.managed()) { if (valid(obj)) total += obj.size(); } } if ((who == this()) || (.is($admin))) { out += [("Total usage: " + ($integer.to_english(total))) + " bytes"]; size = who.get_quota(); line = ("Total quota: " + ($integer.to_english(size))) + " bytes"; out += [line, ("Remaining: " + ($integer.to_english(size - total))) + " bytes"]; } if (!(who.quota_valid())) { if (who == this()) out += ["*** You are over quota! ***"]; else out += [("*** " + (who.name())) + " is over quota! ***"]; } if (who.quota_exempt()) { if (who == this()) out += ["*** You are exempt from quota! ***"]; else out += [("*** " + (who.name())) + " is exempt from quota! ***"]; } return out; }; new method Replacing public method $user.set_name() public method $user.set_name() { arg new_name, @ignore; var old_name, part, sname; (> .perms(sender(), 'manager) <); // if $sys is calling this, we probably want to strip off // the user_ prefix... if (sender() == $sys) new_name = strsed(new_name, ("^" + ((parents()[1]).objname())) + "_", ""); // so it doesnt bomb on .set_objname if ((> $user_db.valid_name(new_name) <)) old_name = .name(); catch any { (> pass(new_name, 'prop) <); if (new_name in (registered || [])) .unregister_name(new_name); if (!(| $user_db.key_changed(old_name, new_name) |)) $user_db.insert(new_name, this()); if (old_name != new_name) { sname = new_name.strip(); (> .set_objname(tosym("user_" + sname)) <); } } with { (| pass(old_name, 'prop) |); rethrow(error()); } }; new method Replacing frob method $no_one.mail_name() frob method $no_one.mail_name() { arg frob; if (valid(frob[1])) return (frob[1]).mail_name(); return frob[1]; }; new method Adding frob method $no_one.namef() frob method $no_one.namef() { arg frob, @args; if (valid(frob[1])) return (frob[1]).namef(@args); return frob[1]; }; new method Replacing frob method $no_one.name() frob method $no_one.name() { arg frob, @args; if (valid(frob[1])) return (frob[1]).name(); return frob[1]; }; add objvar Adding objvar $player<$command_cache>,commands object $player; var $command_cache commands = 0; add objvar Adding objvar $player<$command_cache>,shortcuts object $player; var $command_cache shortcuts = 0; add objvar Adding objvar $builder<$command_cache>,commands object $builder; var $command_cache commands = 0; update objvar Updating objvar $builder<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[["@realm?s", [["@realm?s", "", "@realm?s", 'realms_cmd, #[]]]], ["@child?ren|@kids", [["@child?ren|@kids", "*", "@child?ren|@kids <object>", 'children_cmd, #[[1, ['object, []]]]]]], ["@par?ents", [["@par?ents", "*", "@par?ents <object>", 'parents_cmd, #[[1, ['object, []]]]]]], ["@build", [["@build", "*", "@build <any:-conf?igure>", 'build_cmd, #[[1, ['any_opt, ["conf?igure"]]]]]]], ["@attach", [["@attach", "* to *", "@attach <any> to <descendant of $place>", 'attach_cmd, #[[1, ['any, []]], [3, ['descendant, [$place]]]]]]], ["@destroy", [["@destroy", "*", "@destroy <list object>", 'destroy_cmd, #[[1, ['list, ['object, []]]]]]]], ["@dig", [["@dig", "*", "@dig <any>", 'dig_cmd, #[[1, ['any, []]]]]]], ["@teleport|@go", [["@teleport|@go", "*", "@teleport|@go <any>", 'teleport_cmd, #[[1, ['any, []]]]]]], ["@def-msg|@def-message", [["@def-msg|@def-message", "*", "@def-msg|@def-message <any>", 'define_msg_cmd, #[[1, ['any, []]]]]]], ["@undef-msg|@undef-message", [["@undef-msg|@undef-message", "*", "@undef-msg|@undef-message <any>", 'undefine_msg_cmd, #[[1, ['any, []]]]]]], ["@prob?lems|@pr|@bug?s", [["@prob?lems|@pr|@bug?s", "*", "@prob?lems|@pr|@bug?s <any>", 'problems_cmd, #[[1, ['any, []]]]]]], ["@mv|@move", [["@mv|@move", "*", "@mv|@move <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]]]; new = #[["@realm?s", [["@realm?s", "", "@realm?s", 'realms_cmd, #[]]]], ["@child?ren|@kids", [["@child?ren|@kids", "*", "@child?ren|@kids <object>", 'children_cmd, #[[1, ['object, []]]]]]], ["@par?ents", [["@par?ents", "*", "@par?ents <object>", 'parents_cmd, #[[1, ['object, []]]]]]], ["@build", [["@build", "*", "@build <any:-conf?igure>", 'build_cmd, #[[1, ['any_opt, ["conf?igure"]]]]]]], ["@attach", [["@attach", "* to *", "@attach <any> to <descendant of $place>", 'attach_cmd, #[[1, ['any, []]], [3, ['descendant, [$place]]]]]]], ["@destroy", [["@destroy", "*", "@destroy <list object>", 'destroy_cmd, #[[1, ['list, ['object, []]]]]]]], ["@dig", [["@dig", "*", "@dig <any>", 'dig_cmd, #[[1, ['any, []]]]]]], ["@teleport|@go", [["@teleport|@go", "*", "@teleport|@go <any>", 'teleport_cmd, #[[1, ['any, []]]]]]], ["@def-msg|@def-message", [["@def-msg|@def-message", "*", "@def-msg|@def-message <any>", 'define_msg_cmd, #[[1, ['any, []]]]]]], ["@undef-msg|@undef-message", [["@undef-msg|@undef-message", "*", "@undef-msg|@undef-message <any>", 'undefine_msg_cmd, #[[1, ['any, []]]]]]], ["@mv|@move", [["@mv|@move", "*", "@mv|@move <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]], ["@action-request|@ar", [["@action-request|@ar", "*", "@action-request|@ar <any>", 'action_request_cmd, #[[1, ['any, []]]]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$builder<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $builder; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); add objvar Adding objvar $builder<$command_cache>,shortcuts object $builder; var $command_cache shortcuts = 0; old method Deleting normal method $builder.format_messages() object $builder; eval { del_method('format_messages); }; old method Deleting normal method $builder._problem__fix() object $builder; eval { del_method('_problem__fix); }; old method Deleting normal method $builder._problem__dismiss() object $builder; eval { del_method('_problem__dismiss); }; old method Deleting normal method $builder._problem__interactive() object $builder; eval { del_method('_problem__interactive); }; old method Deleting normal method $builder._problem__claim() object $builder; eval { del_method('_problem__claim); }; old method Deleting normal method $builder._problem__mailmsg() object $builder; eval { del_method('_problem__mailmsg); }; old method Deleting normal method $builder._problem__get_group() object $builder; eval { del_method('_problem__get_group); }; old method Deleting normal method $builder._problem__comment() object $builder; eval { del_method('_problem__comment); }; old method Deleting normal method $builder._problem__iview() object $builder; eval { del_method('_problem__iview); }; old method Deleting normal method $builder._problem__ilist() object $builder; eval { del_method('_problem__ilist); }; old method Deleting normal method $builder._problem_listgrp() object $builder; eval { del_method('_problem_listgrp); }; old method Deleting normal method $builder.problems_cmd() object $builder; eval { del_method('problems_cmd); }; old method Deleting normal method $builder._problem__view() object $builder; eval { del_method('_problem__view); }; old method Deleting normal method $builder._problem__get_report() object $builder; eval { del_method('_problem__get_report); }; old method Deleting normal method $builder._problem__list() object $builder; eval { del_method('_problem__list); }; new method Adding protected method $builder._ar__get_request() protected method $builder._ar__get_request() { arg args, cmd; var request, g, menu; if (!args) throw(~stop, ("No request specified with '" + cmd) + "'"); [request, @args] = args; if ((request[1]) == "$") { catch any request = $object_lib.to_dbref(request); with throw(~stop, (traceback()[1])[2]); if ((!(request.is($action_request))) || (request == $action_request)) throw(~stop, (request.namef('ref)) + " is not a Action Request."); } else { if ((request[1]) == "#") request = substr(request, 2); request = toint(request); if (request <= 0) throw(~stop, "Invalid request number #" + request); for g in ($argroup.children()) { if (dict_contains(g.requests(), request)) return ((g.requests())[request])[1]; } throw(~stop, "Unable to find action request #" + request); } }; new method Adding protected method $builder._ar__fix() protected method $builder._ar__fix() { arg args, opts, request; var line, cmt, n; n = (request.group()).name(); if (request.resolved_on()) return (((n + " Action Request #") + (request.id())) + " has already been resolved by ") + ((request.resolved_by()).namef('ref)); .tell(request.format()); line = (> .prompt(("Mark " + n) + " Action Request as resolved? [yes] ") <); if ((line.is_boolean()) == 0) return "** Aborting."; .tell("** Enter any final remarks, or nothing for no remarks."); cmt = .read("** Enter \".\" to finish or \"@abort\" to abort."); if (type(cmt) != 'list) return []; request.resolve(); .tell(("** " + n) + " Action Request has been marked as resolved."); if (cmt) request.add_comment(cmt); return ._ar__mailmsg(request, cmt); }; new method Adding protected method $builder._ar__get_group() protected method $builder._ar__get_group() { arg args, opts; var group, groups, s, menu; groups = $argroup.children(); if (opts) { if ("a?ll" in (opts.slice(1))) group = 'All; else if (!(group = (| groups.match_object((opts[1])[2]) |))) throw(~stop, ("Invalid AR Group '" + ((opts[1])[2])) + "'"); } else { while (1) { menu = ["0=>ALL GROUPS"]; for group in [1 .. listlen(groups)] menu += [(group + "=>") + ((groups[group]).name())]; menu += ["X=>Exit"]; s = .do_menu("AR Groups", "Select AR Group", @menu); if ((!s) || (s == "X")) return 0; if (s.is_numeric()) { if ((!(group = (| groups[toint(s)] |))) && (s == "0")) group = 'All; } if (!group) .tell(["**", ("** Sorry, '" + s) + "' is not a valid group."]); else break; } } return group; }; new method Replacing protected method $builder.move_cmd() protected method $builder.move_cmd() { arg cmdstr, cmd, args; var what, dest, loc, opts, src, fromto; (> .perms(caller(), 'command) <); [src, args, opts] = args; if (args && (type(args[1]) == 'string)) { if ((args[1]) == "to") args = delete(args, 1); if (!args) throw(~stop, "You must move to somewhere."); catch ~obj, ~namenf, ~ambig dest = $parse_lib.ref(join(args)); with throw(~stop, (traceback()[1])[2]); } else { dest = args; } what = src[2]; dest = dest[2]; catch any { loc = what.location(); fromto = ((" from " + ((| loc.name() |) || $nowhere)) + " to ") + (dest.name()); (| what.tell(((("You are suddenly yanked" + fromto) + " by ") + (.name())) + ".") |); (> what.move_to(dest) <); // hook into messages eventually (| loc.announce((what.name()) + " suddenly disappears.") |); (| dest.announce((what.name()) + " suddenly appears.", what) |); return (("You move " + (what.name())) + fromto) + "."; } with { (| what.tell(("You feel as if " + (.name())) + " was incapable of moving you, you did not go anywhere.") |); return (traceback()[1])[2]; } }; new method Adding protected method $builder._ar__view() protected method $builder._ar__view() { arg args, opts, request; return request.format(); }; new method Adding protected method $builder._ar__list() protected method $builder._ar__list() { arg args, opts; var requests, w, all, r, g, list, group; group = (> ._ar__get_group(args, opts) <); if (!group) return "Goodbye."; if (group != 'All) { requests = filter r in (group.requests()) where (!((r[2])[2])); requests = #[[group, requests]]; .tell(("** Un-Resolved " + (group.name())) + " Action Requests:"); w = (.linelen()) - 20; } else { requests = #[]; for g in (setremove($argroup.children(), $dismissed_problems)) { list = filter r in (g.requests()) where (!((r[2])[2])); if (list) requests = dict_add(requests, g, list); } all = 1; .tell("** ALL Un-Resolved Action Requests:"); w = (.linelen()) - 34; } return ._ar__listgrp(requests, w, all); }; new method Adding protected method $builder._ar__iview() protected method $builder._ar__iview() { arg pr; var str, msg; msg = "[RET] Return, [N]ext, [P]rev, [C]laim, [F]ix, [D]ismiss, [A]ppend"; while (1) { .tell(pr.format()); str = (> .prompt(msg) <); if ((!str) || match_template(str, "x|ex?it")) return 0; if (match_template(str, "n?ext")) return 'next; if (match_template(str, "p?revious")) return 'prev; if (match_template(str, "c?laim")) .tell(._ar__claim([], [], pr)); else if (match_template(str, "f?ix|r?esolve")) .tell(._ar__fix([], [], pr)); else if (match_template(str, "d?ismiss")) .tell(._ar__dismiss([], [], pr)); else if (match_template(str, "a?ppend|cmt|com?ment")) .tell(._ar__comment([], [], pr)); } }; new method Adding protected method $builder._ar__ilist() protected method $builder._ar__ilist() { arg how; var requests, list, g, r, pr, list, keys, choice; while (1) { if (how == 'mine) { requests = #[]; for g in (setremove($argroup.children(), $dismissed_problems)) { list = filter r in (g.requests()) where ((!((r[2])[2])) && (((r[2])[5]) == this())); if (list) requests = dict_add(requests, g, list); } .tell("** Your Un-Resolved Action Requests:"); list = ._ar__listgrp(requests, (.linelen()) - 32, 1); } else { list = ._ar__list([], []); if ((!list) || (list == "Goodbye.")) return; } pr = (> .prompt("Select Action Request, or [RET] to exit") <); if ((!pr) || match_template(pr, "x|ex?it")) return; if ((!(pr.is_numeric())) || (!dict_contains(list, toint(pr)))) { .tell("Invalid Action Request"); } else { pr = toint(pr); keys = dict_keys(list); while ((choice = ._ar__iview(list[pr]))) { if (choice == 'next) { r = pr in keys; if (r < listlen(keys)) { pr = keys[r + 1]; } else { .tell("No Next Action Request."); break; } } else { r = pr in keys; if (r != 1) { pr = keys[r - 1]; } else { .tell("No Previous Action Request."); break; } } } } } }; new method Adding protected method $builder.action_request_cmd() protected method $builder.action_request_cmd() { arg cmdstr, cmd, args; var syn, opts, request, command; syn = ("Syntax: " + cmd) + " [+<ar group>] <cmt|list|view|claim|dismiss|fix> [addtl]"; [args, opts] = (> $parse_lib.opt(args, "a?ll", "f?ull") <); if (!args) return ._ar__interactive(); if ((listlen(args) > 1) && ((args[1]).is_numeric())) args = [args[2], args[1]] + sublist(args, 3); [command, @args] = args; if (match_template(command, "com?ment|cmt")) { request = (> ._ar__get_request(args, cmd + " comment") <); return (> ._ar__comment(sublist(args, 2), opts, request) <); } else if (match_template(command, "l?ist")) { return (> ._ar__list(args, opts) <); } else if (match_template(command, "v?iew")) { request = (> ._ar__get_request(args, cmd + " view") <); return (> ._ar__view(sublist(args, 2), opts, request) <); } else if (match_template(command, "cl?aim")) { request = (> ._ar__get_request(args, cmd + " claim") <); return (> ._ar__claim(sublist(args, 2), opts, request) <); } else if (match_template(command, "r?esolv|f?ix")) { request = (> ._ar__get_request(args, cmd + " fix") <); return (> ._ar__fix(sublist(args, 2), opts, request) <); } else if (match_template(command, "d?ismiss")) { request = (> ._ar__get_request(args, cmd + " dismiss") <); return (> ._ar__dismiss(sublist(args, 2), opts, request) <); } else { if ((!args) && (command.is_numeric())) { request = (> ._ar__get_request([command], cmd + " view") <); return (> ._ar__view([], opts, request) <); } return [syn, ("Unsupported command '" + command) + "'"]; } }; new method Adding protected method $builder._ar__dismiss() protected method $builder._ar__dismiss() { arg args, opts, request; var line, cmt, n, id; n = (request.group()).name(); id = request.id(); if ((request.group()) == $dismissed_problems) return ((n + " Action Request #") + id) + " has already been dismissed"; .tell(request.format()); line = (> .prompt(((("Dismiss " + n) + " Action Request #") + id) + "? [yes] ") <); if ((line.is_boolean()) == 0) return "** Aborting."; .tell("** Enter any remarks, or nothing for no remarks."); cmt = .read("** Enter \".\" to finish or \"@abort\" to abort."); if (type(cmt) != 'list) return; if (cmt) request.add_comment(cmt); request.change_group($dismissed_problems); return ("** " + n) + " Action Request has been marked as resolved."; }; new method Adding protected method $builder._ar__interactive() protected method $builder._ar__interactive() { var choice, category, bug, list, line, menu; while (choice != 'exit) { choice = .do_menu("Action Requests", "", "1=>Scan unclaimed open requests", "2=>Scan your open requests", "X=>Exit", 'exit); switch (choice) { case "1": (> ._ar__ilist('unclaimed) <); case "2": (> ._ar__ilist('mine) <); case 'exit: return "Goodbye."; } } }; new method Adding protected method $builder._ar__listgrp() protected method $builder._ar__listgrp() { arg requests, w, full; var group, request, r, id, date, summary, resolved, str, list, out; list = #[]; out = []; for group in (dict_keys(requests)) { for request in (requests[group]) { id = request[1]; [r, resolved, date, summary] = request[2]; date = $time.format("%d-%h-%Y", date); if (full) str = strfmt("%4r: %11l %11l %*e", id, group.name(), date, w, summary).trim('right); else str = strfmt("%4r: %13l %*e", id, date, w, summary).trim('right); out += [str]; list = dict_add(list, id, r); } } .tell(out); .tell(("--- " + listlen(dict_keys(list))) + " Total"); return list; }; new method Adding private method $builder._ar__mailmsg() private method $builder._ar__mailmsg() { arg request, msg; var u, recip, text, mail, id, fmt, c, cmts; u = request.submitted_by(); id = request.id(); if (valid(u) && (u.is($mail_list))) { text = (u.mail_name()) + " and *bugs"; .tell("** Specify recipients for this comment, or 'none'"); recip = (> .prompt(("** Mail comment to [" + text) + "] ") <); if (!recip) recip = text; if ((recip == "no") || (recip == "none")) return "** Not mailing."; recip = .parse_mail_recipient_list(recip); if (!recip) return "** No valid recipients."; mail = $mail_message.new_mail(); mail.set_subject((("Comment on AR #" + id) + ": ") + (request.summary())); text = ["Reported By: " + (request.submitted_by())]; text += ["Reported On: " + ($time.format("%d-%h-%Y", request.submitted_on()))]; text += [""]; text += ((request.text()).mmap('wrap_lines, 70, "> ", 1)).flatten(); cmts = request.comments(); msg = (cmts.last())[3]; cmts = sublist(cmts, 1, listlen(cmts) - 1); for c in (cmts) { fmt = "On " + ($time.format("%d-%h-%Y ", c[1])); fmt += ((c[2]).namef('ref)) + " Comments:"; text += ["", fmt] + (((c[3]).mmap('wrap_lines, 70, "> ", 1)).flatten()); } text += [""] + msg; mail.set_text(text); catch any mail.send(@recip); with return (traceback()[1])[2]; return "** Mail sent."; } }; new method Adding protected method $builder._ar__comment() protected method $builder._ar__comment() { arg args, opts, request; var text, fmt, cmt, n, u, msg, id; n = (request.group()).name(); id = request.id(); .tell("** Commenting on Action Request #" + id); cmt = .read("** Enter \".\" to finish or \"@abort\" to abort."); if ((type(cmt) != 'list) || (!cmt)) return "** No comments added."; request.add_comment(cmt); .tell((("** Comments added to " + n) + " AR #") + id); return ._ar__mailmsg(request, cmt); }; new method Replacing protected method $builder.build_query_realm() protected method $builder.build_query_realm() { arg there; var line, realm, r, prompt; prompt = ((("What realm is " + (there.name())) + " in? [") + (((.location()).realm()).name())) + "] "; while (!realm) { line = (> .build_prompt(prompt, tostr((.location()).realm())) <); if (!line) { realm = (.location()).realm(); } else if (line == "@realms") { r = ($place_lib.known_realms()).union($realm.descendants()); .tell(["Realms:", ""] + ((r.mmap('name)).prefix(" "))); } else { realm = $place_lib.match_realm(line); if (!realm) { .tell(("Unknown realm \"" + line) + "\", try @realms."); } else if (!(realm.is($realm))) { .tell((realm.namef('ref)) + " is not a realm, try @realms."); realm = 0; } } } return realm; }; new method Adding protected method $builder._ar__claim() protected method $builder._ar__claim() { arg args, opts, request; var n, id, s, cmt; n = (request.group()).name(); id = request.id(); if (request.claimed_on()) { .tell((((n + " Action Request #") + id) + " has already been claimed by ") + ((request.claimed_by()).namef('ref))); s = (> .prompt("Reclaim it in your name? [no] ") <); if ((!s) || ((s.is_boolean()) == 0)) return "** Aborting."; } .tell(request.format()); s = (> .prompt(("Claim this " + n) + " Action Request? [yes] ") <); if ((s.is_boolean()) == 0) return "** Aborting."; .tell("** Enter any remarks, or nothing for no remarks."); cmt = .read("** Enter \".\" to finish or \"@abort\" to abort claiming."); if (type(cmt) != 'list) return; if (cmt) request.add_comment(cmt); request.claim(); return (("** You have claimed " + n) + " Action Request #") + id; }; clear objvar Clearing objvar $dmi_data_ui<$command_cache>,commands object $dmi_data_ui; old var $command_cache commands; clear objvar Clearing objvar $dmi_data_ui<$command_cache>,shortcuts object $dmi_data_ui; old var $command_cache shortcuts; add objvar Adding objvar $dmi_data_ui<$root>,credit object $dmi_data_ui; var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"]; update objvar Updating objvar $programmer<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[["@id", [["@id", "*", "@id <any>", 'id_cmd, #[[1, ['any, []]]]]]], ["@which", [["@which", "*", "@which <any>", 'which_cmd, #[[1, ['any, []]]]]]], ["@eval", [["@eval", "*", "@eval <any>", 'eval_cmd, #[[1, ['any, []]]]]]], ["@add-c?ommand|@ac", [["@add-c?ommand|@ac", "*", "@add-c?ommand|@ac <any>", 'add_command_cmd, #[[1, ['any, []]]]]]], ["@del-c?ommand|@dc", [["@del-c?ommand|@dc", "*", "@del-c?ommand|@dc <any>", 'del_command_cmd, #[[1, ['any, []]]]]]], ["@join", [["@join", "*", "@join <any>", 'join_cmd, #[[1, ['any, []]]]]]], ["@chpar?ents", [["@chpar?ents", "*", "@chpar?ents <any>", 'chparents_cmd, #[[1, ['any, []]]]]]], ["@add-s?hortcut|@as", [["@add-s?hortcut|@as", "*", "@add-s?hortcut|@as <any>", 'add_shortcut_cmd, #[[1, ['any, []]]]]]], ["@del-m?ethod|@delm?ethod|@dm", [["@del-m?ethod|@delm?ethod|@dm", "*", "@del-m?ethod|@delm?ethod|@dm <objref>", 'del_method_cmd, #[[1, ['objref, []]]]]]], ["@rehash", [["@rehash", "", "@rehash", 'rehash_cmd, #[]]]], ["@trace-method|@trace", [["@trace-method|@trace", "*", "@trace-method|@trace <objref>", 'trace_method_cmd, #[[1, ['objref, []]]]]]], ["@ledit", [["@ledit", "*", "@ledit <objref: +e?dited>", 'local_edit_cmd, #[[1, ['objref_opt, ["e?dited"]]]]]]], ["@program", [["@program", "*", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]]], ["@program", "* with *", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1> with <any>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]], [3, ['any, []]]]]], ["@del-v?ariable|@dv", [["@del-v?ariable|@dv", "*", "@del-v?ariable|@dv <objref>", 'del_var_cmd, #[[1, ['objref, []]]]]]], ["@show", [["@show", "*", "@show <objref: +c?hop>", 'show_cmd, #[[1, ['objref_opt, ["c?hop"]]]]]]], ["@del-s?hortcut|@ds", [["@del-s?hortcut|@ds", "*", "@del-s?hortcut|@ds <any>", 'del_shortcut_cmd, #[[1, ['any, []]]]]]], ["@add-p?arent|@ap", [["@add-p?arent|@ap", "*", "@add-p?arent|@ap <any>", 'add_parent_cmd, #[[1, ['any, []]]]]]], ["@del-p?arent|@dp", [["@del-p?arent|@dp", "*", "@del-p?arent|@dp <any>", 'del_parent_cmd, #[[1, ['any, []]]]]]], ["@grep", [["@grep", "*", "@grep <any:+d?escend +f?ull +l?ist +r?eplace-with=1>", 'grep_cmd, #[[1, ['any_opt, ["d?escend", "f?ull", "l?ist", "r?eplace-with"]]]]]]], ["@chmod|@mmod|@omod|@chflag?s", [["@chmod|@mmod|@omod|@chflag?s", "*", "@chmod|@mmod|@omod|@chflag?s <any>", 'chmod_cmd, #[[1, ['any, []]]]]]], ["@dump", [["@dump", "*", "@dump <any: +t?extdump +m?ethods +v?ariables +h?eader>", 'dump_cmd, #[[1, ['any_opt, ["t?extdump", "m?ethods", "v?ariables", "h?eader"]]]]]]], ["@list", [["@list", "*", "@list <objref: +n?umbers +t?extdump>", 'list_cmd, #[[1, ['objref_opt, ["n?umbers", "t?extdump"]]]]]]], ["@add-v?ariable|@av", [["@add-v?ariable|@av", "*", "@add-v?ariable|@av <any>", 'add_var_cmd, #[[1, ['any, []]]]]]], ["@hl?ist|@help-list", [["@hl?ist|@help-list", "*", "@hl?ist|@help-list <any>", 'help_list_cmd, #[[1, ['any, []]]]]]], ["@hw?rite|@help-write", [["@hw?rite|@help-write", "*", "@hw?rite|@help-write <any>", 'help_write_cmd, #[[1, ['any, []]]]]]], ["@spawn", [["@spawn", "*", "@spawn <any>", 'spawn_cmd, #[[1, ['any, []]]]]]], ["@ancestors", [["@ancestors", "*", "@ancestors <any>", 'ancestors_cmd, #[[1, ['any, []]]]]]], ["@nh?n|@new-help|@new-help-node", [["@nh?n|@new-help|@new-help-node", "*", "@nh?n|@new-help|@new-help-node <any:+n?amed=1 +o?bjname=1 +i?ndex=1>", 'new_help_node_cmd, #[[1, ['any_opt, ["n?amed", "o?bjname", "i?ndex"]]]]]]], ["@config-set?ting|@configure-set?ting", [["@config-set?ting|@configure-set?ting", "*", "@config-set?ting|@configure-set?ting <any>", 'configure_setting_cmd, #[[1, ['any, []]]]]]], ["@def-set?ting|@define-set?ting", [["@def-set?ting|@define-set?ting", "*", "@def-set?ting|@define-set?ting <any>", 'define_setting_cmd, #[[1, ['any, []]]]]]], ["@undef-set?ting|@undefine-set?ting", [["@undef-set?ting|@undefine-set?ting", "*", "@undef-set?ting|@undefine-set?ting <any>", 'undefine_setting_cmd, #[[1, ['any, []]]]]]], ["@descend?ants", [["@descend?ants", "*", "@descend?ants <objref:+a?ll +r?edundant +o?nly +n?ot>", 'descendants_cmd, #[[1, ['objref_opt, ["a?ll", "r?edundant", "o?nly", "n?ot"]]]]]]], ["@d?isplay", [["@d?isplay", "*", "@d?isplay <objref: +c?hop +g?enerations>", 'display_cmd, #[[1, ['objref_opt, ["c?hop", "g?enerations"]]]]]]], ["@cp|@copy", [["@cp|@copy", "*", "@cp|@copy <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]]]; new = #[["@id", [["@id", "*", "@id <any>", 'id_cmd, #[[1, ['any, []]]]]]], ["@which", [["@which", "*", "@which <any>", 'which_cmd, #[[1, ['any, []]]]]]], ["@eval", [["@eval", "*", "@eval <any>", 'eval_cmd, #[[1, ['any, []]]]]]], ["@add-c?ommand|@ac", [["@add-c?ommand|@ac", "*", "@add-c?ommand|@ac <any>", 'add_command_cmd, #[[1, ['any, []]]]]]], ["@del-c?ommand|@dc", [["@del-c?ommand|@dc", "*", "@del-c?ommand|@dc <any>", 'del_command_cmd, #[[1, ['any, []]]]]]], ["@join", [["@join", "*", "@join <any>", 'join_cmd, #[[1, ['any, []]]]]]], ["@chpar?ents", [["@chpar?ents", "*", "@chpar?ents <any>", 'chparents_cmd, #[[1, ['any, []]]]]]], ["@add-s?hortcut|@as", [["@add-s?hortcut|@as", "*", "@add-s?hortcut|@as <any>", 'add_shortcut_cmd, #[[1, ['any, []]]]]]], ["@del-m?ethod|@delm?ethod|@dm", [["@del-m?ethod|@delm?ethod|@dm", "*", "@del-m?ethod|@delm?ethod|@dm <objref>", 'del_method_cmd, #[[1, ['objref, []]]]]]], ["@trace-method|@trace", [["@trace-method|@trace", "*", "@trace-method|@trace <objref>", 'trace_method_cmd, #[[1, ['objref, []]]]]]], ["@ledit", [["@ledit", "*", "@ledit <objref: +e?dited>", 'local_edit_cmd, #[[1, ['objref_opt, ["e?dited"]]]]]]], ["@program", [["@program", "*", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]]], ["@program", "* with *", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1> with <any>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]], [3, ['any, []]]]]], ["@del-v?ariable|@dv", [["@del-v?ariable|@dv", "*", "@del-v?ariable|@dv <objref>", 'del_var_cmd, #[[1, ['objref, []]]]]]], ["@show", [["@show", "*", "@show <objref: +c?hop>", 'show_cmd, #[[1, ['objref_opt, ["c?hop"]]]]]]], ["@del-s?hortcut|@ds", [["@del-s?hortcut|@ds", "*", "@del-s?hortcut|@ds <any>", 'del_shortcut_cmd, #[[1, ['any, []]]]]]], ["@add-p?arent|@ap", [["@add-p?arent|@ap", "*", "@add-p?arent|@ap <any>", 'add_parent_cmd, #[[1, ['any, []]]]]]], ["@del-p?arent|@dp", [["@del-p?arent|@dp", "*", "@del-p?arent|@dp <any>", 'del_parent_cmd, #[[1, ['any, []]]]]]], ["@grep", [["@grep", "*", "@grep <any:+d?escend +f?ull +l?ist +r?eplace-with=1>", 'grep_cmd, #[[1, ['any_opt, ["d?escend", "f?ull", "l?ist", "r?eplace-with"]]]]]]], ["@chmod|@mmod|@omod|@chflag?s", [["@chmod|@mmod|@omod|@chflag?s", "*", "@chmod|@mmod|@omod|@chflag?s <any>", 'chmod_cmd, #[[1, ['any, []]]]]]], ["@dump", [["@dump", "*", "@dump <any: +t?extdump +m?ethods +v?ariables +h?eader>", 'dump_cmd, #[[1, ['any_opt, ["t?extdump", "m?ethods", "v?ariables", "h?eader"]]]]]]], ["@list", [["@list", "*", "@list <objref: +n?umbers +t?extdump>", 'list_cmd, #[[1, ['objref_opt, ["n?umbers", "t?extdump"]]]]]]], ["@add-v?ariable|@av", [["@add-v?ariable|@av", "*", "@add-v?ariable|@av <any>", 'add_var_cmd, #[[1, ['any, []]]]]]], ["@hl?ist|@help-list", [["@hl?ist|@help-list", "*", "@hl?ist|@help-list <any>", 'help_list_cmd, #[[1, ['any, []]]]]]], ["@hw?rite|@help-write", [["@hw?rite|@help-write", "*", "@hw?rite|@help-write <any>", 'help_write_cmd, #[[1, ['any, []]]]]]], ["@spawn", [["@spawn", "*", "@spawn <any>", 'spawn_cmd, #[[1, ['any, []]]]]]], ["@ancestors", [["@ancestors", "*", "@ancestors <any>", 'ancestors_cmd, #[[1, ['any, []]]]]]], ["@nh?n|@new-help|@new-help-node", [["@nh?n|@new-help|@new-help-node", "*", "@nh?n|@new-help|@new-help-node <any:+n?amed=1 +o?bjname=1 +i?ndex=1>", 'new_help_node_cmd, #[[1, ['any_opt, ["n?amed", "o?bjname", "i?ndex"]]]]]]], ["@config-set?ting|@configure-set?ting", [["@config-set?ting|@configure-set?ting", "*", "@config-set?ting|@configure-set?ting <any>", 'configure_setting_cmd, #[[1, ['any, []]]]]]], ["@def-set?ting|@define-set?ting", [["@def-set?ting|@define-set?ting", "*", "@def-set?ting|@define-set?ting <any>", 'define_setting_cmd, #[[1, ['any, []]]]]]], ["@undef-set?ting|@undefine-set?ting", [["@undef-set?ting|@undefine-set?ting", "*", "@undef-set?ting|@undefine-set?ting <any>", 'undefine_setting_cmd, #[[1, ['any, []]]]]]], ["@descend?ants", [["@descend?ants", "*", "@descend?ants <objref:+a?ll +r?edundant +o?nly +n?ot>", 'descendants_cmd, #[[1, ['objref_opt, ["a?ll", "r?edundant", "o?nly", "n?ot"]]]]]]], ["@d?isplay", [["@d?isplay", "*", "@d?isplay <objref: +c?hop +g?enerations>", 'display_cmd, #[[1, ['objref_opt, ["c?hop", "g?enerations"]]]]]]], ["@cp|@copy", [["@cp|@copy", "*", "@cp|@copy <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]], ["@rehash", [["@rehash", "*", "@rehash <any:+r?aw +c?lient>", 'rehash_cmd, #[[1, ['any_opt, ["r?aw", "c?lient"]]]]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$programmer<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $programmer; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); old method Deleting normal method $programmer.grep_full() object $programmer; eval { del_method('grep_full); }; old method Deleting normal method $programmer.grep_replace_method() object $programmer; eval { del_method('grep_replace_method); }; old method Deleting normal method $programmer.grep_list() object $programmer; eval { del_method('grep_list); }; old method Deleting normal method $programmer.grep_replace() object $programmer; eval { del_method('grep_replace); }; old method Deleting normal method $programmer._show_variables() object $programmer; eval { del_method('_show_variables); }; old method Deleting normal method $programmer.grep_brief() object $programmer; eval { del_method('grep_brief); }; old method Deleting normal method $programmer.create_cmd() object $programmer; eval { del_method('create_cmd); }; old method Deleting normal method $programmer._show_methods() object $programmer; eval { del_method('_show_methods); }; new method Adding protected method $programmer._grep__list() protected method $programmer._grep__list() { arg regexp, objs; var obj, code, x, l, lr, what, loop, method, opt; opt = .get_setting("@program-options", $programmer); for obj in (objs) { if (!valid(obj)) continue; if (!(obj.has_flag('code))) { .tell(("You cannot read method code on " + obj) + ", skipping.."); continue; } for method in (obj.methods()) { code = obj.list_method(method); for l in (code) { if (match_regexp(l, regexp)) { .tell(([$object_lib.format_method_header(obj, method, opt, obj.method_flags(method), obj.method_access(method))] + (code.prefix(" "))) + ["."]); break; } refresh(); } refresh(); } refresh(); } return "---"; }; new method Replacing protected method $programmer.del_parent_cmd() protected method $programmer.del_parent_cmd() { arg cmdstr, cmd, args; var syn, obj, parent; (> .perms(caller(), 'command) <); syn = cmd + " <parent> [from] <object>"; args = args.explode(); if ((listlen(args) > 2) && ((args[2]) == "from")) args = delete(args, 2); if (listlen(args) != 2) (> .tell_error(syn) <); if (!args) (> .tell_error(syn) <); parent = (> .match_env_nice(args[1]) <); obj = (> .match_env_nice(args[2]) <); catch any { (> obj.del_parent(parent) <); return ((("Deleted parent from " + (obj.namef('ref))) + ", parents: ") + ((obj.parents()).to_english())) + "."; } with { (> .tell_error("", (traceback()[1])[2]) <); } }; new method Replacing protected method $programmer.grep_cmd() protected method $programmer.grep_cmd() { arg cmdstr, cmd, args; var more, regexp, from, syn, opts, d, f, l, r, rep, slice, objs, obj, out; (> .perms(caller(), 'command) <); [more, opts] = args; if ((more.length()) < 2) return ("=> Syntax: `" + cmd) + " [options] <regexp> <object> <object>.."; regexp = more[1]; more = more.subrange(2); // handle the options slice = opts.slice(1); if ((r = (| "r?eplace-with" in slice |))) { rep = (opts[r])[4]; r = (opts[r])[3]; } if ((d = (| "d?escend" in ((args[2]).slice(1)) |))) d = (opts[d])[3]; if ((l = (| "l?ist" in ((args[2]).slice(1)) |))) l = (opts[l])[3]; if ((f = (| "f?ull" in ((args[2]).slice(1)) |))) f = (opts[f])[3]; // now we check for conflicting or incorrect options.. if (d && (!(.is($admin)))) return "Only administrators may use the +descend option, talk to one."; if (d && ((more.length()) > 1)) return "+descend can only be used with a single object as the target."; if (r && (f || l)) return "+replace-with option cannot be used with +full or +list."; if (f && l) return "+full cannot be used with +list."; // the pause() flushes so we can see the 'Searching for ..' // Do this now because .descendants() can lag .tell(("Searching for \"" + regexp) + "\"..."); pause(); // figure out our targets if (d) { obj = (> .match_env_nice(more[1]) <); objs = [obj, @obj.descendants()]; } else { objs = []; for obj in (more) objs += [(> .match_env_nice(obj) <)]; } // verify its a valid regexp catch ~regexp match_regexp("", regexp); with return "Invalid regular expression: " + ((traceback()[1])[2]); // call the right grep method if (r) return (> ._grep__replace(regexp, objs, rep) <); else if (l) return (> ._grep__list(regexp, objs) <); else if (f) return (> ._grep__full(regexp, objs) <); else return (> ._grep__brief(regexp, objs) <); }; new method Replacing protected method $programmer.descendants_cmd() protected method $programmer.descendants_cmd() { arg cmdstr, cmd, args; var obj, max, line, opts, i, r, not, only, f; (> .perms(caller(), 'command) <); // parse args [obj, args, opts] = args; if ((obj[1]) != 'object) return "Object reference must simply be a dbref."; if ((obj[2]) != (obj[3])) .tell(("Ignoring specified definer " + (obj[2])) + "."); obj = obj[3]; only = (not = []); max = 1; if ((i = "o?nly" in (opts.slice(1)))) { only = map f in ((((opts[i])[4]).split(" *, *")).nonzero()) to (f.to_symbol()); opts = delete(opts, i); } if ((i = "n?ot" in (opts.slice(1)))) { not = map f in ((((opts[i])[4]).split(" *, *")).nonzero()) to (f.to_symbol()); opts = delete(opts, i); } if ((i = "r?edundant" in (opts.slice(1)))) { r = (opts[i])[3]; opts = delete(opts, i); } if ((i = "a?ll" in (opts.slice(1)))) { if ((opts[i])[3]) max = 0; opts = delete(opts, i); } if (opts) { if ((max = find i in (opts) where ((i[2]).is_numeric()))) { max = toint((opts[max])[2]); if (max < 1) return "Maximum levels must be greater than zero."; } } // do it line = ("-- Descendants of " + obj) + " ["; .tell((line + (((obj.parents()).mmap('objname)).to_english())) + "]"); if (max) { line = (max + " level") + ((max > 1) ? "s" : ""); max++; } else { line = "all levels"; } if (r) line += ", redundant entries"; .tell("-- " + line); if (only) .tell("-- only objects with flag(s): +" + (only.join(" AND +"))); if (not) .tell("-- not objects with flag(s): +" + (not.join(" OR +"))); return [obj.format_descendants("", #[], 0, max, only, not, r), "--"]; }; new method Adding protected method $programmer._grep__replace() protected method $programmer._grep__replace() { arg regexp, objs, replace; var obj, method; for obj in (objs) { if (!valid(obj)) continue; if (!(obj.is_writable_by(this()))) { .tell(("You cannot write on " + obj) + ", skipping.."); continue; } for method in (obj.methods()) { (> ._grep__replace_method(obj, method, regexp, replace) <); refresh(); } refresh(); } return "Done."; }; new method Replacing protected method $programmer.display_cmd() protected method $programmer.display_cmd() { arg cmdstr, cmd, args; var opts, slice, what, match, i, chop, f, gen, def, obj, out; (> .perms(caller(), 'command) <); opts = args[3]; args = args[1]; chop = 1; slice = opts.slice(1); if ((i = "c?hop" in slice) && (!((opts[i])[3]))) chop = 0; else chop = .linelen(); def = args[3]; if ((i = "g?enerations" in slice)) { gen = (opts[i])[4]; if (gen.is_numeric()) gen = ['generations, toint(gen)]; else if (gen) gen = ['ancestors_descending, (> .match_env_nice(gen) <)]; else gen = ['ancestry, def]; def = 0; } else { gen = ['generations, 1]; } what = [args[1]] + ((| args[5] |) ? [args[5]] : []); obj = args[2]; if (type(obj) == 'frob) return ["The target object was a frob. Please use @exam instead."]; out = $object_lib.format_object(obj, chop); if (!(args[4])) f = .get_setting("match-default", $programmer); else f = args[4]; match = .get_setting("match-with", $programmer); catch ~perm { if ('method in what) out += ._display_methods(obj, obj.list_methods(gen, def, f, match), chop, f); } with { out += [" ** No permission to list methods **"]; } catch ~perm { if ('variable in what) out += ._display_variables(obj, obj.variable_info(gen, def, f, match), chop, f); } with { out += [" ** No permission to show variables **"]; } return out + ["---"]; }; new method Adding protected method $programmer._grep__brief() protected method $programmer._grep__brief() { arg regexp, objs; var obj, method, out, x, l, line, lines, code; for obj in (objs) { if (!valid(obj)) continue; if (!(obj.has_flag('code))) { .tell(("You cannot read method code on " + obj) + ", skipping.."); continue; } out = []; for method in (obj.methods()) { code = obj.list_method(method); lines = []; for x in [1 .. listlen(code)] { l = code[x]; if (match_regexp(l, regexp)) lines += [x]; refresh(); } if (lines) out += [(((obj + ".") + method) + "(): ") + (lines.to_english())]; refresh(); } if (out) .tell(out); refresh(); } return "---"; }; new method Replacing public method $programmer.eval_prefix() public method $programmer.eval_prefix() { return dict_union(#[["me", ("me = " + this()) + ";"], ["here", ("here = " + (.location())) + ";"]], eval_prefix || #[]); }; new method Adding protected method $programmer._grep__replace_method() protected method $programmer._grep__replace_method() { arg obj, method, regexp, replace; var old_code, code, x, l, lr, errs, what; old_code = (code = obj.list_method(method)); for x in [1 .. listlen(code)] { l = code[x]; if (!match_regexp(l, regexp)) continue; lr = strsed(l, regexp, replace, "g"); .tell([((((("Change " + obj) + ".") + method) + "() line ") + x) + " from:", " " + l, "to:", " " + lr]); what = (> .prompt("? (yes, no, abort, abort-all) [yes] ") <); if ((!what) || (what in ["yes", "y"])) { code = replace(code, x, lr); } else if (what == "abort") { .tell("Aborting method .."); return; } else if (what == "abort-all") { throw(~stop, "Aborting grep replace"); } else if (!(what in ["no", "n"])) { .tell(("Unknown command '" + what) + "', assuming 'no'."); } refresh(); } if ((old_code != code) && (errs = obj.add_method(code, method))) .tell(((([((("Error in compilation of updated method " + obj) + ".") + method) + "():"] + (errs.prefix(" "))) + ["-- Method code: "]) + (code.prefix(" "))) + ["--"]); }; new method Adding protected method $programmer._show__methods() protected method $programmer._show__methods() { arg obj, f, match, chop; var methods, types, m, t, out; types = #[]; for m in (obj.methods()) { if (tostr(m).(match)(f) != 0) types = types.add_elem(obj.method_access(m), ((("." + m) + "(") + ((obj.method_info(m))[1])) + ")"); } // hard-listing the types guarantee's their order out = []; for t in (['root, 'driver, 'public, 'protected, 'private, 'frob]) { if (!(types.contains(t))) continue; out += [(((tostr(t).capitalize()) + " methods matching \"") + f) + "\":"]; for m in (types[t]) out += [" " + m]; } return out; }; new method Replacing public method $programmer.parse_methodcmd_options() public method $programmer.parse_methodcmd_options() { arg syntax, args, @more; var o, opt, opts, out, r, l; [(o ?= []), (opts ?= [])] = more; o += [["pub?lic"], ["r?oot"], ["dr?iver"], ["pri?vate"], ["pro?tected"], ["no?override"], ["s?yncronized"], ["l?ocked"], ["na?tive"]]; opts = dict_union(#[['exists, 0], ['ignore, 0], ['mflags, []], ['mstate, 'public], ['error, 0]], opts); args = $parse_lib.getopt(args, o); if (!(args[1])) { out = []; for opt in (o) out += [" +|-" + (opt[1])]; (> .tell_error(syntax, ["Valid options:"] + (out.lcolumnize())) <); } r = (| $parse_lib.ref((args[1]).join()) |); if (!r) { opts = opts.add('error, "Invalid <object>.<method> reference."); opts = opts.add('ignore, 1); } if (!((r[4]).valid_ident())) { opts = opts.add('error, (((r[2]) + ".") + tostr(r[4])) + "() is not a valid method reference."); opts = opts.add('ignore, 1); } r = replace(r, 4, tosym(r[4])); if ((r[2]) && (!((r[2]).is_writable_by(this())))) { opts = opts.add('error, ("You cannot program " + (r[2])) + "."); opts = opts.add('ignore, 1); } if ((| (r[2]).find_method(r[4]) |) == (r[2])) { opts = opts.add('mflags, (r[2]).method_flags(r[4])); opts = opts.add('mstate, (r[2]).method_access(r[4])); opts = opts.add('exists, 1); } opts = opts.add('object, r[2]); opts = opts.add('method, r[4]); for opt in (args[2]) { switch (opt[1]) { case "pub?lic", "r?oot", "dr?iver", "pri?vate", "pro?tected": opts = opts.add('mstate, (opt[1]).to_symbol()); case "no?override", "s?yncronized": opts = opts.add('mflags, (opts['mflags]).setadd((opt[1]).to_symbol())); case "l?ocked": .tell("You cannot set the locked flag on a method."); case "n?ative": .tell("You cannot set the native flag on a method."); default: if (!(opt[1])) { .tell(("Unknown option: \"" + (opt[2])) + "\""); .tell("Valid options: " + ((o.slice(1)).to_english())); continue; } opts = opts.add((opt[1]).to_symbol(), [opt[3], opt[4]]); } } return opts; }; new method Replacing protected method $programmer.managed_cmd() protected method $programmer.managed_cmd() { arg cmdstr, cmd, args; var manager, managed, obj, out, len; (> .perms(caller(), 'command) <); if (!args) args = "."; manager = (| .match_environment(args) |); if (!manager) { manager = (| $user_db.search(args) |); if (!manager) return ("Unable to find \"" + args) + "\"."; } managed = manager.managed(); if (!managed) return (manager.namef('ref)) + " does not manage any objects."; out = [(manager.namef('ref)) + " manages:"]; len = (.linelen()) / 2; for obj in (managed) { if (!valid(obj)) { .tell((" ** invalid object (" + obj) + ") **"); continue; } out += [((" " + ((obj.namef('xref)).pad(len))) + " ") + ($object_lib.see_perms(obj, ["", ""]))]; } return out + ["---"]; }; new method Replacing protected method $programmer.list_cmd() protected method $programmer.list_cmd() { arg cmdstr, cmd, args; var i, pattern, ref, methods, s, def, method, opts, str, m, d, out, type; (> .perms(caller(), 'command) <); if ((opts = .get_setting("@list-options", $programmer))) { opts = (> $parse_lib.opt(opts, "n?umbers", "t?extdump") <); opts = union(args[3], opts[2]); } else { opts = args[3]; } if ((i = (| "n?umbers" in (opts.slice(1)) |)) && ((opts[i])[3])) type = 'numbered; else if ((i = (| "t?extdump" in (opts.slice(1)) |)) && ((opts[i])[3])) type = 'textdump; else type = 'normal; ref = args[1]; if ((ref[1]) == 'variable) return ((("The reference " + (ref[3])) + ",") + ((ref[4]) || "")) + " is not for a method."; if ((ref[1]) == 'object) return ("The reference " + (ref[3])) + " is not for a method."; if (!((ref[2]).has_flag('methods))) return .tell(("You don't have permission to find methods on " + (ref[2])) + "."); if (!((ref[2]).has_flag('code))) return .tell(("You don't have permission to list methods on " + (ref[2])) + "."); def = (| (ref[2]).find_method(tosym(ref[4])) |); if (def) { pattern = ref[4]; methods = [tosym(ref[4])]; } else { if (ref[4]) pattern = ref[4]; else pattern = .get_setting("match-default", $programmer); def = ref[3]; m = .get_setting("match-with", $programmer); methods = []; for method in (def.methods()) { if (tostr(method).(m)(pattern) != 0) methods += [method]; } if (!methods) return .tell((("No method found matching " + def) + ".") + pattern); } cmd = .get_setting("@program-options", $programmer); out = []; for method in (methods) { .ptell(.format_method(def, method, type, cmd), #[]); pause(); } }; new method Adding protected method $programmer._show__variables() protected method $programmer._show__variables() { arg obj, f, match, chop; var parent, out, v, line, len; out = []; len = .linelen(); for parent in (obj.data()) { if (valid(parent[1])) { out += [(((parent[1]) + " variables matching \"") + f) + "\":"]; if ((parent[1]).has_flag('variables, this())) { for v in (parent[2]) { if (tostr(v[1]).(match)(f) == 0) continue; line = ((" " + (v[1])) + ": ") + toliteral(v[2]); if (chop) line = line.chop(len); out += [line]; } } else { out += [" ** Permission Denied **"]; } } else { out += [($object_lib.get_name(parent[1])) + " Variables:"]; for v in (parent[2]) { if (tostr(v[1]).(match)(f) == 0) continue; line = ((" " + (v[1])) + ": ") + toliteral(v[2]); if (chop) line = line.chop(len); out += [line]; } } refresh(); } return out; }; new method Replacing protected method $programmer.eval_cmd() protected method $programmer.eval_cmd() { arg cmdstr, com, str; var result, adjust, vars, v, evalp, times, line, reg, obj, definer, ref, debug; (> .perms(caller(), 'command) <); evalp = .eval_prefix(); vars = (evalp.keys()).join(", "); v = (evalp.values()).join(); // clean it up str = strsed(str, "^;*", ""); // perform escape substitution if (str && ((str[1]) == "|")) str = substr(str, 2); else str = (> .eval_subs(str) <); // check for debug flags if ((reg = regexp(str, "^(trace|debug|profile|ops|opcodes) *;*(.*)$"))) { [debug, str] = reg; if (debug == "ops") debug = "opcodes"; debug = tosym(debug); } else { debug = 0; } // who are we evaluating as if ((reg = regexp(str, "^ *as +([^; ]+)"))) { catch ~objnf, ~namenf, ~ambig ref = $parse_lib.ref(reg[1]); with (> .tell_error("", (traceback()[1])[2]) <); obj = ref[2]; definer = ref[3]; str = strsed(str, "^ *as +([^; ]+)[ ;]+", ""); if ((!(definer.is_writable_by(this()))) || (!(obj.is_writable_by(this())))) return ("You do not have permission to evaluate on " + (reg[1])) + "."; if (!(obj.is(definer))) return (obj + " isn't a child of ") + definer; } else { obj = (definer = this()); } // are we just adjusting our offset? if (!str) { result = (> .evaluate(((("var " + vars) + ";") + v) + "return (> 1 <);", obj, definer, 'no_offset) <); result = replace(result[1], 1, ((result[1])[1]) - 1); if (eval_offset) line = strfmt("adjusted by %s ticks and %s.%6{0}r seconds.", (eval_offset[1]) - (result[1]), (eval_offset[2]) - (result[2]), abs((eval_offset[3]) - (result[3]))); else line = strfmt("set to %s ticks and %s.%6{0}r seconds.", @result); eval_offset = result; return "Eval offset " + line; } // format it if (match_begin(str, "var") && (reg = regexp(str, "var ([^;]+)"))) { str = strsed(str, "var ([^;]+);", ""); str = ((((("var " + vars) + ", ") + (reg.join(","))) + ";") + v) + str; } else if ("return" in str) { str = ((("var " + vars) + ";") + v) + str; } else { str = strsed(str, " *;* *$", ""); str = ((((("var " + vars) + ";") + v) + "return (> ") + str) + " <);"; } if (debug) { result = (> .evaluate(str, obj, definer, debug) <); debug = (| result[3] |); } else { result = (> .evaluate(str, obj, definer, debug) <); } [times, result] = result; // Display the errors, or the result. if ((result[1]) == 'errors) { .tell(result[2]); } else if ((result[1]) == 'traceback) { .tell((result[2]).fmt_tb()); line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]); if (times[2]) line += (" (" + ((times[1]) / (times[2]))) + " ticks per second)"; return line + " ]"; } else { if (type(result[2]) == 'objnum) .tell("=> " + ((| (result[2]).namef('xref) |) || (result[2]))); else .tell("=> " + toliteral(result[2])); if (debug) .tell(debug); line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]); if (times[2]) line += (" (" + ((times[1]) / (times[2]))) + " ticks per second)"; return line + " ]"; } }; new method Adding protected method $programmer._grep__full() protected method $programmer._grep__full() { arg regexp, objs; var obj, method, out, x, l, code; for obj in (objs) { if (!valid(obj)) continue; if (!(obj.has_flag('code))) { .tell(("You cannot read method code on " + obj) + ", skipping.."); continue; } out = []; for method in (obj.methods()) { code = obj.list_method(method); for x in [1 .. listlen(code)] { l = code[x]; if (match_regexp(l, regexp)) out += [(((((obj + ".") + method) + "() line ") + x) + ": ") + l]; refresh(); } refresh(); } if (out) .tell(out); refresh(); } return "---"; }; new method Replacing protected method $programmer.add_var_cmd() protected method $programmer.add_var_cmd() { arg cmdstr, cmd, args; var ref, value, syn; (> .perms(caller(), 'command) <); syn = "@av <object>,<variable>[=<value>]"; if (!args) (> .tell_error(syn, "Invalid obj,variable reference.") <); catch any ref = (> $parse_lib.ref(args.word(1)) <); with (> .tell_error(syn, (traceback()[1])[2]) <); if (((ref[1]) != 'variable) || (!(ref[4]))) (> .tell_error(syn, "Invalid obj,variable reference.") <); if (" " in args) { args = substr(args, (" " in args) + 1); if (args && ((args[1]) == "=")) args = substr(args, (" " in args) + 1); if (args) { value = .eval([("return " + args) + ";"]); if ((value[1]) == 'errors) (> .tell_error(syn, ("Unable to parse value \"" + args) + "\".") <); value = value[2]; } else { value = 0; } } else { value = 0; } catch any { (> (ref[3]).add_var(tosym(ref[4]), value) <); } with { if (error() in [~varexists, ~symbol]) return (traceback()[1])[2]; rethrow(error()); } return ((((("Object variable " + (ref[3])) + ",") + (ref[4])) + " added with value ") + value) + "."; }; new method Replacing protected method $programmer.show_cmd() protected method $programmer.show_cmd() { arg cmdstr, com, args; var show, match, i, chop, f, obj, out; (> .perms(caller(), 'command) <); if (((args[1])[1]) == 'object) show = ['method, 'variable]; else if ((args[1])[5]) show = [(args[1])[1], (args[1])[5]]; else show = [(args[1])[1]]; if ((i = "c?hop" in ((args[3]).slice(1)))) chop = ((args[3])[i])[3]; else chop = 1; if ((args[1])[4]) f = (args[1])[4]; else f = .get_setting("match-default", $programmer); match = .get_setting("match-with", $programmer); obj = (args[1])[3]; if (type(obj) == 'frob) return ["The target object was a frob. Please use @exam instead."]; .tell([((("Object: " + obj) + " [") + ((obj.size()).to_english())) + " bytes]", "Parents: " + ((obj.parents()).join(", "))]); if ('method in show) { if (!(obj.has_flag('methods, this()))) .tell(" ** No permission to list methods **"); else .tell(._show__methods(obj, f, match, chop)); } if ('variable in show) { if (!(obj.has_flag('variables, this()))) .tell(" ** No permission to show variables **"); else .tell(._show__variables(obj, f, match, chop)); } .tell("---"); }; update objvar Updating objvar $admin<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[["@del-t?ask|@kill", [["@del-t?ask|@kill", "*", "@del-t?ask|@kill <any>", 'del_task_cmd, #[[1, ['any, []]]]]]], ["@backup", [["@backup", "", "@backup", 'backup_cmd, #[]]]], ["@shutdown", [["@shutdown", "*", "@shutdown <any>", 'shutdown_cmd, #[[1, ['any, []]]]]]], ["@mojo", [["@mojo", "*", "@mojo <any>", 'mojo_cmd, #[[1, ['any, []]]]]]], ["@adjust|@promote", [["@adjust|@promote", "* to *", "@adjust|@promote <user> to <any>", 'adjust_cmd, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@new-password|@newpw?d", [["@new-password|@newpw?d", "*", "@new-password|@newpw?d <user>", 'new_password_cmd, #[[1, ['user, []]]]]]], ["@task?s", [["@task?s", "*", "@task?s <any>", 'tasks_cmd, #[[1, ['any, []]]]]]], ["@core", [["@core", "*", "@core <list object>", 'core_cmd, #[[1, ['list, ['object, []]]]]]]], ["@rehash-all", [["@rehash-all", "*", "@rehash-all <any:-p?urge>", 'rehash_all_cmd, #[[1, ['any_opt, ["p?urge"]]]]]]], ["@reap", [["@reap", "*", "@reap <any>", 'reap_cmd, #[[1, ['any, []]]]]]], ["@quota", [["@quota", "* to *", "@quota <object> to <any:+e?xempt>", 'quota_cmd, #[[1, ['object, []]], [3, ['any_opt, ["e?xempt"]]]]]]], ["@kick", [["@kick", "*", "@kick <any>", 'kick_cmd, #[[1, ['any, []]]]]]], ["@chman?age", [["@chman?age", "*", "@chman?age <any>", 'chmanage_cmd, #[[1, ['any, []]]]]]], ["@player-breakdown|@pb", [["@player-breakdown|@pb", "", "@player-breakdown|@pb", 'player_breakdown_cmd, #[]]]]]; new = #[["@del-t?ask|@kill", [["@del-t?ask|@kill", "*", "@del-t?ask|@kill <any>", 'del_task_cmd, #[[1, ['any, []]]]]]], ["@backup", [["@backup", "", "@backup", 'backup_cmd, #[]]]], ["@shutdown", [["@shutdown", "*", "@shutdown <any>", 'shutdown_cmd, #[[1, ['any, []]]]]]], ["@mojo", [["@mojo", "*", "@mojo <any>", 'mojo_cmd, #[[1, ['any, []]]]]]], ["@adjust|@promote", [["@adjust|@promote", "* to *", "@adjust|@promote <user> to <any>", 'adjust_cmd, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@new-password|@newpw?d", [["@new-password|@newpw?d", "*", "@new-password|@newpw?d <user>", 'new_password_cmd, #[[1, ['user, []]]]]]], ["@task?s", [["@task?s", "*", "@task?s <any>", 'tasks_cmd, #[[1, ['any, []]]]]]], ["@core", [["@core", "*", "@core <list object>", 'core_cmd, #[[1, ['list, ['object, []]]]]]]], ["@rehash-all", [["@rehash-all", "*", "@rehash-all <any:-p?urge>", 'rehash_all_cmd, #[[1, ['any_opt, ["p?urge"]]]]]]], ["@reap", [["@reap", "*", "@reap <any>", 'reap_cmd, #[[1, ['any, []]]]]]], ["@quota", [["@quota", "* to *", "@quota <object> to <any:+e?xempt>", 'quota_cmd, #[[1, ['object, []]], [3, ['any_opt, ["e?xempt"]]]]]]], ["@kick", [["@kick", "*", "@kick <any>", 'kick_cmd, #[[1, ['any, []]]]]]], ["@chman?age", [["@chman?age", "*", "@chman?age <any>", 'chmanage_cmd, #[[1, ['any, []]]]]]], ["@scour", [["@scour", "*", "@scour <any>", 'scour_cmd, #[[1, ['any, []]]]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$admin<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $admin; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); old method Deleting normal method $admin.player_breakdown_cmd() object $admin; eval { del_method('player_breakdown_cmd); }; old method Deleting normal method $admin.reap_list() object $admin; eval { del_method('reap_list); }; old method Deleting normal method $admin.reap_mail() object $admin; eval { del_method('reap_mail); }; old method Deleting normal method $admin.reap_user() object $admin; eval { del_method('reap_user); }; new method Adding public method $admin.scour_cmd() public method $admin.scour_cmd() { arg cmdstr, cmd, line; var allopts, opts, parse, comp, neg, match, list, start, end, obj, pos, found, out, i, x, y; // command requires mojo for full search, so check it (> .check_mojo() <); // check to see if arguments have been provided if (!line) return .tell("Syntax: @scour <scope> [{comparison}] [range] [options]"); // determine the scope of the search: method, variable, or setting if ((parse = line.regexp("\.([a-zA-Z0-9_]+)\((.*)\)"))) parse = (| ['method, ".", (parse[1]).to_symbol(), fromliteral(("[" + (parse[2])) + "]")] |); else if ((parse = line.regexp(",([a-zA-Z0-9_]+)"))) parse = (| ['variable, ",", (parse[1]).to_symbol()] |); else if ((parse = line.regexp(":([a-zA-Z0-9-]+)"))) parse = (| ['setting, ":", parse[1]] |); else return .tell("Scope parse failed."); // if provided, find the basis of comparison refresh(); comp = line.regexp("{(.+)}"); if (comp) { comp = comp[1]; // if (line[line.index("{") - 1] == "!") if ((line[stridx(line, "{") - 1]) == "!") neg = 1; } // parse options and determine the objects to be scoured refresh(); allopts = ["d?escend", "m?atch"]; opts = ($parse_lib.opt(line, @allopts))[2]; catch ~namenf { if ((pos = "d?escend" in (opts.slice(1)))) { start = $object_lib.to_dbref(((opts[pos])[4]).strip("'")); list = [start, @start.descendants()]; } else if ((| ([start, end] = line.regexp("([^ .]+) ?\.\. ?([^ .]+)")) |)) { [start, end] = map i in ([start, end]) to ($object_lib.to_dbref(i)); list = map i in [toint(start) .. toint(end)] to (refresh() && toobjnum(i)); list = filter i in (list) where (refresh() && valid(i)); } else { return .tell("You must specify a range of objects or an object from which to descend."); } } with { return .tell((traceback()[1])[2]); } if ((pos = "m?atch" in (opts.slice(1)))) { match = map i in ((allopts = ["r?egexp", "t?emplate", "e?quals"])) to (((opts[pos])[4]).match_template(i)); if (match[1]) match = 'regexp; else if (match[2]) match = 'match_template; else if (match[3]) match = 'equals; else return .tell((((opts[pos])[4]) + " is not a valid matching type: ") + (allopts.to_english())); } // defaults refresh(); match ?= 'regexp; // scours the database and makes comparisons .tell(["Beginning analysis...", "".pad(79, "-")]); for obj in (list) { refresh(); catch any { switch (parse[1]) { case 'method: i = toliteral(obj.(parse[3])(@parse[4])); if (comp) { if (neg ? i.(match)(comp) : (!i.(match)(comp))) continue; } found = 1; .tell([tostr(obj), " %20e %55e".format((parse[2]) + tostr(parse[3]), i)]); case 'variable: out = []; for x in (obj.data()) { refresh(); if (valid(x[1]) && ((parse[3]) in (((obj.data())[x[1]]).keys()))) { i = toliteral(((obj.data())[x[1]])[parse[3]]); if (comp) { if (neg ? i.(match)(comp) : (!i.(match)(comp))) continue; } out += [(" <" + (x[1])) + ">", " %20e %50e".format((parse[2]) + tostr(parse[3]), i)]; } } if (!out) continue; found = 1; .tell([tostr(obj), @out]); case 'setting: if ((parse[3]) in ((pos = obj.all_defined_settings()).keys())) { i = toliteral(obj.get_setting(parse[3], pos[parse[3]])); if (comp) { if (neg ? i.(match)(comp) : (!i.(match)(comp))) continue; } found = 1; .tell([tostr(obj), " %20e %55e".format((parse[2]) + (parse[3]), i)]); } continue; } } with { continue; } } if (!found) .tell("No matches found."); .tell(["".pad(79, "-"), "Finished."]); // $#Created: 22 Jul 98 20:09 $kirnamat }; new method Adding private method $admin._reap__user() private method $admin._reap__user() { arg str; var user, ans, managed, obj, reapq, nuke, name, keep; user = (| $user_db.search(str) |); if (!user) { catch any user = $object_lib.to_dbref(str); with return ("Unable to find user " + str) + "."; } if (!(> $parse_lib.ask(("Reap " + (user.namef('ref))) + "? [no] ") <)) return "Aborting reap."; managed = setremove(user.managed(), user); nuke = (keep = []); reapq = ["", ("Reap this object managed by " + (user.namef('ref))) + "? [yes] "]; for obj in (managed) { .tell(""); .tell($object_lib.format_object(obj, 0)); if ((> $parse_lib.ask(reapq, "(yes|y)", "yes") <)) nuke = setadd(nuke, obj); else keep = setadd(keep, obj); } if (nuke) { .tell(["WRT TST Object", "--- --- ------"]); for obj in (nuke) .tell(strfmt("%3r %3r %s", listlen(obj.writers('literal)), listlen(obj.trusted('literal)), obj.namef('ref))); .tell(""); if ((> $parse_lib.ask("Destroy these objects? [yes] ", "(yes|y)", "yes") <)) { for obj in (nuke) { // must have been nuked already if (!valid(obj)) next; name = obj.namef('ref); catch any { obj.destroy(); } with { .tell("--- While Destroying " + name); .tell_traceback(traceback()); } } } } for obj in (keep) .tell((("Changed Manager for " + (obj.namef('ref))) + " to ") + ($reaper.namef('ref))); if (!(> $parse_lib.ask(("Destroy " + (user.namef('ref))) + "? ") <)) return "Not destroying " + (user.namef('ref)); name = user.namef('ref); catch any { user.destroy(); } with { .tell("--- While Destroying " + name); .tell_traceback(traceback()); } return ("Done reaping " + name) + "."; }; new method Replacing protected method $admin.rehash_all_cmd() protected method $admin.rehash_all_cmd() { arg cmdstr, cmd, args; var purge, o, objs, list; (> .perms(caller(), 'command) <); (> .check_mojo() <); .tell("Rebuilding all caches.."); pause(); pause(); // go atomic, we do not want confused users trying to run commands that // do not exist... $sys.atomic(1); // purge everything if ((o = (| "p?urge" in ((args[2]).slice(1)) |))) purge = ((args[2])[0])[3]; else purge = 1; if (purge) { .tell("Purging caches.."); for o in ($command_cache.descendants()) { (| o.purge_cache() |); refresh(); } } // rehash non-general caches list = ($command_cache.children()).setremove($user_interfaces); list = ((list.mmap('descendants)).flatten()).compress(); .tell(("Rehashing " + listlen(list)) + " general caches."); for o in (list) { if (!(o.is_general_cache())) { (| o.rehash_cache() |); refresh(); } } $remote_cache.rehash_cache(); // re-init user clients objs = (| $user_db.connected() |) || [this()]; list = hash o in (objs) to ([(| o.location() |) || $void, 1]); for o in (objs + dict_keys(list)) { .tell("Initializing " + (o.namef('ref))); o.cache_client_init(); refresh(); } // ok, good... $sys.atomic(0); return "Done..."; }; new method Replacing protected method $admin.reap_cmd() protected method $admin.reap_cmd() { arg cmdstr, cmd, args; var opts, thresh, i; (> .perms(caller(), 'command) <); (> .check_mojo() <); [args, opts] = (> $parse_lib.opt(args, "t?ime", "m?ail") <); args = args.join(); if ((i = "t?ime" in (opts.slice(1)))) { catch any thresh = $time.from_english((opts[i])[4]); with return (traceback()[1])[2]; } if ("m?ail" in (opts.slice(1))) return ._reap__mail(args, thresh || (86400 * 7)); if (args) return (> ._reap__user(args) <); else return (> ._reap__list(thresh || ((86400 * 30) * 3)) <); }; new method Adding private method $admin._reap__list() private method $admin._reap__list() { arg thresh; var t, reap, u, tl, m, v, n, last; t = time(); reap = []; .tell([("--- Reap Possibilities (Not connected for " + ($time.to_english(thresh))) + ")", strfmt("E %21L %3l %10l %10l %10l %l", "User", "MNG", "Created", "Notified", "Last On", "Idle"), strfmt("- %21L %3l %10l %10l %10l %l", "----", "---", "-------", "-------", "-------", "----")]); for u in ($user.descendants()) { if ((u.connected()) || ((u.has_flag('core)) || (u.is($admin)))) continue; tl = (last = abs(u.connected_at())); if ((tl + thresh) > t) continue; m = ""; tl = t - tl; if (tl / 31449600) { v = tl / 31449600; m = (v + " yr") + ((v > 1) ? "s" : ""); tl = tl % 31449600; } if (tl / 2592000) { v = tl / 2592000; m += (((m ? " " : "") + v) + " mnth") + ((v > 1) ? "s" : ""); tl = tl % 2592000; } if (tl / 604800) { v = tl / 604800; m += (((m ? " " : "") + v) + " wk") + ((v > 1) ? "s" : ""); } if (!m) m = "newborn"; if (u._reap__notified()) n = $time.format("%e-%b-%y", u._reap__notified()); else n = ""; reap += [[last, strfmt("%s %21L %3l %10l %10l %10l %l", ((u.get_setting("rl-email", $user_info))[2]) ? " " : "!", u.name(), listlen(u.managed()), $time.format("%e-%b-%y", u.created_on()), n, $time.format("%e-%b-%y", last), m)]]; } .tell(((reap.sort()).slice(2)).reverse()); return "---"; }; new method Adding private method $admin._reap__mail() private method $admin._reap__mail() { arg str, interval; var email, msg, subj, ps, po, user; user = (| $user_db.search(str) |); if (!user) { catch any user = $object_lib.to_dbref(str); with return ("Unable to find user " + str) + "."; } email = user.user_info("email"); ps = (user.gender()).pronoun('ps); po = (user.gender()).pronoun('po); subj = ("[" + ($motd.server_name())) + "] IMMINENT USER REAPING"; msg = (((((((((("Your user account " + (user.namef('ref))) + " on ") + ($motd.server_name())) + " is slated for reaping, possibly due to inactivity. If you do not connect within ") + ($time.to_english(interval))) + " ") + ps) + " and all objects managed by ") + po) + " will be destroyed. This is an automatic message sent to the supplied email address. If this message is in error simply discard it.").wrap_lines(75); .tell("---"); .tell("To: " + email); .tell("Subject: " + subj); .tell(""); .tell(msg); .tell("---"); if (!(> $parse_lib.ask("Send this email message? [yes] ", "(yes|y)", "yes") <)) return "Message not sent."; catch any { $smtp.sendmail('admin, email, subj, msg); } with { .tell_traceback(traceback()); return "** Unable to send message"; } user.set_reap_notified(time()); return "Message sent."; }; update objvar Updating objvar $introtut_mailbox<$root>,settings public method $root.__upgrade_set_var() { var old, new; old = #[["closable", 1], ["closed", 0]]; new = #[["closable", 1], ["closed", 1]]; catch any { dblog("__upgrade_handle_var(1, settings)"); settings = .__upgrade_handle_var(1, "$introtut_mailbox<$root>,settings", old, settings, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $introtut_mailbox; eval { .__upgrade_set_var(); }; object $root; eval { del_method('__upgrade_set_var); }; // old public method $root.__upgrade_set_var(); new method Replacing public method $trash.did_arrive() public method $trash.did_arrive() { arg mover, place; var msg; (> pass(place) <); (| (items = items.add(sender(), time())) |); }; add objvar Adding objvar $realm_settings<$root>,credit object $realm_settings; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; update objvar Updating objvar $place<$root>,flags object $place; var $root flags = ['methods, 'code, 'fertile, 'variables, 'core, 'general_cache]; update objvar Updating objvar $place<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[]; new = #[["fribble", [["fribble", "*", "fribble <any>", 'fribble_cmd, #[[1, ['any, []]]]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$place<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $place; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); new method Replacing public method $place.will_arrive() public method $place.will_arrive() { arg mover, old_place; (> pass(mover, old_place) <); if (restrict_entry && ((!(mover.is($path))) && ((mover != $housekeeper) && ((!(.trusts(mover))) && ((| (mover.location()) != this() |) && (!(restrict_entry.try(mover)))))))) throw(~locked, ((((.name()).capitalize()) + " is locked to ") + (restrict_entry.lock_name('place))) + "."); }; new method Replacing public method $place.will_attach() public method $place.will_attach() { arg type, @by_whom; [(by_whom ?= sender())] = by_whom; if ((.realm()).is_buildable_by(by_whom)) return 1; if ((| .trusts(by_whom) |)) return 1; if (.get_setting("public-home", $place)) return 1; throw(~perm, "Place is not publicly extendable."); }; update objvar Updating objvar $the_pit<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[]; new = #[["zibble", [["zibble", "*", "zibble <any>", 'foo_cmd, #[[1, ['any, []]]]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$the_pit<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $the_pit; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); add objvar Adding objvar $tutorial<$command_cache>,commands object $tutorial; var $command_cache commands = 0; add objvar Adding objvar $tutorial<$command_cache>,shortcuts object $tutorial; var $command_cache shortcuts = 0; add objvar Adding objvar $introtut_speaking<$event_handler>,hooked object $introtut_speaking; var $event_handler hooked = #[]; add objvar Adding objvar $introtut_nonverbal<$event_handler>,hooked object $introtut_nonverbal; var $event_handler hooked = #[]; add objvar Adding objvar $introtut_look<$event_handler>,hooked object $introtut_look; var $event_handler hooked = #[]; add objvar Adding objvar $introtut_gender<$event_handler>,hooked object $introtut_gender; var $event_handler hooked = #[]; add objvar Adding objvar $introtut_env<$event_handler>,hooked object $introtut_env; var $event_handler hooked = #[]; add objvar Adding objvar $introtut_moving<$event_handler>,hooked object $introtut_moving; var $event_handler hooked = #[]; add objvar Adding objvar $introtut_help_short<$event_handler>,hooked object $introtut_help_short; var $event_handler hooked = #[]; add objvar Adding objvar $introtut_help_nav<$event_handler>,hooked object $introtut_help_nav; var $event_handler hooked = #[]; update objvar Updating objvar $realm<$root>,flags object $realm; var $root flags = ['methods, 'code, 'variables, 'core, 'fertile]; add objvar Adding objvar $realm<$root>,credit object $realm; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; new method Adding public method $realm.is_buildable_by() public method $realm.is_buildable_by() { arg whom; if (.trusts(whom)) return 1; else if (this() == definer()) return 0; else return (parents()[1]).is_buildable_by(whom); }; add objvar Adding objvar $mail_postmaster<$mail_list>,last_received_on object $mail_postmaster; var $mail_list last_received_on = 0; update objvar Updating objvar $antisocial<$foundation>,msgs object $antisocial; var $foundation msgs = #[["ice", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pours a bucket of ice water over ", <$generator, ["who", [], [], 'gen_who]>, "'s head."], #[]]>], ["actor", <$ctext_frob, [["You pour a bucket of ice water over ", <$generator, ["who", [], [], 'gen_who]>, "'s head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pours a bucket of ice water over your head."], #[]]>]]], ["eye", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " eyes ", <$generator, ["who", [], [], 'gen_who]>, " warily."], #[]]>], ["actor", <$ctext_frob, [["You eye ", <$generator, ["who", [], [], 'gen_who]>, " warily."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " eyes you warily."], #[]]>]]], ["pat", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pats ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["actor", <$ctext_frob, [["You pat ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pats you onna head."], #[]]>]]], ["pummel", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pummels ", <$generator, ["who", [], [], 'gen_who]>, " into a milky white substance."], #[]]>], ["actor", <$ctext_frob, [["You pummel ", <$generator, ["who", [], [], 'gen_who]>, " into a milky white substance."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pummels you into a milky white substance. ouch."], #[]]>]]], ["prod", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " prods ", <$generator, ["who", [], [], 'gen_who]>, " with a cowpoke."], #[]]>], ["actor", <$ctext_frob, [["You prod ", <$generator, ["who", [], [], 'gen_who]>, " with a cowpoke."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " prods you with a cowpoke. ouch."], #[]]>]]], ["kick", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " kicks ", <$generator, ["who", [], [], 'gen_who]>, " firmly in the kiester."], #[]]>], ["actor", <$ctext_frob, [["You kick ", <$generator, ["who", [], [], 'gen_who]>, " firmly in the kiester."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " kicks you firmly in the kiester."], #[]]>]]], ["hug", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bear hugs ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You bear hug ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bear hugs you. oif."], #[]]>]]], ["beat", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["actor", <$ctext_frob, [["You pull out a stick and beat the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats you repeatedly."], #[]]>]]], ["hit", #[["general", <$ctext_frob, [["Boldly, ", <$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["actor", <$ctext_frob, [["Boldly, you pull out a stick and beat the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["who", <$ctext_frob, [["Boldly, ", <$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats you repeatedly. oif."], #[]]>]]], ["peer", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " peers suspiciously at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You peer suspiciously at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " peers suspiciously at you."], #[]]>]]], ["bite", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " BITES ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You BITE ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " BITES you."], #[]]>]]], ["nip", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " nips at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You nip at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " nips at you."], #[]]>]]], ["poke", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " firmly jabs ", <$generator, ["pro", [["actor", 1]], ["pp"], 'gen_pro]>, " index finger into ", <$generator, ["who", [], [], 'gen_who]>, "'s ribs."], #[]]>], ["actor", <$ctext_frob, [["You jab your index finger firmly into ", <$generator, ["who", [], [], 'gen_who]>, "'s ribs."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " firmly jabs ", <$generator, ["pro", [["actor", 1]], ["pp"], 'gen_pro]>, " index finger into your ribs. oif."], #[]]>]]], ["bonk", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " maliciously bonks ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["actor", <$ctext_frob, [["You maliciously bonk ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " maliciously bonks you onna head. oif."], #[]]>]]], ["fart", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " farts in ", <$generator, ["who", [], [], 'gen_who]>, "'s general direction."], #[]]>], ["actor", <$ctext_frob, [["You fart in ", <$generator, ["who", [], [], 'gen_who]>, "'s general direction."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " farts in your general direction."], #[]]>]]], ["bounce", #[["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bounces towards you obnoxiously!"], #[]]>], ["general", <$ctext_frob, [["You bounce obnoxiously towards ", <$generator, ["who", [], [], 'gen_who]>, "!"], #[]]>]]]]; update objvar Updating objvar $antisocial<$has_commands>,local public method $has_commands.__upgrade_set_var() { var old, new; old = #[["ice", [["ice", "*", "ice <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["eye", [["eye", "*", "eye <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["fart", [["fart", "*", "fart <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["kick", [["kick", "*", "kick <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pat", [["pat", "*", "pat <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pummel", [["pummel", "*", "pummel <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["poke", [["poke", "*", "poke <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["prod", [["prod", "*", "prod <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bonk", [["bonk", "*", "bonk <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hug", [["hug", "*", "hug <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hit", [["hit", "*", "hit <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["peer", [["peer", "*", "peer <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bite", [["bite", "*", "bite <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["nip", [["nip", "*", "nip <object>", 'anti_cmd, #[[1, ['object, []]]]]]]]; new = #[["ice", [["ice", "*", "ice <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["eye", [["eye", "*", "eye <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["fart", [["fart", "*", "fart <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["kick", [["kick", "*", "kick <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pat", [["pat", "*", "pat <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pummel", [["pummel", "*", "pummel <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["poke", [["poke", "*", "poke <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["prod", [["prod", "*", "prod <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bonk", [["bonk", "*", "bonk <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hug", [["hug", "*", "hug <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hit", [["hit", "*", "hit <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["peer", [["peer", "*", "peer <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bite", [["bite", "*", "bite <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["nip", [["nip", "*", "nip <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bounce", [["bounce", "*", "bounce <object>", 'anti_cmd, #[[1, ['object, []]]]]]]]; catch any { dblog("__upgrade_handle_var(1, local)"); local = .__upgrade_handle_var(1, "$antisocial<$has_commands>,local", old, local, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $antisocial; eval { .__upgrade_set_var(); }; object $has_commands; eval { del_method('__upgrade_set_var); }; // old public method $has_commands.__upgrade_set_var(); update objvar Updating objvar $antisocial<$foundation>,defined_msgs object $antisocial; var $foundation defined_msgs = #[["ice", #[['branches, ["general", "actor", "who"]]]], ["eye", #[['branches, ["general", "actor", "who"]]]], ["pat", #[['branches, ["general", "actor", "who"]]]], ["pummel", #[['branches, ["general", "actor", "who"]]]], ["prod", #[['branches, ["general", "actor", "who"]]]], ["kick", #[['branches, ["general", "actor", "who"]]]], ["hug", #[['branches, ["general", "actor", "who"]]]], ["beat", #[['branches, ["general", "actor", "who"]]]], ["hit", #[['branches, ["general", "actor", "who"]]]], ["peer", #[['branches, ["general", "actor", "who"]]]], ["bite", #[['branches, ["general", "actor", "who"]]]], ["nip", #[['branches, ["general", "actor", "who"]]]], ["poke", #[['branches, ["general", "actor", "who"]]]], ["bonk", #[['branches, ["general", "actor", "who"]]]], ["fart", #[['branches, ["general", "actor", "who"]]]], ["bounce", #[['branches, ["general", "actor", "who"]]]]]; clear objvar Clearing objvar $settings_ui<$command_cache>,commands object $settings_ui; old var $command_cache commands; clear objvar Clearing objvar $settings_ui<$command_cache>,shortcuts object $settings_ui; old var $command_cache shortcuts; update objvar Updating objvar $smtp_connection<$root>,flags object $smtp_connection; var $root flags = ['core, 'variables, 'methods, 'code]; new method Replacing public method $smtp.get_email_address() public method $smtp.get_email_address() { arg type; var email, r, host; if (type(type) == 'objnum) (| (type = type.name()) |); if (type(type) != 'string) type = tostr(type); return .format_email_address((| .parse_recipient(type) |) || $mail_admin); }; update objvar Updating objvar $login_daemon<$root>,defined_settings public method $root.__upgrade_set_var() { var old, new; old = #[["creation-disabled-msg", #[]], ["creation-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]]; new = #[["creation-disabled-msg", #[]], ["creation-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["guests-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["guests-disabled-msg", #[]]]; catch any { dblog("__upgrade_handle_var(3, defined_settings)"); defined_settings = .__upgrade_handle_var(3, "$login_daemon<$root>,defined_settings", old, defined_settings, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $login_daemon; eval { .__upgrade_set_var(); }; object $root; eval { del_method('__upgrade_set_var); }; // old public method $root.__upgrade_set_var(); update objvar Updating objvar $login_daemon<$root>,settings public method $root.__upgrade_set_var() { var old, new; old = #[["creation-disabled-msg", "Sorry, character creation is disabled."], ["creation-allowed", 1]]; new = #[["creation-disabled-msg", "Sorry, character creation is disabled."], ["creation-allowed", 1], ["guests-allowed", 1], ["guests-disabled-msg", "Sorry, guests are disabled."]]; catch any { dblog("__upgrade_handle_var(1, settings)"); settings = .__upgrade_handle_var(1, "$login_daemon<$root>,settings", old, settings, new); } with { dblog("ERROR: " + traceback()[1][2]); } }; object $login_daemon; eval { .__upgrade_set_var(); }; object $root; eval { del_method('__upgrade_set_var); }; // old public method $root.__upgrade_set_var(); update objvar Updating objvar $smtp_daemon<$smtp_daemon>,msg_id object $smtp_daemon; var $smtp_daemon msg_id = 352; new method Replacing frob method $thing_frob.match_name() frob method $thing_frob.match_name() { arg this, str; var t, m; if (!str) return 0; if ((m = match_begin((this['name])[2], str))) return 1; if (this.contains('name_templates)) { for t in (this['name_templates]) { if ((m = match_template(str, t))) return 1; } } return 0; }; new method Replacing frob method $wearable_frob.discard() frob method $wearable_frob.discard() { arg data; if (!(data['worn])) pass(data); if (data['worn]) (data['worn]).shed((<this(), data>)); }; update objvar Updating objvar $lock_frob<$lock_frob>,lock_types object $lock_frob; var $lock_frob lock_types = [["inside", $inside_lock_frob], ["indirect", $indirect_lock_frob], ["owner", #-1692], ["carry", $carry_lock_frob], ["parent", $parent_lock_frob]]; add objvar Adding objvar $trie<$root>,credit object $trie; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; new method Replacing public method $trie.to_dict() public method $trie.to_dict() { arg trie, @prefix; var n, i, dict; // This function will only convert single-valued tries (such as were // probably obtained from dictionaries [(prefix ?= "")] = prefix; dict = (trie[1]) ? #[[prefix + ((trie[1])[1]), (trie[1])[2]]] : #[]; if (trie[2]) { for i in [1 .. (trie[2]).length()] dict = dict_union(dict, .to_dict(trie[2 + i], prefix + ((trie[2])[i]))); refresh(); } return dict; }; new method Replacing public method $ctext_frob.append() public method $ctext_frob.append() { arg this, new, @br; var data, tmp, vars; data = this[1]; vars = this[2]; if (br) { switch (br[1]) { case "p": data += [(<$format, ["p", [], [], 'do_p]>)]; case "br": data += [(<$format, ["br", [], [], 'do_br]>)]; default: data += [$format.new_tag(br[1], [], [])]; } } if (type(new) == 'list) { data += new; } else if ((type(new) == 'frob) && (class(new) == $ctext_frob)) { data += new._ctext(); vars = dict_union(vars, new.vars()); } else { data += [new]; } return (<this(), [data, vars]>); }; new method Replacing public method $ctext_frob.uncompile() public method $ctext_frob.uncompile() { arg this; var vars; vars = this[2]; if (!(| vars['uncompiler] |)) vars = dict_add(vars, 'uncompiler, $uncompiler); vars = dict_union(vars, (vars['uncompiler]).init()); return ((vars['uncompiler])._eval_ctext(this[1], vars))[1]; }; new method Replacing public method $ctext_frob.set_vars() public method $ctext_frob.set_vars() { arg this, new; var vars, key; return (<this(), [this[1], dict_union(this[2], new)]>); vars = this[2]; for key in (new.keys()) vars = dict_add(vars, key, new[key]); return (<this(), [this[1], vars]>); }; new method Replacing public method $ctext_frob.eval_ctext() public method $ctext_frob.eval_ctext() { arg this; var data, vars; vars = this[2]; vars = dict_add(vars, 'time, 'pre); if (!(| vars['sender] |)) vars = dict_add(vars, 'sender, sender()); if (!(| vars['evaluator] |)) vars = dict_add(vars, 'evaluator, $bs_eval); vars = dict_union(vars, (vars['evaluator]).init()); return .new_with(@(vars['evaluator])._eval_ctext(this[1], vars)); }; new method Replacing public method $ctext_frob.format() public method $ctext_frob.format() { arg this; var vars; vars = this[2]; vars = dict_add(vars, 'time, 'post); if (!(| vars['receiver] |)) vars = dict_add(vars, 'receiver, sender()); if (!(| vars['evaluator] |)) vars = dict_add(vars, 'evaluator, $bs_eval); if (!(| vars['formatter] |)) vars = dict_add(vars, 'formatter, $plain_format); vars = dict_union(vars, (vars['formatter]).init()); return (vars['formatter]).format(this[1], vars); }; add objvar Adding objvar $rtree<$root>,credit object $rtree; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; add objvar Adding objvar $connection_interface<$command_cache>,commands object $connection_interface; var $command_cache commands = 0; add objvar Adding objvar $connection_interface<$command_cache>,shortcuts object $connection_interface; var $command_cache shortcuts = 0; new method Replacing protected method $login_interface.connect_guest_cmd() protected method $login_interface.connect_guest_cmd() { arg cmdstr, cmd, args; var syn, msg, c, email, name, result, semail, user; if (!($login_daemon.get_setting("guests-allowed", $login_daemon))) return (> .tell_error("", $login_daemon.get_setting("guests-disabled-msg", $login_daemon)) <); syn = cmd + " <your name> <your email>"; semail = $smtp.get_email_address('login); args = args.explode(); c = .connection(); if ((args.length()) < 2) (> .tell_error(syn) <); name = (args.subrange(1, (args.length()) - 1)).join(); email = args[args.length()]; if ($sys.validate_email_addresses()) { catch any { .print("Verifying Email Address.."); msg = $smtp.verify_email_address(email); .print("SMTP Response: " + (msg.join(" "))); } with { .print("Aborting: " + ((traceback()[1])[2])); return; } } catch any user = (> $sys.create_user(name, 0, email, 'anonymous_user_class) <); with (> .tell_error(syn, (traceback()[1])[2], "If there is a problem contact: " + semail) <); c.change_interface(user); }; new method Replacing protected method $login_interface.help_cmd() protected method $login_interface.help_cmd() { arg cmdstr, cmd; .print($motd.connect_help()); if (!($login_daemon.get_setting("creation-allowed", $login_daemon))) .print(["", "NOTE: User creation is disabled, connect as a guest first."]); }; update objvar Updating objvar $http_interface<$http_interface>,info object $http_interface; var $http_interface info = #[['generate, 'change], ['script_name, "/aredit/change"], ['path_info, "/"], ['directory_object, $directories], ['lock_object, 0]]; add objvar Adding objvar $http_interface<$root>,credit object $http_interface; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; new method Replacing public method $http_interface.parse_line() public method $http_interface.parse_line() { arg line; var match, URI; if (!method) { if (!line) return; line = explode(line); if (listlen(line) != 3) { (.connection()).write(.response(400, "HTTP/0.9 not supported.")); (.connection()).close(); return; } if ((match = regexp(line[1], "^(GET|HEAD|POST)$"))) { info = #[['URI, line[2]]]; method = match[1]; } else { info = #[['URI, line[2]]]; .respond(.response(405, ("Method: \"" + (line[1])) + "\".")); (.connection()).close(); return; } http = line[3]; } else if (line) { if ((match = regexp(line, "^([^:]+): *(.+)$"))) { if (((match[1]) == "Connection") && ((match[2]) == "Keep-Alive")) keep_alive = 1; else if ((match[1]) == "Authorization") .process_auth_info(match[2]); else header = header.add_elem(@match); } } else { // parse the URI match = $http_lib.explode_url(info['URI]); info = dict_union(info, match[1]); args = match[2]; catch any { (> .(tosym("http_method_" + method))() <); } with { if (error() != ~stop) .respond($parse_lib.html_traceback(traceback(), (status = 500))); } } }; new method Replacing protected method $http_interface.http_method_POST() protected method $http_interface.http_method_POST() { var len, body, part; len = (| header["Content-Length"] |); if ((len == ~keynf) || (!len)) (> .respond(.response(400, "No Content-Length.")) <); body = (.connection()).handle_POST_input(toint(len[1])); // handle this differently in normal situations for part in (body) args = dict_union(args, $http_lib.explode_http_encoding(part)); .http_method_GET(); }; new method Adding public method $http_interface.info() public method $http_interface.info() { return info; }; clear objvar Clearing objvar $pop3_interface<$pop3_interface>,messages object $pop3_interface; old var $pop3_interface messages; old method Deleting normal method $pop3_interface.message_size() object $pop3_interface; eval { del_method('message_size); }; old method Deleting normal method $pop3_interface.format_rfc822() object $pop3_interface; eval { del_method('format_rfc822); }; old method Deleting normal method $pop3_interface.unique_id() object $pop3_interface; eval { del_method('unique_id); }; new method Replacing protected method $pop3_interface.uidl_cmd() protected method $pop3_interface.uidl_cmd() { arg argstr; var x; (> .check_state("UIDL", 'transaction) <); if (argstr) { (> .check_valid_message((x = toint(argstr))) <); .print((("+OK " + x) + " ") + ((mail_objects[x]).unique_id())); } else { .print("+OK"); for x in [1 .. mail_objects.length()] { if (!(x in deleted)) .print((x + " ") + ((mail_objects[x]).unique_id())); } .print("."); } }; new method Adding protected method $pop3_interface.mailbox_size() protected method $pop3_interface.mailbox_size() { var x; return map x in (mail_objects) to (x.rfc822_size()).sum(); }; new method Replacing protected method $pop3_interface.top_cmd() protected method $pop3_interface.top_cmd() { arg argstr; var args, m, n, x, b; (> .check_state("TOP", 'transaction) <); if (((args = argstr.explode()).length()) != 2) throw(~stop, "-ERR command needs two arguments"); if ((n = toint(args[2])) < 0) throw(~stop, "-ERR second argument must be a non-negative integer"); (> .check_valid_message((m = toint(args[1]))) <); .print("+OK"); for x in ((mail_objects[m]).format_rfc822()) { if (x) .print(((x[1]) == ".") ? ("." + x) : x); else .print(x); if (b) { if (--n <= 0) break; } else if (!x) { b++; } } .print("."); }; new method Replacing protected method $pop3_interface.retr_cmd() protected method $pop3_interface.retr_cmd() { arg argstr; var msgnum, x; (> .check_state("RETR", 'transaction) <); (> .check_valid_message((msgnum = toint(argstr))) <); .print(("+OK " + ((mail_objects[msgnum]).rfc822_size())) + " octets"); for x in ((mail_objects[msgnum]).format_rfc822()) { refresh(); if (!x) .print(x); else .print(((x[1]) == ".") ? ("." + x) : x); } .print("."); }; new method Replacing protected method $pop3_interface.check_valid_message() protected method $pop3_interface.check_valid_message() { arg num; if ((num < 1) || (num > (mail_objects.length()))) throw(~stop, ("-ERR no such message, only " + (mail_objects.length())) + " messages in maildrop"); else if (num in deleted) throw(~stop, "-ERR ", x, " refers to a deleted message"); }; new method Replacing protected method $pop3_interface.pass_cmd() protected method $pop3_interface.pass_cmd() { arg argstr; var x; (> .check_state("USER", 'authorization) <); if (!maildrop) throw(~stop, "-ERR issue USER command first"); if (maildrop.check_password(argstr)) { catch any mail_objects = maildrop.mail(); with throw(~stop, "-ERR could not open maildrop"); state = 'transaction; .print(((((("+OK " + (maildrop.namef('ref))) + " has ") + (mail_objects.length())) + " messages (") + (.mailbox_size())) + " octets)"); } else { throw(~stop, "-ERR authentication failed"); } }; new method Replacing protected method $pop3_interface.list_cmd() protected method $pop3_interface.list_cmd() { arg argstr; var x, m; (> .check_state("LIST", 'transaction) <); if (argstr) { (> .check_valid_message((x = toint(argstr))) <); .print("+OK " + ((mail_objects[x]).rfc822_size())); } else { .print(((("+OK " + ((m = .live_messages()).length())) + " messages (") + (.mailbox_size())) + " octets)"); for x in [1 .. mail_objects.length()] { if (!(x in deleted)) .print((x + " ") + ((mail_objects[x]).rfc822_size())); } .print("."); } }; new method Replacing protected method $pop3_interface.rset_cmd() protected method $pop3_interface.rset_cmd() { arg argstr; (> .check_state("RSET", 'transaction) <); deleted = []; .print(((("+OK maildrop has " + (mail_objects.length())) + " messages (") + (.mailbox_size())) + " octets)"); }; new method Replacing protected method $pop3_interface.stat_cmd() protected method $pop3_interface.stat_cmd() { arg argstr; var x, m; (> .check_state("STAT", 'transaction) <); .print((("+OK " + ((m = .live_messages()).length())) + " ") + (.mailbox_size())); }; new method Replacing protected method $pop3_interface.live_messages() protected method $pop3_interface.live_messages() { var x, r; r = []; for x in [1 .. mail_objects.length()] { if (!(x in deleted)) r += [mail_objects[x]]; } return r; }; new method Replacing public method $mail_message.add_reader(): nooverride public method $mail_message.add_reader(): nooverride { arg who; if (!($mail_lib.has_mail_perms(caller()))) (> .perms(sender()) <); readers = setadd(readers, who); }; new method Replacing public method $mail_message.send() public method $mail_message.send() { arg @recips; var r, valid, invalid, from; if (!($mail_lib.has_mail_perms(caller()))) (> .perms(sender()) <); if (delivered) throw(~delivered, "This mail has already been delivered."); if (!recips) recips = .recipients(); if (((recips.length()) == 1) && ((recips[1]) == $no_one)) throw(~norcpt, "No recipients specified."); // Cache RFC822 size .rfc822_size(); valid = []; invalid = []; for r in (recips) { if (r.has_ancestor($mail_list)) valid += [r]; else invalid += [r]; } if (invalid) throw(~invrcpt, "Invalid mail recipients: " + (invalid.mmap('name)), invalid); recips = valid; invalid = []; // ok, now that we have that cleared up, lets set pertinent info... .set_time(time()); if ((!(.from())) || (sender() != $no_one)) .set_from(sender()); // and now to finalize the recipients for r in (recips) { if ((r.list_is_inet()) && (!frominet)) { from = (sender().user_info("name")) || (sender().name()); from += (" <" + (sender().user_info("email"))) + ">"; r = r.get_setting("inet-list", $mail_list); $smtp.sendmail(from, r, header['subj], .body()); delivered++; } else if (r.list_is_sendable_by(sender())) { r.add_mail(); .add_recipient(r); delivered++; } else { invalid += [r]; } } if (!delivered) throw(~delivered, "Unable to deliver message."); return invalid; }; new method Replacing public method $mail_message.add_recipient(): nooverride public method $mail_message.add_recipient(): nooverride { arg whom; var current; if (!($mail_lib.has_mail_perms(caller()))) (> .perms(sender()) <); current = (| header['rcpt] |) || []; if ((| whom in current |)) throw(~type, "Recipient is already in the list of recipients"); header = dict_add(header, 'rcpt, setadd(current, whom)); }; new method Replacing public method $mail_message.format_rfc822() public method $mail_message.format_rfc822() { var out, x, line; if (!($mail_lib.has_mail_perms(caller()))) (> .perms(sender()) <); if (.meta()) { out = []; for x in (.meta()) out += [((x[1]) + ": ") + (x[2])]; } else { out = ["Date: " + ($time.format("%a, %e %b %Y %T %Z", .time()))]; out += ["From: " + ($smtp.get_email_address(.from()))]; out += ["To: " + (((.recipients()).omap($smtp, 'get_email_address)).join(", "))]; out += [((("Message-ID: <" + (.unique_id())) + "@") + ($sys.server_info('server_hostname))) + ">"]; out += ["Subject: " + (.subject())]; out += ["X-UIDL: " + (.unique_id())]; } out += [""]; for line in (.body()) { refresh(); if ((line.length()) > 79) out += line.wrap_lines(75); else out += [line]; } return out; }; new method Adding public method $mail_message.unique_id() public method $mail_message.unique_id() { if (!($mail_lib.has_mail_perms(caller()))) (> .perms(sender()) <); if (!(header.contains('uidl))) header = header.add('uidl, $mail_lib.generate_unique_id(this())); return header['uidl]; }; update objvar Updating objvar $note<$root>,flags object $note; var $root flags = ['core, 'fertile, 'code, 'methods, 'variables]; add objvar Adding objvar $page<$root>,credit object $page; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $page_home_index<$root>,credit object $page_home_index; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $page_bin_index<$root>,credit object $page_bin_index; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; new method Replacing public method $page_bin_index._show_object() public method $page_bin_index._show_object() { arg obj, what; var top, middle, bottom, desc, alert, nalert, line; middle = (bottom = []); top = [("<h1>" + (._make_object_href(obj))) + "</h1>"]; // CORENOTE: merge this with a central location (likely $directories) alert = ("<p><font size=\"+1\" color=\"#" + (($cml_color.get_color("red"))[1])) + "\"><b>"; nalert = "</b></font>"; top += ["<table>"]; top += [("<tr><td><b>Perms</b>:</td><td>" + (((obj.flags()).prefix("+")).join())) + "</td></tr>", ("<tr><td><b>Size</b>:</td><td>" + ((obj.size()).to_english())) + " bytes (on disk)</td></tr>", ("<tr><td><b>Manager</b>:</td><td>" + (._make_object_href(obj.manager()))) + "</td></tr>", ._show_header_objs(obj.writers('literal), "Writer"), ._show_header_objs(obj.parents(), "Parent")]; if (obj.has_ancestor($located)) top += [("<tr><td><b>Location</b>:</td><td>" + (._make_object_href(obj.location()))) + "</td></tr>"]; if (obj.help_node()) top += [((("<tr><td><b>Associated Help</b>:</td><td><a href=\"/bin/help?node=" + (obj.help_node())) + "\">") + (obj.help_node())) + "</a></td></tr>"]; top += [("<tr><td><b>Credit</b>:</td><td>" + join(obj.credit(), "<br>")) + "</td></tr>"]; top += ["</table><p><hr size=1 noshade><p>"]; if (obj.has_ancestor($described)) { if (what['desc]) { bottom += ["<p><b>Description</b>:<blockquote><pre>"]; desc = obj.prose(); switch (type(desc)) { case 'frob: for line in (desc.uncompile()) bottom += line.wrap_lines(79, " "); case 'list: bottom += desc; case 'string: bottom += [desc]; } bottom += ["</pre></blockquote>"]; middle += [._make_show_object_href("Hide Description", obj, what, 'desc, 0)]; } else { middle += [._make_show_object_href("Show Description", obj, what, 'desc, 1)]; } top += ["</td></tr>"]; } if (what['methods]) { if (!(obj.has_flag('methods, this()))) bottom += [(alert + "** No permission to List Methods **") + nalert]; else bottom += (["<p><b>Methods:</b><blockquote><pre>"] + (._show_methods(obj))) + ["</pre></blockquote>"]; middle += [._make_show_object_href("Hide Methods", obj, what, 'methods, 0)]; } else { middle += [._make_show_object_href("List Methods", obj, what, 'methods, 1)]; } if (what['vars]) { if (!(obj.has_flag('variables, this()))) bottom += [(alert + "** No permission to Show Variables **") + nalert]; else bottom += (["<p><b>Variables:</b><blockquote><pre>"] + (._show_variables(obj))) + ["</pre></blockquote>"]; middle += [._make_show_object_href("Hide Variables", obj, what, 'vars, 0)]; } else { middle += [._make_show_object_href("Show Variables", obj, what, 'vars, 1)]; } return (((top + middle) + ["<p>"]) + bottom) + ["<p>"]; }; add objvar Adding objvar $page_desktop_login<$root>,credit object $page_desktop_login; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $page_file_index<$root>,credit object $page_file_index; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $page_root_index<$root>,credit object $page_root_index; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $page_login<$root>,credit object $page_login; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $plain_page<$root>,credit object $plain_page; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $page_web_prefs<$root>,credit object $page_web_prefs; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; update objvar Updating objvar $character<$located>,location object $character; var $located location = $nowhere; update objvar Updating objvar $path<$foundation>,msgs object $path; var $foundation msgs = #[["invoke", #[["actor", <$ctext_frob, [["You take ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["source", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " goes through ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["dest", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " arrives."], #[['this, $path]]]>]]], ["exit-close", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " closes ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["actor", <$ctext_frob, [["You close ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>]]], ["exit-open", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " opens ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["actor", <$ctext_frob, [["You open ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>]]], ["lock-fail", #[["actor", <$ctext_frob, [[<$generator, ["this", [], [], 'gen_this]>, " is locked."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is locked."], #[]]>]]], ["lock-try", #[["actor", <$ctext_frob, [["You use ", <$generator, ["lock", [], [], 'gen_lock]>, " on ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[], #[['this, $path]]]>]]], ["lock-unlock", #[["actor", <$ctext_frob, [["You unlock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " unlocks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>]]], ["lock-lock", #[["actor", <$ctext_frob, [["You lock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " locks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>]]], ["exit-closed", #[["actor", <$ctext_frob, [["You try to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is closed."], #[]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is closed."], #[]]>]]]]; add objvar Adding objvar $climate<$root>,credit object $climate; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; new method Replacing public method $climate.ctext_variables() public method $climate.ctext_variables() { arg current, season; var vars; vars = #[["weather", current.name()], ["weather_desc", current.prose()], ["season", season]]; vars = dict_union(vars, current.attribute_vars()); return vars; }; add objvar Adding objvar $weather<$root>,credit object $weather; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; new method Replacing public method $weather.attribute_vars() public method $weather.attribute_vars() { var i, attr, extra, a; a = .attributes(); attr = $weather_attributes.alist_dict(a); for i in ($weather_attributes.extra_attributes()) dict_add(attr, @i); return attr; }; new method Replacing public method $db.exact_match() public method $db.exact_match() { arg key; var match; // get an exact match of a key, return the value match = (| (type(database) == 'dictionary) ? (database[key]) : ((database.match_exact(key))[2]) |); if (match == ~keynf) throw(~matchnf, ("No object by the key \"" + key) + "\" exists."); return match; }; new method Replacing public method $registry.exact_match() public method $registry.exact_match() { arg name; // returns a direct match of the name (if there is one) if (!(.has_flag('variables))) throw(~perm, "Database is not readable by sender."); name = .strip_key(name); return (> pass(name) <); }; new method Replacing root method $mail_db.core_mail_db() root method $mail_db.core_mail_db() { .set_database(#[["news", $mail_list_news], ["bugs", $mail_list_bugs], ["admin", $mail_admin], ["tracebacks", $mail_list_tracebacks], ["postmaster", $mail_postmaster]]); }; update objvar Updating objvar $help_coldcore<$help_node>,body object $help_coldcore; var $help_node body = <$ctext_frob, [[<$format, ["img", [["plain", <$format, ["quote", [], ["\n ___ _ _ _ _ _ ___ _\n / __|___| |__| | | || |___| |_ __ / __|_ _ __| |_ ___ _ __\n | (__/ _ \ / _` | | __ / -_) | '_ \ \__ \ || (_-< _/ -_) ' \ \n \___\___/_\__,_| |_||_\___|_| .__/ |___/\_, /__/\__\___|_|_|_|\n |_| |__/\n"], 'do_quote]>], ["src", "http://www.cold.org/coldcore/cold-help.jpg"]], [], 'do_img]>, <$format, ["p", [], [], 'do_p]>, "Welcome to ", <$generator, ["servname", [], [], 'gen_servname]>, ". This is a hypertext help system. If you are on an interactive login you can type ", <$format, ["tt", [], ["@help help"], 'do_tt]>, " for help on how to use this help system. Following is a list of Launch Points to the help system:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help"]], ["Help"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How to use this help system"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_general"]], ["General"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["General Information"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_building"]], ["Building"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Extending your Environment"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_prog"]], ["Programming"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Topics about programming"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_admin"]], ["Administration"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["ColdCore Administration"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_reference"]], ["Reference"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Core Reference Information"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_updates"]], ["Updates"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["ChangeLog for this system"], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_administrators"]], ["Administrators"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["List of Administrators and Roles"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_credit"]], ["Credit"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Credit and Copyright Information"], 'do_dd]>], 'do_dl]>], #[['links, #[["Help", "$help_help"], ["General", "$help_general"], ["Building", "$help_building"], ["Programming", "$help_prog"], ["Administration", "$help_admin"], ["Reference", "$help_reference"], ["Updates", "$help_updates"], ["Administrators", "$help_administrators"], ["Credit", "$help_credit"]]]]]>; update objvar Updating objvar $help_environment<$help_node>,links object $help_environment; var $help_node links = #[["@context", $help_cmd_context], ["@remember", $help_cmd_remember]]; update objvar Updating objvar $help_environment<$help_node>,body object $help_environment; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Your environment is where the system tries to find things, when you name something. It does this by first checking everything in your contents, and everything in the location you are in. ", <$format, ["subj", [["level", "2"]], ["Context"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The system will also check your recent context. The server records the last object you named, as well as all of the last objects you named (with a gender). You can list your recent context with the command ", <$format, ["link", [["node", "$help_cmd_context"]], ["@context"], 'do_link]>, ", receiving a result similar to:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["Last thing: the Magazine Rack\nLast it: the Magazine Rack \nLast her: Squeak the lemming\nLast him: Miro"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the system is attempting to find a named object, it first checks in your context. This allows you to name objects by their gender (if you remember it correctly). For instance:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], [<$format, ["quote", [], ["> get bottle\nYou take the bottle.\n> drop it\nYou drop the bottle."], 'do_quote]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Multiple Matches"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "In the case where multiple objects would match a single name, you can use ordinal references, such as ", <$format, ["tt", [], ["the 3rd bottle"], 'do_tt]>, " or ", <$format, ["tt", [], ["the second key"], 'do_tt]>, ". ", <$format, ["subj", [["level", "2"]], ["Posessive Matching"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "If something is located in something else, in your environment (either being carried by somebody, or in a box, etc), you can refer to it posessively. For instance, if the user 'Joe' is holding a note, you can look at it with the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], ["> look at Joe's note"], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Keywords"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "There are also two words known by the system. The first is ", <$format, ["tt", [], ["me"], 'do_tt]>, ", which is always you. The second is ", <$format, ["tt", [], ["here"], 'do_tt]>, ", which is always your location. ", <$format, ["subj", [["level", "2"]], ["Remembering"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "If you are having a hard time remembering an items object name, or typing it's full name, you can remember it as a shorter name, with the command ", <$format, ["link", [["node", "$help_cmd_remember"]], ["@remember"], 'do_link]>, "."], #[['links, #[["@context", "$help_cmd_context"], ["@remember", "$help_cmd_remember"]]]]]>; update objvar Updating objvar $help_appearance<$help_node>,body object $help_appearance; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Anything in the virtual environment will always have some common attributes, such as name, description and gender. If you manage the item, you can change these attributes and alter its appearance (this includes yourself). Everything that can be changed is described in more detail in the following sections:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_desc"]], ["Description"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_gender"]], ["Gender"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_wearing"]], ["Wearing"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["Names", "$help_app_names"], ["Description", "$help_app_desc"], ["Gender", "$help_app_gender"], ["Wearing", "$help_app_wearing"]]]]]>; update objvar Updating objvar $help_interface_client<$help_node>,body object $help_interface_client; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When you connect to a Virtual Environment System you use a ", <$format, ["i", [], ["client"], 'do_i]>, ". A client is simply a program you run from your machine. This program connects you with the server somewhere on the network. If you used ", <$format, ["tt", [], ["telnet"], 'do_tt]>, " to get here, your client is ", <$format, ["tt", [], ["telnet"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "This system is not designed for use with ", <$format, ["tt", [], ["telnet"], 'do_tt]>, ". It has many customized aspects which telnet simply does not support. Because of this it is suggested for your own benefit and enjoyment that you get a supported client. ", <$format, ["np", [], [], 'do_np]>, "Currently supported clients are: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "25%,75%"]], [<$format, ["tr", [], [<$format, ["td", [], ["Tinyfugue"], 'do_td]>, <$format, ["td", [], [<$format, ["web", [["src", "ftp://tf.tcp.com/pub/tinyfugue"], ["name", "ftp://tf.tcp.com/pub/tinyfugue"]], [], 'do_web]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["TkMOO-lite"], 'do_td]>, <$format, ["td", [], [<$format, ["web", [["src", "http://www.cs.cf.ac.uk/User/Andrew.Wilson/tkMOO-light/"], ["name", "http://www.cs.cf.ac.uk/User/Andrew.Wilson/tkMOO-light/"]], [], 'do_web]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>; update objvar Updating objvar $help_groups<$help_node>,body object $help_groups; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The group system is an all purpose classification system which can be used for a wide array of purposes. Groups can work in one of two ways: either they are simply a list of objects, and can be tested against for permissions sake, or they use a logical expression as their condition. ", <$format, ["subj", [["level", "2"]], ["Object Groups"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Object groups are heirarchial, so for an example consider the following group heirarchy:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["$group [*-mvc]\n $staff_group [*-mvc]\n $building_group [*fmvc]"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If a user is added to the staff group, and something tests against the building group, the staff members are included so it will evaluate true--even though they are not in the building group. ", <$format, ["subj", [["level", "2"]], ["Groups and Security"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Groups can be specified as a writer on an object, and when testing against writer permissions for that object, it will also include anybody in the group, or evaluate against the condition of the group. ", <$format, ["subj", [["level", "2"]], ["Programmer API"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "To use a group in ColdC code, simply call the method ", <$format, ["method", [["$group.includes", 1]], [".includes"], 'do_method]>, "() on the group, with a single argument of the object which is in question. ", <$format, ["subj", [["level", "2"]], ["Available Groups"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "To see a list of all available groups, use the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@descend $group +all +only=core"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All groups have a setting of '", <$format, ["tt", [], ["group"], 'do_tt]>, "', which is a list of objects--except for $conditional_group and its descendants, where it is a logical expression."], #[]]>; update objvar Updating objvar $help_cml_formatters<$help_node>,body object $help_cml_formatters; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The standard formatter tags are loosely based on HTML 3.0: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "11%,89%"]], [<$format, ["tr", [], [<$format, ["td", [], ["action"], 'do_td]>, <$format, ["td", [], ["One flag of ", <$format, ["tt", [], ["cmd"], 'do_tt]>, ", which is run if the action is triggered (either by clicking on it, or using the action-trigger command ", <$format, ["tt", [], ["'>'."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["b"], 'do_td]>, <$format, ["td", [], ["Bold or strong."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["br"], 'do_td]>, <$format, ["td", [], ["Line Break. Differs from {p} in that it can be stacked multiple times, for multiple breaks. Use of {p} is preferred."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dd"], 'do_td]>, <$format, ["td", [], ["Dictionary Definition, must be an argument to a Dictionary List (", <$format, ["tt", [], ["dl"], 'do_tt]>, ")."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["detail"], 'do_td]>, <$format, ["td", [], ["Generate a description detail. One required option of ", <$format, ["tt", [], ["name"], 'do_tt]>, " which is unique to this detail througout the entire description. Details may be nested."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dfn"], 'do_td]>, <$format, ["td", [], ["Definition. Used to indent a block of text. Arguments can be ", <$format, ["tt", [], ["ind"], 'do_tt]>, ", which is an integer representing the spaces to indent (in plaintext this defaults to eight); and ", <$format, ["tt", [], ["nobound"], 'do_tt]>, ", which effects the line breaks after the definition."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dl"], 'do_td]>, <$format, ["td", [], ["Dictionary list. Arguments can contain tags dt (dictionary title) and dd (dictionary definition)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dt"], 'do_td]>, <$format, ["td", [], ["Dictionary Title, must be an argument to a Dictionary List (", <$format, ["tt", [], ["dl"], 'do_tt]>, ")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["i"], 'do_td]>, <$format, ["td", [], ["Italics or Emphasis."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["img"], 'do_td]>, <$format, ["td", [], ["Place image in description. Image is only visible in HTML formats."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["lh"], 'do_td]>, <$format, ["td", [], ["List Header, must be an argument for ", <$format, ["tt", [], ["ol"], 'do_tt]>, " or ", <$format, ["tt", [], ["ul."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["li"], 'do_td]>, <$format, ["td", [], ["List Element, must be an argument for ", <$format, ["tt", [], ["ol"], 'do_tt]>, " or ", <$format, ["tt", [], ["ul."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["link"], 'do_td]>, <$format, ["td", [], ["Creates a hypertext link to the help node (as an objname) specified with the option ", <$format, ["tt", [], ["node."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["np"], 'do_td]>, <$format, ["td", [], ["New Paragraph, similar to {p}, but in plaintext it breaks with two lines rather than one."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["ol"], 'do_td]>, <$format, ["td", [], ["Ordered list. Within arguments use tags lh (list header) and li (list element)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["p"], 'do_td]>, <$format, ["td", [], ["Paragraph Break, similar to {np}, but in plaintext it only breaks with one line."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["subj"], 'do_td]>, <$format, ["td", [], ["Rougly equivalent to HTML's header <h?> tags. Argument ", <$format, ["tt", [], ["level"], 'do_tt]>, " specifies which level of subject to use (1-4) and defaults to a value of 4."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["table"], 'do_td]>, <$format, ["td", [], ["Similar to tables in HTML. Options are ", <$format, ["tt", [], ["ind"], 'do_tt]>, " (how many spaces to indent the table before formatting) and ", <$format, ["tt", [], ["cols"], 'do_tt]>, " (column definition). ", <$format, ["tt", [], ["cols"], 'do_tt]>, " must be defined. It is a comma seperated list of column specs, which can either be in specific character units or percentages (the whole list must be either one or the other). Arguments consist of ", <$format, ["tt", [], ["tr"], 'do_tt]>, " (table row) tags."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["td"], 'do_td]>, <$format, ["td", [], ["Table Cell, options include ", <$format, ["tt", [], ["colspan"], 'do_tt]>, " and ", <$format, ["tt", [], ["rowspan"], 'do_tt]>, " which can be used to span columns and rows with the Table Cell."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["tr"], 'do_td]>, <$format, ["td", [], ["Table Row, arguments consist of ", <$format, ["tt", [], ["td"], 'do_tt]>, " tags for each table cell in the row."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["tt"], 'do_td]>, <$format, ["td", [], ["Fixed-width font (typewriter), also used for literal text."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["ul"], 'do_td]>, <$format, ["td", [], ["Unordered list. Within arguments use tags lh (list header) and li (list element)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["web"], 'do_td]>, <$format, ["td", [], ["Creates a www hypertext link. This tag requires ", <$format, ["tt", [], ["src"], 'do_tt]>, " and ", <$format, ["tt", [], ["name"], 'do_tt]>, " options. The ", <$format, ["tt", [], ["src"], 'do_tt]>, " should have a valid URL as the value and the ", <$format, ["tt", [], ["name"], 'do_tt]>, " should have the name of the URL to be displayed."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>; update objvar Updating objvar $help_cml_generators<$help_node>,body object $help_cml_generators; var $help_node body = <$ctext_frob, [[<$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "16%,84%"]], [<$format, ["tr", [], [<$format, ["td", [], ["columnize"], 'do_td]>, <$format, ["td", [], ["Generates a list of columnized strings taken from the argument list. Option ", <$format, ["tt", [], ["cols"], 'do_tt]>, " defines column information."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["def"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["var"], 'do_tt]>, " which is the name of a variable. Creates a new variable generator with that name, which has the value of the first argument. Will ", <$format, ["i", [], ["not"], 'do_i]>, " evaluate arguments, instead stores the unparsed first argument. Similar to ", <$format, ["tt", [], ["set"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["english"], 'do_td]>, <$format, ["td", [], ["Generates an english-formatted list from the arguments. Options can include ", <$format, ["tt", [], ["sep"], 'do_tt]>, " (element seperator, defaulting to \",\"), ", <$format, ["tt", [], ["empty"], 'do_tt]>, " (what to print if the argument list is empty, defaulting to \"nothing\"), ", <$format, ["tt", [], ["and"], 'do_tt]>, " (what to print as a seperator before the last element, defaulting to \"and\")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["foreach"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["list"], 'do_tt]>, ". Will iterate over body for each element in list. Additional option ", <$format, ["tt", [], ["var"], 'do_tt]>, " may be defined for iteration variable, defaults to ", <$format, ["tt", [], ["iterator"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["join"], 'do_td]>, <$format, ["td", [], ["Joins arguments. Options can include ", <$format, ["tt", [], ["seperator"], 'do_tt]>, " which is either ", <$format, ["tt", [], ["none"], 'do_tt]>, ", ", <$format, ["tt", [], ["english"], 'do_tt]>, " or a string literal. If ", <$format, ["tt", [], ["none"], 'do_tt]>, " the list is forwarded to the caller, rather than joined to a string"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["name"], 'do_td]>, <$format, ["td", [], ["Generates the names of the objects in the arguments list. Options can include ", <$format, ["tt", [], ["seperator"], 'do_tt]>, " which is either ", <$format, ["tt", [], ["none"], 'do_tt]>, ", ", <$format, ["tt", [], ["english"], 'do_tt]>, " or a string literal. If ", <$format, ["tt", [], ["none"], 'do_tt]>, " is given a list is generated, otherwise a string is generated"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["pro"], 'do_td]>, <$format, ["td", [], ["Generates a pronoun. Required option is ", <$format, ["tt", [], ["obj"], 'do_tt]>, " which defines the object for the pronoun generation. First argument is taken as the type of pronoun to use, as defined on $gender"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["random"], 'do_td]>, <$format, ["td", [], ["Returns a random number ranging from ", <$format, ["tt", [], ["low"], 'do_tt]>, " to ", <$format, ["tt", [], ["high"], 'do_tt]>, " which are given as options. Low can be omitted, one is used then instead."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["servname"], 'do_td]>, <$format, ["td", [], ["The name of the server, as is set on ", <$format, ["tt", [], ["@set $motd:server-name"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["set"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["var"], 'do_tt]>, " which is the name of a variable. Creates a new variable generator with that name, which has the value of the first argument. Will evaluate arguments and store results. Similar to ", <$format, ["tt", [], ["def"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["switch"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["value"], 'do_tt]>, " which is evaluated. The resulting value is then used to select a result. Currently switch uses every other item in the argument list as a case/value pair (use the ", <$format, ["tt", [], ["join"], 'do_tt]>, " generator for arguments with spaces). If there is a remaining odd element is is considered the default result"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["time"], 'do_td]>, <$format, ["td", [], ["Arguments are sent to the native method $time.format()"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["vars"], 'do_td]>, <$format, ["td", [], ["Returns the names of variables available. Option ", <$format, ["tt", [], ["separator"], 'do_tt]>, " is the same as in ", <$format, ["tt", [], ["name"], 'do_tt]>, " generator"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "4"]], ["Other tags"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Each cml processor can also create extra generators. Also, caller to the cml can create extra variables that are available for generators."], #[]]>; update objvar Updating objvar $help_cml_customizing<$help_node>,body object $help_cml_customizing; var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], ["Interface"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Ctext frobs are created by calling the .", <$format, ["method", [["compiler.compile_cml", 1]], ["compile_cml"], 'do_method]>, "() method off the cml compiler object. On a ctext frob, you may call .", <$format, ["method", [["ctext_frob.uncompile", 1]], ["uncompile"], 'do_method]>, "() to return the original text. A call to .", <$format, ["method", [["ctext_frob.eval_ctext", 1]], ["eval_ctext"], 'do_method]>, "() evaluates the generators, but will not touch the formatters. This is used to speed up message dispatching. Calling ", <$format, ["method", [["ctext_frob.format", 1]], ["format"], 'do_method]>, "() provides the final formatting of the ctext, evaluating everything, including the formatters. You can add/modify variables on a ctext frob by calling .", <$format, ["method", [["ctext_frob.set_var", 1]], ["set_var"], 'do_method]>, "(", <$format, ["var", [], ["variable"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, "), or .", <$format, ["method", [["ctext_frob.set_vars", 1]], ["set_vars"], 'do_method]>, "(", <$format, ["var", [], ["dict"], 'do_var]>, "), which does the same, but assigning multiple variables at once. ", <$format, ["subj", [["level", "3"]], ["Adding new evaluators"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "An evaluator is an object which contains methods for generation or formatting. An evaluation object that is descended from a vanilla evaluator (like $bs_eval) will try to store the evaluation results in a list, and is therefore most suitable for adding new generators. On the other hand, evaluators descended from a formatter object create a string, and try to evaluate and concatenate lists until a string is obtained. Hence, they should be used for formatting. To add a new generator or formatter, simply add a do_format or gen_generator method on the object, where 'format' or 'generator' is the name of the new tag that you wish to add. Make sure that the object is in the evaluation path (by explicitly adding an 'evaluator, 'formatter or even an 'uncompiler field to the ctext frob.)"], #[]]>; update objvar Updating objvar $help_coldc_methods_access<$help_node>,links object $help_coldc_methods_access; var $help_node links = #[["Frobbed Method Calls", $help_coldc_methods_frob], ["method_access()", $help_func_method_access], ["set_method_access()", $help_func_set_method_access]]; update objvar Updating objvar $help_coldc_methods_access<$help_node>,body object $help_coldc_methods_access; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "It is possible to restrict what calls a method by setting the method's access. By default all methods are ", <$format, ["i", [], ["public"], 'do_i]>, " methods. The available settings for method access are: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "15%,85%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["public"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This access state is the default. A public method can be called by any object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["protected"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Protected methods can only be called by the defining object, or descendants of the defining object (sender() must be this())."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["private"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Private methods can only be called by the object they were defined on (caller() must be this())."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["root"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Root methods can only be called by the ", <$format, ["tt", [], ["$root"], 'do_tt]>, " object (caller() must be ", <$format, ["tt", [], ["$root"], 'do_tt]>, ")."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["driver"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Driver methods can only be called by the driver."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["frob"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This access state only allows ", <$format, ["link", [["node", "$help_coldc_methods_frob"]], ["Frobbed Method Calls"], 'do_link]>, "."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Method access can be manipulated using the functions ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_method_access"]], ["method_access()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_method_access"]], ["set_method_access()"], 'do_link]>], 'do_tt]>, "."], #[['links, #[["Frobbed Method Calls", "$help_coldc_methods_frob"], ["method_access()", "$help_func_method_access"], ["set_method_access()", "$help_func_set_method_access"]]]]]>; update objvar Updating objvar $help_coldc_tasks_tasks<$help_node>,links object $help_coldc_tasks_tasks; var $help_node links = #[["task_id()", $help_func_task_id], ["task_info()", $help_func_task_info], ["tasks()", $help_func_tasks], ["stack()", $help_func_stack], ["user()", $help_func_user], ["set_user()", $help_func_set_user], ["atomic()", $help_func_atomic]]; update objvar Updating objvar $help_coldc_tasks_tasks<$help_node>,body object $help_coldc_tasks_tasks; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "One or more frames executed in a series is called a ", <$format, ["i", [], ["task"], 'do_i]>, ". Tasks will originate from either a connection, a heartbeat, or by a fork in another task. There is no restriction on how many frames a task can execute. ", <$format, ["np", [], [], 'do_np]>, "Several different functions return information about a task, or are used on a task-wide scale: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "23%,77%"]], [<$format, ["tr", [], [<$format, ["th", [], ["FUNCTION"], 'do_th]>, <$format, ["th", [], ["BEHAVIOUR"], 'do_th]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_id"]], ["task_id()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns unique ID for the current task"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_info"]], ["task_info()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns information on a task"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_tasks"]], ["tasks()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns a list of all paused or preempted tasks"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_stack"]], ["stack()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns full execution frame stack"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_user"]], ["user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns task user"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_user"]], ["set_user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Sets task user"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Used to turn on/off Atomic execution"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["task_id()", "$help_func_task_id"], ["task_info()", "$help_func_task_info"], ["tasks()", "$help_func_tasks"], ["stack()", "$help_func_stack"], ["user()", "$help_func_user"], ["set_user()", "$help_func_set_user"], ["atomic()", "$help_func_atomic"]]]]]>; update objvar Updating objvar $help_func_backup<$help_node>,body object $help_func_backup; var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " backup()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function synchronizes the running database to disk and starts an asyncrynous backup (Genesis copies the files to the file ", <$format, ["i", [], ["binary"], 'do_i]>, ".bak, where ", <$format, ["i", [], ["binary"], 'do_i]>, " is the binary database directory name specified upon bootup). This function executes atomically, and a slight pause may be noticed while it synchronizes the object cache to disk and copies the index files. ", <$format, ["np", [], [], 'do_np]>, "The return value of ", <$format, ["tt", [], ["backup()"], 'do_tt]>, " is always ", <$format, ["tt", [], ["1"], 'do_tt]>, ", and should be ignored. If a backup is in progress the error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown. The error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown if there are file or directory problems. When the asyncrynous backup is finished the driver calls ", <$format, ["tt", [], ["$sys.backup_done()"], 'do_tt]>, "."], #[]]>; new method Replacing public method $help_administrators.body() public method $help_administrators.body() { arg @ignored; var admins, a, output, def, role, c1, c2, o; admins = []; def = "General Administrator"; for a in ($sys.admins()) { role = a.get_setting("admin-role", $admin); if (match_begin(role, "Arch")) role = "0 " + role; else if (role && ((role[1]) in ($string.alphabet()))) role = "00 " + role; else if (!role) role = "000 " + def; admins += [[role, a]]; } output = []; for a in (admins.sort()) { o = $cml_lib.format_obj_tag('look, a[2], (a[2]).name()); c1 = $cml_lib.format_td_tag(o); role = strsed(a[1], "^0+ ", ""); c2 = $cml_lib.format_td_tag(role); output += [$cml_lib.format_tr_tag(c1, c2)]; } return $ctext_frob.new_with([$cml_lib.format_dfn_tag(["Administrators:", $cml_lib.format_p_tag(), $cml_lib.format_table_tag("25%,75%", @output)])]); }; update objvar Updating objvar $help_cmd_paste<$help_node>,body object $help_cmd_paste; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@paste [to <target>]"], 'do_tt]>, <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "The non-VR interaction command ", <$format, ["tt", [], ["@paste"], 'do_tt]>, " is used to display blocks of text either to the room or to a specific person (<target>). If no target is specified, it is displayed to the room. You will be prompted for the text. When you are finished typing in the text, type a period at the beginning of a line, followed by no other characters. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["> @paste\nReceiving input. Enter \".\" to finish or \"@abort\" to abort.\n> USER PID %CPU %MEM VSZ RSS COMMAND\n> brandon 10267 0.0 19.4 5800 5928 ./genesis\n> .\n-------------- Brandon (@paste's) ---------------\nUSER PID %CPU %MEM VSZ RSS COMMAND\nbrandon 10267 0.0 19.4 5800 5928 ./genesis\n------------------- + Finis + -------------------\n2 lines of text pasted"], 'do_quote]>], 'do_dfn]>], #[]]>; update objvar Updating objvar $help_cmd_display<$help_node>,body object $help_cmd_display; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@d?isplay <objref> [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Shows general information about an object, including it's size, owner, parents, location, and what permissions it has. You can optionally have it list all the public methods you have defined on an object, or all the variables, and which object defines them as below. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire\nObject: $vampire (Vampire)\nCreated: Mon Jan 13 18:19:17 1997\nQuota: 75000 bytes\nPerms:\nSize: 6,132 bytes (on disk)\nManager: $vampire (Vampire)\nWriters: (none)\nParents: $admin (Generic Admin) and $antisocial\nLocation: $the_pit (The Pit)\n---"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire,\nObject Variables matching \"*\"\n ,test_dict: #[]\n ,test: 0\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire.\nPublic Methods matching \"*\":\n ---- 34 .edit_cmd(cmdstr, com, args)\n ---- 14 .quit_editor()\n ---- 49 .pulse()\n ---- 24 .startup()\n ---- 8 .dict_test(cmdstr, cmd, @str)\n ---- 51 .tmp_pulse()\n"], 'do_quote]>], 'do_dfn]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+c?hop"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Chops lines longer than the players cols ", <$format, ["link", [["node", "$help_interface_settings"]], ["setting"], 'do_link]>, "."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+g?enerations"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets which object to go back from."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["setting", "$help_interface_settings"]]]]]>; update objvar Updating objvar $help_cmd_backup<$help_node>,body object $help_cmd_backup; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: @backup"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Start an asynchronous backup of the binary database."], #[]]>; update objvar Updating objvar $help_cmd_describe<$help_node>,links object $help_cmd_describe; var $help_node links = #[["CML", $help_cml], ["@edit", $help_cmd_edit]]; update objvar Updating objvar $help_cmd_describe<$help_node>,body object $help_cmd_describe; var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@desc?ribe|@prose <what> [as <description>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Sets the description (prose) for an object. If nothing other than the target object is given on the command line, you will be prompted for the description. Otherwise it will take anything after the preposition '", <$format, ["i", [], ["as"], 'do_i]>, "' as the description. ", <$format, ["np", [], [], 'do_np]>, "The description is not written in plaintext, but is in ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, ". Because of this, all plaintext formatting you include will be disregarded. Use CML tags for any desired formatting. ", <$format, ["np", [], [], 'do_np]>, "Note: This will overwrite the current description. To edit the description on the object, use the ", <$format, ["link", [["node", "$help_cmd_edit"]], ["@edit"], 'do_link]>, " command."], #[['links, #[["CML", "$help_cml"], ["@edit", "$help_cmd_edit"]]]]]>; update objvar Updating objvar $help_cmd_new<$help_node>,body object $help_cmd_new; var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@new <parent> [named <name>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Creates a new VR object with the given parent, and optionally set the name. This command is preferred when working with VR objects, as it will correctly handle both real and ", <$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frob"], 'do_link]>, " instances. The alternative is ", <$format, ["link", [["node", "$help_cmd_spawn"]], ["@spawn"], 'do_link]>, " which will always create new objects. If you want to create a new non-VR object, use @spawn or call the parent's .new() method.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_destroy"]], ["@destroy"], 'do_link]>], #[['links, #[["Frob", "$help_coldc_types_frobs"], ["@spawn", "$help_cmd_spawn"], ["@destroy", "$help_cmd_destroy"]]]]]>; update objvar Updating objvar $help_cmd_spawn<$help_node>,body object $help_cmd_spawn; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@spawn <parent>[named <name>]"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Create a new object with the given parent, and optionally set the name. This command is generally used only by programmers, as it always creates a real object and does not create a frob instance, and it will create any type of object, not just a VR object. In general the command ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>, " is used instead."], #[['links, #[["@new", "$help_cmd_new"]]]]]>; update objvar Updating objvar $help_cmd_bugs<$has_name>,name object $help_cmd_bugs; var $has_name name = ['prop, "@bugs|@pr|@problems", "@bugs|@pr|@problems"]; update objvar Updating objvar $help_obj_mail_list<$help_node>,body object $help_obj_mail_list; var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The Mail List is a generic recipient for mail. To create a mailing list simply spawn a new object from $mail_list, and name it as appropriate for your list. You can configure the following settings on a mailing list: mail-notify, mail-senders, mail-readers and inet-list. The first three settings can be set as logically true or false (i.e. anybody, everybody, nobody, etc), or they can be set to the token \"writers\", or they can be a list of objects. If they are the token \"writers\" it includes whoever is included as a writer. If it is a list of objects, only those objects are included. ", <$format, ["subj", [["level", "2"]], ["mail-notify"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "A list of people who will receive notification, if false or true no notification is made to anybody. ", <$format, ["subj", [["level", "2"]], ["mail-senders"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Who can send to the list, or if true anybody can send to the list. ", <$format, ["subj", [["level", "2"]], ["mail-readers"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Who who can read the list. If true anybody can read the list. ", <$format, ["subj", [["level", "2"]], ["inet-list"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Can be set to an email address. If so, it will treat this Mail List as an Internet Mailing List. This behaviour is special in that it will forward to the specified email address if mail is received from within the Virtual Environment--but if mail is received from the SMTP gateway it will be stored on the list as normal.", <$format, ["p", [], [], 'do_p]>, "To setup an internet list in this way, simply set this setting to be the internet list address, and also subscribe the SMTP name for the ColdCore list (list-<name>@domain) to the internet list. For this to work as an internet list hook, you must also setup SMTP forwarding from your operating system, or bind the SMTP port directly to port 25. More information on this can be found at: ", <$format, ["web", [["src", "http://www.cold.org/sitenames.html"], ["name", "http://www.cold.org/sitenames.html"]], [], 'do_web]>, <$format, ["p", [], [], 'do_p]>, "This setting can only be set by administrators, look for a mail-forward setting in the future, which will have configurable access restrictions."], #[]]>; update objvar Updating objvar $editor_parser<$editor_parser>,commands object $editor_parser; var $editor_parser commands = #[["ap?pend", 'append_cmd], ["a?fter", 'after_cmd], ["d?elete|e?rase", 'delete_cmd], ["done|quit", 'quit_cmd], ["h?elp", 'help_cmd], ["i?nsert", 'insert_cmd], ["line", 'line_cmd], ["l?ist|ls", 'list_cmd], ["m?ove|mv", 'move_cmd], ["save|comp?ile", 'save_cmd], ["store", 'store_cmd], ["sed|sub", 'subst_cmd], ["send|mail", 'send_cmd], ["c?opy|cp", 'copy_cmd], ["f?ill|w?rap", 'fill_cmd], ["j?oin", 'join_cmd]]; update objvar Updating objvar $editor_parser<$editor_parser>,command_help object $editor_parser; var $editor_parser command_help = #[['insert_cmd, ["Syntax: i?nsert [<text>] OR '<text>", "", "Add <text> before current line. You may also use a single-quote (') as a shortcut character. If text does not exist you will be prompted for the input."]], ['after_cmd, ["Syntax: a?fter [<text>] OR _<text>", "", "Add <text> after current line. You may also use an underscore (_) as a shortcut character. If text does not exist you will be prompted for the input."]], ['append_cmd, ["Syntax: ap?pend <text> OR ,<text>", "", "Add <text> after current line. You may also use a comma (,) as a shortcut character."]], ['delete_cmd, ["Syntax: d?elete [<range>]", "", "Delete <range> or current line."]], ['copy_cmd, ["Syntax: copy [<range>] [to] <line>", "", "Copy <range> of text or current line to <line>."]], ['quit_cmd, ["Syntax: done|quit", "", "Close editor without saving changes."]], ['fill_cmd, ["Syntax: fill <range> <line width>", "", "Fill <range> of lines to fit within <line width> appropriately (either by expanding or joining)."]], ['help_cmd, ["Syntax: help [<command>]", "", "Basic editor help."]], ['line_cmd, ["Syntax: line <line>", "", "Change the current line to <line>. You can also use a period (.) as a shortcut character."]], ['move_cmd, ["Syntax: move [<range>] [to] <line>", "", "Move <range> or current line to <line>."]], ['list_cmd, ["Syntax: list [<range>] [-n?umbers]", "", "List <range> or all of edit buffer. The option -n?umbers may be used to not specify line numbers."]], ['subst_cmd, ["Syntax: s?ub|sed <old> <new> [<range>] [<options>]", "", "Search for <old> and replace it with <new> in <range> (defaulting to the current line). The character following the command is used as a seperator (a space in the example). This allows for the sed-like syntax: s/old/new/. The command 'sed' will use strsed() with regular expressions, the command 'sub' or 's' will use strsub() with literal matching. Options are any one of:", "", " g Globally match and replace (do it multiple times)", " s Single match and replace (do it only on the first occurance)", " c Case matters when matching.", " i Case doesn't matter when matching.", "", "Option defaults for sed are: si", "Option defaults for sub are: gi"]], ['save_cmd, ["Syntax: save|comp?ile [as] [<ref>]", "", "Save document, if arguments are given will save alternate copy."]], ['store_cmd, ["Syntax: store", "", "Store editor--do not save changes. Editor can be resumed with @reedit."]], ['send_cmd, ["Syntax: send|mail <mail-recipient>", "", "Used to send current contents of editor to a mail recipient."]], ['join_cmd, ["Syntax: j?oin <range> \"<sep>\"", "", "Join <range> lines together as one line, seperated by <sep> (default as space)"]]]; new method Adding public method $editor_session.join_cmd() public method $editor_session.join_cmd() { arg cmd, tmpl, args; var range, width, sep, spos, epos; (> .perms(caller(), 'command) <); catch any range = ._parse_range(args.word(1)); with return "Illegal range, can't join."; if (" " in args) sep = ((substr(args, (" " in args) + 1).trim()).unquote()) || " "; else sep = " "; [spos, epos] = range; text = (sublist(text, 1, spos - 1) + [join(sublist(text, spos, (epos - spos) + 1), sep)]) + sublist(text, epos + 1); modified = 1; line = spos; return ("Join completed. Current set to " + line) + "."; }; new method Replacing public method $editor_session.sed() public method $editor_session.sed() { arg start, end, search, replace, opts; var x, line, changed; if (end > listlen(text)) end = listlen(text); for x in [start .. end] { line = strsed(text[x], search, replace, opts); if (strcmp(line, text[x])) { text = replace(text, x, line); changed++; } } return changed; }; new method Replacing public method $editor_session.sub() public method $editor_session.sub() { arg start, end, search, replace, opts; var x, line, changed, i; if (end > listlen(text)) end = listlen(text); for x in [start .. end] { line = strsub(text[x], search, replace, opts); if (strcmp(line, text[x])) { text = replace(text, x, line); changed++; } } return changed; }; add objvar Adding objvar $adapter<$root>,credit object $adapter; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $math<$root>,credit object $math; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; new method Adding public method $time.realm_time() public method $time.realm_time() { arg realm, @season; var d, lt, hr, pm, min, tm; d = realm.get_setting("weather-time", $realm); lt = ((d[5]).local_time()) + (d[6]); hr = ((lt / 3600) + (d[6])) % 24; if (hr >= 12) { pm = "PM"; if (hr > 12) hr -= 12; } else { pm = "AM"; } min = (lt / 60) % 60; tm = strfmt("%2{0}r:%2{0}r ", hr, min) + pm; return [tm + (season ? ((" (" + (d[2])) + "time)") : ""), (d[3]).realm()]; }; add objvar Adding objvar $heap<$root>,credit object $heap; var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"]; new method Adding public method $cml_lib.fmt_table() public method $cml_lib.fmt_table() { arg cols, @contents; return (<$format, ["table", [["cols", cols]], contents, 'do_table]>); }; new method Adding public method $cml_lib.fmt_invoke() public method $cml_lib.fmt_invoke() { arg object, method, name; return (<$format, ["invoke", [["object", object], ["method", method]], [name], 'do_invoke]>); }; new method Adding public method $cml_lib.fmt_subj() public method $cml_lib.fmt_subj() { arg text, @level; [(level ?= 4)] = level; return (<$format, ["subj", [["level", level]], [text], 'do_subj]>); }; new method Adding public method $cml_lib.fmt_br() public method $cml_lib.fmt_br() { return br; }; new method Adding public method $cml_lib.fmt_obj() public method $cml_lib.fmt_obj() { arg context, object, name, @args; var opt, src; if (args) { [opt, (src ?= sender())] = args; return (<$format, ["obj", [["context", context], ["name", name], ["options", opt]], [object, src], 'do_obj]>); } else { return (<$format, ["obj", [["context", context], ["name", name]], [object], 'do_obj]>); } }; new method Adding public method $cml_lib.gen_join() public method $cml_lib.gen_join() { arg list, @sep; [(sep ?= ", ")] = sep; return (<$generator, ["join", [["separator", sep]], list, 'gen_join]>); }; new method Adding public method $cml_lib.fmt_input() public method $cml_lib.fmt_input() { arg @flags; return (<$format, ["input", flags, [], 'do_input]>); }; new method Adding public method $cml_lib.fmt_td() public method $cml_lib.fmt_td() { arg contents, @flags; var spanning, color; return (<$format, ["td", flags, [contents], 'do_td]>); }; new method Adding public method $cml_lib.fmt_textarea() public method $cml_lib.fmt_textarea() { arg contents, @flags; return (<$format, ["textarea", flags, [contents], 'do_textarea]>); }; new method Adding public method $cml_lib.fmt_tr() public method $cml_lib.fmt_tr() { arg @contents; return (<$format, ["tr", [], contents, 'do_tr]>); }; new method Adding public method $cml_lib.fmt_pre() public method $cml_lib.fmt_pre() { arg args; return (<$format, ["pre", [], [args], 'do_pre]>); }; new method Adding public method $cml_lib.fmt_quote() public method $cml_lib.fmt_quote() { arg args; return (<$format, ["quote", [], [args], 'do_quote]>); }; new method Adding public method $cml_lib.fmt_b() public method $cml_lib.fmt_b() { arg contents; return (<$format, ["b", [], [contents], 'do_b]>); }; new method Adding public method $cml_lib.fmt_href() public method $cml_lib.fmt_href() { arg url, str; return (<$format, ["a", [["href", url]], [str], 'do_href]>); }; new method Adding public method $cml_lib.fmt_sep() public method $cml_lib.fmt_sep() { return sep; }; new method Adding public method $cml_lib.fmt_p() public method $cml_lib.fmt_p() { return p; }; new method Replacing public method $cml_lib.format_dfn_tag() public method $cml_lib.format_dfn_tag() { arg args; return (<$format, ["dfn", [], args, 'do_dfn]>); }; new method Adding public method $cml_lib.gen_english() public method $cml_lib.gen_english() { arg list; return (<$generator, ["english", [], list, 'gen_english]>); }; new method Adding public method $cml_lib.fmt_form() public method $cml_lib.fmt_form() { arg form, @flags; return (<$format, ["form", flags, form, 'do_form]>); }; new method Replacing public method $cml_lib.format_td_tag() public method $cml_lib.format_td_tag() { arg contents, @flags; var spanning, color; return (<$format, ["td", flags, [contents], 'do_td]>); }; new method Adding public method $cml_lib.fmt_dfn() public method $cml_lib.fmt_dfn() { arg args; return (<$format, ["dfn", [], args, 'do_dfn]>); }; new method Adding public method $cml_lib.fmt_hr() public method $cml_lib.fmt_hr() { arg @flags; if (flags) return (<$format, ["hr", flags, [], 'do_hr]>); return hr; }; add objvar Adding objvar $converters<$root>,credit object $converters; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $security_lib<$root>,credit object $security_lib; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; add objvar Adding objvar $directories<$root>,credit object $directories; var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"]; update objvar Updating objvar $conditional_group<$group>,group object $conditional_group; var $group group = <$false_lock_frob, #[]>; maintenance object $root; eval { del_method('__upgrade_handle_var); }; old obj Removing $owner_lock_frob... old object $owner_lock_frob;