parent $builder object $programmer var $root child_index 33 var $root owners [$programmer] var $root fertile 0 var $has_commands commands [["@show *", 'show_cmd], ["@list|@nlist *", 'list_cmd], ["@program *", 'program_cmd], ["@d?isplay *", 'display_cmd], ["@dump *", 'dump_cmd], ["@id *", 'id_cmd], ["@go *", 'go_cmd], ["@mcom?mands *", 'mcommands_cmd], ["@info *", 'info_cmd], ["@which *", 'which_cmd], ["@mv|@move|@cp|@copy *", 'copy_move_cmd], ["@del-m?ethod|@delm?ethod|@dm *", 'del_method_cmd], ["@add-m?ethod|@addm?ethod|@am *", 'add_method_cmd], ["@eval *", 'eval_cmd], ["@ancestor?s|@ascend *", 'ancestors_cmd], ["@add-c?ommand|@ac *", 'add_command_cmd], ["@del-c?ommand|@dc *", 'del_command_cmd], ["@as * eval *", 'eval_as_cmd], ["@def?iner * this|as * eval *", 'eval_as_to_cmd], ["@descend?ants from * to *", 'descendants_cmd], ["@join *", 'join_cmd], ["@ledit *", 'local_edit_cmd]] var $has_commands shortcuts [[";*", 'eval_cmd, ["eval", 1]]] var $has_verbs verbs #[] var $location contents [] var $located location $nowhere var $user password "*" var $user connected_at 0 var $user last_command_at 0 var $user connections [] var $root inited 1 var $root owned [$programmer] var $programmer eval_prefix 0 var $command_aliases command_aliases [] var $user modes #[] var $mail_list letters #[] var $mail_list letters_index #[] var $mail_list senders 1 var $mail_list readers [$core] var $mail_list notify [$programmer] var $mail_list last_letter 0 var $mail_ui subscribed #[[$programmer, 791485891]] var $gendered gender $gender_neuter var $located obvious 1 var $described prose #[] var $user prompt "" var $root manager $programmer var $root writable [$programmer] var $root readable ['parameters, 'methods, 'code] var $user parsers [$command_parser, $verb_parser] var $user tell_traceback ['brief, 0] var $user context #[] var $root quota 75000 var $root dbref 'programmer var $named name ['uniq, "Generic Programmer"] var $named name_aliases [] var $user_data user_data #[['real_name, [1, "???"]], ['email, [1, "???"]]] var $old_has_settings setting_templates #[["@list-options", 'string], ["@program-options", 'string]] var $programmer eval_tick_offset 0 var $old_command_environment verb_cache #[] var $old_command_environment command_cache [] var $old_command_environment shortcuts_cache [] var $help_ui current_node $help_node_summary var $help_ui last_visited #[['pos, 1], ['nodes, [$help_node_summary]]] var $has_messages message_info #[["teleport.source", [$base_evaluator, $compile_evaluator, $uncompile_evaluator, []]], ["teleport", [$base_evaluator, $compile_evaluator, $uncompile_evaluator, ["actor", "general"]]]] var $has_messages messages #[[$programmer, #[["teleport", <$message_class, #[["actor", <$ctext_class, ['text_stmt, [['string_type, "You teleport to "], ['get_stmt, [['string_type, "dest name"]]], ['string_type, "."]]]>], ["general", <$ctext_class, ['text_stmt, [['get_stmt, [['string_type, "actor name"]]], ['string_type, " teleports here from "], ['get_stmt, [['string_type, "source name"]]], ['string_type, "."]]]>]]>], ["teleport.source", <$ctext_class, ['text_stmt, [['get_stmt, [['string_type, "actor name"]]], ['string_type, " teleports to "], ['get_stmt, [['string_type, "dest name"]]], ['string_type, "."]]]>]]]] var $programmer eval_offset 0 var $mail_list mail [] var $mail_ui current #[['location, 0], ['list, $programmer]] method init_programmer .perms(caller(), $root); .set_tell_traceback('verbose, 4); . method uninit_programmer .perms(caller(), $root); . method eval_cmd arg com, str; var result, adjust, vars, v, evalp, ticks, time, mtime, line, offset; (> .perms(sender(), 'this) <); adjust = !str; evalp = .eval_prefix(); vars = ("var " + ((evalp.keys()).to_string(", "))) + "; "; for v in (evalp.values()) vars = (vars + v) + "; "; // perform escape substitution str = .eval_subs(str); // Evaluate the line. if (str && ((str[1]) == ";")) { str = substr(str, 2); result = .eval([str]); } else { str = ((vars + " return ") + str) + ";"; offset = .eval_offset(); time = [time()]; ticks = [tick()]; mtime = [mtime()]; result = .eval([str]); mtime = mtime + [mtime()]; ticks = ticks + [tick()]; time = time + [time()]; // this is a rough way to figure mtime, but its the best we can do.. time = (time[2]) - (time[1]); ticks = (ticks[2]) - (ticks[1]); if (((mtime[1]) > (mtime[2])) && (!time)) mtime = (999999 - (mtime[1])) + (mtime[2]); else if (((mtime[1]) > (mtime[2])) && time) mtime = ((time * 999999) + (999999 - (mtime[1]))) + (mtime[2]); else mtime = (mtime[2]) - (mtime[1]); if (!adjust) { time = time - (offset['time]); ticks = ticks - (offset['ticks]); mtime = mtime - (offset['mtime]); } // figure out times/ticks if (adjust && ((result[1]) != 'errors)) { eval_offset = eval_offset.add('ticks, ticks); eval_offset = eval_offset.add('mtime, mtime); eval_offset = eval_offset.add('time, time); line = tostr(ticks) + " ticks, "; line = (line + tostr(time)) + " seconds, and "; line = (line + tostr(mtime)) + " microseconds."; .tell("Eval offset adjusted by " + line); return; } } // Display the errors, or the result. if ((result[1]) == 'errors) { .tell(result[2]); } else { .tell("=> " + ($data.unparse(result[2], 'full))); if (ticks) { line = (("[ ticks: " + tostr(ticks)) + " seconds: ") + tostr(time); if (time) line = ((line + " (") + tostr(ticks / time)) + " per)"; .tell(((line + " microseconds: ") + tostr(mtime)) + " ]"); } } . method program_cmd arg com, args; var syn, ref, edited, why, ignore, epref, spref, line; .perms(sender(), 'this); syn = com + " <obj>.<method> [-edited] [comments]"; args = (args + " ") + ((.setting("@program-options")) || ""); args = $parse.options(args, #[["edited", [1, ""]]]); edited = ((args[2])["edited"])[1]; args = args[1]; spref = ((.setting("error-syntax-prefix")) || "=>") + " "; epref = (.setting("error-prefix")) || "! "; if (!args) { .tell(spref + syn); .tell(epref + "No <object>.<method> reference specified."); ignore = 1; } else { catch any { ref = $parse.full_reference(args[1], this(), [this(), 'match_environment]); } with handler { .tell(spref + syn); .tell(epref + ((traceback()[1])[2])); ref = ['method, 0, 0]; ignore = 1; } } if ((ref[1]) != 'method) { .tell(spref + syn); .tell(epref + "Invalid <object>.<method> reference."); ignore = 1; } if ((!edited) && (!($sys.is_admin(this())))) { .tell(epref + "Only administrators can compile without history comments."); edited = 1; } if ((ref[2]) && (!((ref[2]).is_writable_by(this())))) { .tell(epref + "You cannot program that object."); ignore = 1; } why = sublist(args, 2).to_string(); args = ['compile, ref[2], ref[3], edited, why]; if (ignore) { .tell(epref + "Ignoring input until \".\" or \"@abort\"."); args = replace(args, 1, 'ignore); } if (!ignore) line = ((("-- Enter text for " + ((ref[2]).dbref())) + ".") + tostr(ref[3])) + " --"; else line = ""; .programming_done(.read(line), @args); . method show_cmd arg com, name; var obj; .perms(sender(), 'this); if (!name) $parse.tell_error("Must specify an object to show.", ("Syntax: `" + com) + " <object>`"); obj = .match_env_nice(name); catch any { .tell(obj.show()); } with handler { .tell((traceback()[1])[2]); } . method _move_method arg syn, ref1, ref2, [opts]; var line, code; .perms(sender(), 'this); catch any { ref1 = $parse.reference(ref1); ref2 = $parse.reference(ref2); if ((!(ref1[2])) || (!(ref2[2]))) $parse.tell_error("You must define both a method to be copied from, and one to be copied to.", syn); ref1 = replace(ref1, 1, .match_env_nice(ref1[1])); ref1 = replace(ref1, 2, tosym(ref1[2])); ref2 = replace(ref2, 1, .match_env_nice(ref2[1])); ref2 = replace(ref2, 2, tosym(ref2[2])); code = (ref1[1]).list_method(ref1[2]); // Parse Options if (opts && ("-edited" in ($list.to_string(opts[1])))) { if (!($sys.is_system(sender()))) .tell("! Sorry, only admins can turn off the edited messages."); } else { line = (" // " + ($time.ldate('mdy, 'dash))) + "/"; line = ((line + ($time.ltime('24hr))) + " ") + (.namef('ref)); line = (((line + ", moved from ") + ((ref1[1]).dbref())) + ".") + tostr(ref1[2]); code = [@code, line]; } // delete the old method, compile the new one. (ref1[1]).del_method(ref1[2]); (ref2[1]).compile(code, ref2[2]); // cool, we made it. line = ((("Method " + ((ref1[1]).dbref())) + ".") + tostr(ref1[2])) + " moved to "; line = (((line + ((ref2[1]).dbref())) + ".") + tostr(ref2[2])) + "."; .tell(line); } with handler { switch (error()) { case ~methodnf: line = (traceback()[1])[2]; line = substr(line, 1, strlen(line) - 1); $parse.tell_error(((line + " on ") + ((ref1[1]).namef('ref))) + ".", syn); case ~perm: $parse.tell_error("You cannot write on that object.", syn); case ~stop: rethrow(error()); default: // they are men, they can deal with the tracebacks $parse.tell_error([(traceback()[1])[2], traceback()[2], traceback()[3]], syn); } } . method del_method_cmd arg com, what; var syntax, obj, ref, res; .perms(sender(), 'this); syntax = ("Syntax: `" + com) + " <obj>.<method>`"; what = explode(what); if (!what) $parse.tell_error("You must give an object and a method to delete", syntax); ref = $parse.reference(what[1]); obj = .match_env_nice(ref[1], syntax); ref = (ref[2]) || ($parse.tell_error("No method name given.", syntax)); res = (| obj.del_method(tosym(ref)) |); if (type(res) == 'error) { switch (res) { case ~methodnf: .tell("! No such method"); default: .tell("! You do not have the perms to modify that object"); } } else { .tell("Method removed."); } . method move_cmd arg com, [args]; var syn; .perms(sender(), 'this); syn = ("`" + com) + " [from] <$obj.ref> [to] <$obj.ref>`"; // figure up args args = explode(@args); if (args && ((args[1]) == "from")) args = delete(args, 1); if ((listlen(args) > 1) && ((args[2]) == "to")) args = delete(args, 2); if (listlen(args) < 2) $parse.tell_error("Not enough arguments sent.", syn); // what type is it (method/parameter) if (("." in (args[1])) && ("." in (args[2]))) return ._move_method(syn, @args); else if (("," in (args[1])) && ("," in (args[2]))) return ._move_parameter(syn, @args); else $parse.tell_error("You must define both methods, or both parameters.", syn); . method list_cmd arg com, args; var code, nums, line, ref, syntax, ancestor, opt, opts, str; (> .perms(sender(), 'this) <); nums = com == "@nlist"; syntax = com + " <object>.<method>"; // parse arguments opts = #[["n", [0, ""]]]; args = $parse.options(args, opts); opts = args[2]; args = args[1]; str = args ? args[1] | ""; nums = (com == "@nlist") || ((opts["n"])[1]); // figure out the object/reference catch any { ref = $parse.full_reference(str, this(), [this(), 'match_environment]); if ((ref[1]) != 'method) $parse.tell_error("You must submit an object.method() reference", syntax); ancestor = (ref[2]).find_method(ref[3]); code = ancestor.list_method(ref[3]); if (nums) { code = $list.numbered_text(code); } else { for line in [1 .. listlen(code)] code = replace(code, line, " " + (code[line])); } } with handler { switch (error()) { case ~methodnf: line = ((((ref[2]).dbref()) + ".") + tostr(ref[3])) + "()"; $parse.tell_error(line + " not found.", syntax); default: $parse.tell_error((traceback()[1])[2], syntax); } $parse.tell_error((traceback()[1])[2], syntax); } opt = (.setting("@list-options")) || ""; line = ((((ancestor.dbref()) + ".") + tostr(ref[3])) + " ") + opt; if (nums) .tell("--- Method " + line); else .tell("@program " + line); .tell(code); .tell("."); . method copy_move_cmd arg com, [args]; var syn, how, line; .perms(sender(), 'this); syn = ("`" + com) + " [from] <$obj.ref> [to] <$obj.ref>`"; // figure up args args = explode(@args); args = [@args, ""]; args = setremove(args, "from"); args = setremove(args, "to"); if (listlen(args) != 3) $parse.tell_error("Send two object references.", syn); how = (com in ["@mv", "@move"]) ? 'move | 'copy; catch ~namenf { args = [$parse.full_reference(args[1], sender()), args[2], args[3]]; args = [args[1], $parse.full_reference(args[2], sender()), args[3]]; if ((((args[1])[1]) != ((args[2])[1])) && (((args[2])[1]) != 'unknown)) $parse.tell_error(((((("Cannot " + tostr(how)) + ((((args[1])[1]) == 'unknown) ? " an object" | ("from a " + tostr((args[1])[1])))) + " to ") + "a ") + tostr((args[2])[1])) + ".", syn); else if (((args[1])[1]) == 'method) ._copy_move_method(syn, how, @args); else if (((args[1])[1]) == 'parameter) .tell("Parameters are currently unsupported, sorry!"); else $parse.tell("You must specify a full reference for the source object.", syn); } with handler { $parse.tell_error((traceback()[1])[2], syn); } . method display_cmd arg com, disp_ref; var to_show; // display method/parameter info for an object // to_show is a list as follows: // [$object, 'param | 'meth | 'none, "pattern", [opts]] .perms(sender(), 'this); to_show = ._parse_disp_ref(disp_ref); if (to_show) { if ((to_show[4])['header]) ._disp_obj_header(to_show[1], to_show[4]); ._disp_obj_detail(@to_show); .tell($string.center(" + Finis + ", .linelen(), "-")); } . method id_cmd arg verb, obj; .perms(sender(), 'this); obj = .match_env_nice(obj); .tell((((((((obj.namef('xref)) + " ") + ($object.see_perms(obj))) + " ") + ($data.unparse(obj.parents()))) + " ") + tostr(obj.size())) + " bytes"); . method dump_cmd arg com, args; var opts, obj, dbref, x, pdbref, par, data, readable, me, code, syn, tail; .perms(sender(), 'this); syn = [["Options can be:", " +/-n -- nice formatting", " +/-t -- textdump formatting", " +/-m -- show/don't show methods", " +/-p -- show/don't show parameters", "Flags default to \"-n +m +p\""], com + " [options] <object>"]; opts = #[["n", [0, 0]], ["t", [1, 0]], ["m", [1, 0]], ["p", [1, 0]], ["e", [0, 0]]]; args = $parse.options(args, opts); if (!(args[1])) $parse.tell_error(@syn); obj = .match_env_nice((args[1])[1]); me = this(); dbref = obj.dbref(); opts = args[2]; readable = obj.is_readable_by(me); data = (| obj.data() |); if ((opts["p"])[1]) { if (!data) { .tell(" *** Parameters are unreadable by you ***"); } else { if ((opts["n"])[1]) { .tell("Object: " + (obj.namef('ref))); .tell("Parents: " + ($list.to_english($list.map(obj.parents(), 'namef)))); .tell(("Size: " + tostr(obj.size())) + " bytes"); } else { // I'm not sure how the latest drivers handle dbrefs vs objnums for x in (obj.parents()) .tell("parent " + (x.dbref())); .tell("object " + dbref); .tell(""); } for par in (data) { if (type(par[2]) == 'string) { .tell((" *** " + ((par[1]).dbref())) + "'s parameters are unreadable by you ***"); } else { pdbref = (| (par[1]).dbref() |) || toliteral(par[1]); for x in (par[2]) .tell((((("var " + pdbref) + " ") + tostr(x[1])) + " ") + ($data.unparse(x[2]))); } } } } if ((opts["m"])[1]) { .tell(""); if (!('code in readable)) { .tell((" *** " + dbref) + "'s methods are unreadable by you ***"); } else { if ((opts["e"])[1]) tail = " -edited"; else tail = ""; for x in (obj.methods()) { code = obj.list_method(x); if ((opts["n"])[1]) .tell(((("@program " + dbref) + ".") + tostr(x)) + tail); else .tell("method " + tostr(x)); for x in [1 .. listlen(code)] code = replace(code, x, " " + (code[x])); .tell(code); .tell([".", ""]); // this can get long pause(); } } } . method add_method_cmd arg com, what; var syntax, obj, ref, res; .perms(sender(), 'this); syntax = "Syntax: `@add-method <obj>.<method>`"; what = explode(what); if (!what) $parse.tell_error("You must give an object and a method to add", syntax); ref = $parse.reference(what[1]); obj = .match_env_nice(ref[1], syntax); ref = (ref[2]) || ($parse.tell_error("No method name given.", syntax)); res = (| obj.compile([""], tosym(ref)) |); if (res != []) .tell("! You do not have the perms to modify that object"); else .tell("Method added."); . method descendants_cmd arg cmd, from, obj, prep, base; (> .perms(sender(), 'this) <); if (base == "base") base = 0; else base = .match_env_nice(base); obj = .match_env_nice(obj); .tell((("Descendants of " + (obj.namef('xref))) + (base ? " to " + (base.namef('xref)) | "")) + ":"); .tell(obj._display_descendants("", [], base)); .tell("---"); . method ancestors_cmd arg verb, what; var thing; thing = .match_env_nice(what); if (!thing) return; .tell(("Ancestors of " + (thing.namef('ref))) + ":"); .tell(thing._display_ancestors()); .tell("---"); . method _parse_disp_ref arg disp_ref; var sep_pos, sep, obj, obj_name, to_show, opts, ref, pattern, which_det; opts = explode(disp_ref); if (!opts) return []; ref = opts[1]; opts = $list.to_string(sublist(opts, 2)); sep_pos = (":" in ref) || (("." in ref) || ((";" in ref) || ("," in ref))); if (sep_pos) { obj_name = substr(ref, 1, sep_pos - 1) || (.namef('ref)); sep = substr(ref, sep_pos, 1); pattern = substr(ref, sep_pos + 1) || "*"; obj = .match_env_nice(obj_name); if (sep in [";", ":"]) { opts = ($string.trim(opts)) + " anc:"; if ((opts[1]) == "$") { opts = opts + (explode(opts)[1]); opts = substr(opts, strlen(explode(opts)[1]) + 1); } else { opts = opts + ","; } } if ((pattern[1]) == "_") opts = "pri" + opts; which_det = #[[":", 'meth], [".", 'meth], [";", 'param], [",", 'param]][sep]; opts = $display_opts.from_str(opts, obj, $list.last(obj.ancestors())); return [obj, which_det, pattern, opts]; } else { obj = .match_env_nice(ref); opts = $display_opts.from_str(opts, obj, $list.last(obj.ancestors())); return [obj, 'none, "", opts]; } . method _disp_obj_detail arg obj, which_det, pattern, opts; var details, info, detail, len, show_private, param; .perms(sender(), 'this); len = .linelen(); if (which_det == 'meth) { info = obj.method_info(opts['max_parent], $misc, '_display_filter, [pattern], (opts['show_private]) ? [] | ["_*"]); details = [["Methods:", ""], ["Lines $parent.method(args)", "First comment or return value"]]; for detail in (info) details = [@details, [(((((((((detail[4]) ? "+" | " ") + ($string.right(tostr(detail[5]), 4))) + " ") + (((detail[1]) != obj) ? (detail[1]).id() | "")) + ".") + tostr(detail[2])) + "(") + (detail[3])) + ")", detail[6]]]; for detail in (details) .tell(pad((pad(detail[1], len / 2) + " ") + (detail[2]), len)); } else if (which_det == 'param) { info = obj.parameter_info(opts['max_parent]); details = ["Parameter(s)"]; for detail in (info) { param = tostr(detail[2]); if (match_pattern(pattern, param) != 0) { detail = ((((" " + (((detail[1]) != obj) ? (detail[1]).namef('id) | "")) + ",") + param) + ": ") + ($data.unparse(detail[3])); if ((opts['chop_props]) && (strlen(detail) > (len - 1))) detail = $string.chop(detail, len); details = [@details, detail]; } } .tell(details); } . method mcommands_cmd arg cmd, what; var obj, coms, c, len, line, emote, opts; // returns all commands in a nice format. // god this is getting ugly. .perms(sender(), 'this); // options opts = explode(what); what = opts[1]; opts = sublist(opts, 2); if (opts && match_begin("-emote", "-e")) emote = 1; // if (what == "") what = .ancestors(); else what = [.match_env_nice(what)]; for obj in (what) { if ((obj.has_ancestor($has_commands)) || (obj.has_ancestor($has_verbs))) { .tell(("Commands on " + (obj.namef('ref))) + ":"); coms = []; coms = coms + ((| obj.shortcuts() |) || []); coms = coms + ((| obj.commands() |) || []); len = ((.linelen()) - 5) / 2; if (!emote) { for c in (coms) { line = (" " + ($string.left(("\"" + (c[1])) + "\"", len))) + " "; .tell(line + ($data.unparse(c[2]))); } } else { for c in (coms) { // they aren't always a _cmd but fk. .tell((((";" + (.dbref())) + ".del_command(") + ($data.unparse(c[2]))) + ")"); line = (((";" + (.dbref())) + ".add_command(\"") + (c[1])) + "\", "; .tell((line + ($data.unparse(c[2]))) + ")"); } } if ((| obj.verbs() |)) { for c in ((obj.verbs()).to_list()) { line = (" " + ($string.left(("\"" + (c[1])) + "\"", len))) + " "; line = line + ((((c[2])[2]) == 'remote) ? "rmt " | " "); line = line + ($data.unparse((c[2])[1])); .tell(line); } } if (obj == $has_commands) break; } else { .tell(("Object " + (obj.namef('ref))) + " has no commands."); } } . method _disp_obj_header arg obj, opts; var line, lines, objs, line_len, extra_str; // Display header info for obj .perms(sender(), 'this); line_len = .linelen(); // Object: line = "Object: " + (obj.namef('ref)); if (obj.fertile()) line = line + " (Fertile)"; .tell(line); // Owners: if (opts['header]) { objs = obj.owners(); line = $list.to_english($list.map(objs, 'namef, 'ref)); .tell(("Owner" + ((listlen(objs) > 1) ? "s: " | ": ")) + line); .tell(("Size: " + ($integer.to_english(obj.size()))) + " bytes"); // Parents: [parents] objs = obj.parents(); if (objs) { line = $list.to_english($list.map(objs, 'namef, 'ref)); if (!(opts['chop_head_data])) line = $string.chop(line, line_len - 9); .tell(("Parent" + ((listlen(objs) > 1) ? "s: " | ": ")) + line); } objs = obj.children(); if (objs) { line = $list.to_english($list.map(objs, 'namef, 'ref)); if (!(opts['chop_head_data])) line = $string.chop(line, line_len - 10); .tell(((listlen(objs) > 1) ? "Children: " | "Child: ") + line); } if (obj.has_ancestor($located)) .tell("Location: " + ((obj.location()).namef('ref))); } . method go_cmd arg com, where; var loc, p; (> .perms(sender(), 'this) <); if (!where) { .tell("Specify a destination."); return; } if (where == "home") loc = .home(); else loc = (| .match_environment(where) |); if (!loc) { for p in (.remembered_places()) { if ((p.match_name(where)) || (p.match_name_aliases(where))) { loc = p; break; } } } // if we have still not found a location... if (!loc) { catch any { loc = $place_db.find(where); } with handler { switch (error()) { case ~ambig: .tell("Several rooms match that name: " + ((((traceback()[1])[3]).map('namef)).to_english())); case ~namenf: .tell(("Unable to find place \"" + where) + "\"."); return; default: $parse.tell_error((traceback()[1])[2]); } } } if (!loc) { .tell(("Unable to find place \"" + where) + "\"."); return; } if (loc == (.location())) { .tell("You are already there!"); return; } if (!(.teleport(loc))) .tell("Sorry."); . method info_cmd arg com, obj; var info; .perms(sender(), 'this); obj = .match_env_nice(obj); info = obj.info(); if (!info) return .tell("No information about " + (obj.namef('ref))); .tell("-----"); .tell(info); .tell("-----"); . method eval_subs arg code; var idx, ret_code, sub; ret_code = ""; while (code) { idx = "^" in code; if (!idx) { return ret_code + code; } else if ((idx == strlen(code)) || (substr(code, idx + 1, 1) == "^")) { ret_code = ret_code + substr(code, 1, idx); code = substr(code, idx + 1); if (code && ((code[1]) == "^")) code = substr(code, 2); } else { if (idx > 1) { ret_code = ret_code + substr(code, 1, idx - 1); code = substr(code, idx + 1); } else { code = substr(code, 2); } idx = 1; while ((idx <= strlen(code)) && (!((code[idx]) in " =.()[]=<>?|&!*+-/';\""))) idx = idx + 1; sub = .match_env_nice(substr(code, 1, idx - 1)); ret_code = ret_code + (sub.dbref()); code = substr(code, idx); } } return ret_code; . method eval_prefix .perms(sender(), 'this); return $dictionary.union(#[["me", "me = this();"], ["here", "here = me.location()"]], eval_prefix || #[]); . method del_command_cmd arg cmd, str; var syn, cmdref, ref; .perms(sender(), 'this); syn = ("`" + cmd) + " <command reference> [from] <object>`"; if (!str) $parse.tell_error("No arguments specified.", syn); if ((str[1]) == "\"") { str = substr(str, 2); cmdref = substr(str, 1, ("\"" in str) - 1); str = explode(substr(str, ("\"" in str) + 1)); } else if ((str[1]) == "'") { str = explode(str); cmdref = tosym(substr(str[1], 2)); } if (!cmdref) $parse.tell_error("Command references can either be templates or symbols.", syn); if (!str) $parse.tell_error("Invalid object reference.", syn); ref = .match_env_nice(str[listlen(str)]); catch any { ref.del_command(cmdref); } with handler { switch (error()) { case ~perm: $parse.tell_error(strsub((traceback()[1])[2], "%O", ((traceback()[1])[3]).namef('xref)), syn); default: $parse.tell_error((traceback()[1])[2], syn); } } .tell(((("Command " + ((type(cmdref) == 'symbol) ? "for method " | "with template ")) + toliteral(cmdref)) + " deleted from ") + (ref.namef('xref))); . method programming_done arg code, status, obj, meth, hist, why; var last_edit, errors; (> .perms(sender(), 'this) <); if (code == 'aborted) return; if (status == 'ignore) return .tell("Finished ignoring input."); if (hist) { last_edit = (" // " + ($time.ldate('mdy, 'dash))) + "/"; last_edit = (last_edit + ($time.ltime('24hr))) + " "; last_edit = last_edit + (.namef('ref)); if (why) last_edit = (last_edit + ":") + why; code = code + [last_edit]; } catch any { errors = obj.compile(code, meth); if (errors) .tell(errors); else .tell("Method compiled."); } with handler { switch (error()) { case ~perm: $parse.tell_error("! You cannot program that object."); default: $parse.tell_error("! " + ((traceback()[1])[2])); } } . method which_cmd arg which, cmdstr; var cmd, cmds, parent, pcmds, matches, smatches, template, syn, len, line; // searches all commands for str and returns obj.method for said command .perms(sender(), 'this); syn = ("`" + which) + " <template>`"; if (!cmdstr) $parse.tell_error("No template given.", syn); matches = []; smatches = []; template = explode(cmdstr)[1]; for parent in (.ancestors()) { pcmds = (| parent.commands() |); if (pcmds) { for cmd in (pcmds) { if (cmdstr in ($string.strip(cmd[1], "?"))) matches = [@matches, [cmd[1], parent, cmd[2]]]; // else if (match_begin(cmd[1], template)) // matches = [@matches, [cmd[1], parent, cmd[2]]]; } } // do shortcuts seperately so we can note the difference pcmds = (| parent.shortcuts() |); if (pcmds) { for cmd in (pcmds) { if (cmdstr in ($string.strip(cmd[1], "?"))) smatches = [@smatches, [cmd[1], parent, cmd[2], cmd[3]]]; // else if (match_begin(cmd[1], template)) // smatches = [@smatches, [cmd[1], parent, cmd[2], cmd[3]]]; } } if (parent == $has_commands) break; } if ((!matches) && (!smatches)) { .tell(("No commands found matching the template \"" + cmdstr) + "\"."); return; } len = (.linelen()) / 2; .tell(("Commands matching the template \"" + cmdstr) + "\":"); for cmd in (matches) { line = (" " + pad($code.unparse_command(delete(cmd, 2)), len)) + " "; .tell((((line + ((cmd[2]).dbref())) + ".") + tostr(cmd[3])) + "()"); } for cmd in (smatches) { line = (" " + pad($code.unparse_command(delete(cmd, 2)), len)) + " "; .tell((((line + ((cmd[2]).dbref())) + ".") + tostr(cmd[3])) + "()"); } . method _copy_move_method arg syn, how, ref1, ref2, opts; var line, code, type; .perms(sender(), 'this); catch any { code = (ref1[2]).list_method(ref1[3]); if (opts && ("-edited" in opts)) { if (!($sys.is_system(sender()))) .tell("! Only admins can turn off the edited messages."); } else { line = (" // " + ($time.ldate('mdy, 'dash))) + "/"; line = ((line + ($time.ltime('24hr))) + " ") + (.namef('ref)); line = (((line + ", moved from ") + ((ref1[2]).dbref())) + ".") + tostr(ref1[3]); code = [@code, line]; } if (how == 'move) (ref1[2]).del_method(ref1[3]); (ref2[2]).compile(code, ref2[3]); line = ($string.capitalize(tostr(ref1[1]))) + " "; line = (((line + ((ref1[2]).dbref())) + ".") + tostr(ref1[3])) + " "; line = (line + ((how == 'move) ? "moved" | "copied")) + " "; line = (((line + ((ref2[2]).dbref())) + ".") + tostr(ref2[3])) + "."; .tell(line); } with handler { switch (error()) { case ~methodnf: line = (traceback()[1])[2]; line = substr(line, 1, strlen(line) - 1); $parse.tell_error(((line + " on ") + ((ref1[1]).namef('ref))) + ".", syn); case ~perm: $parse.tell_error("You cannot write on that object.", syn); case ~stop: rethrow(error()); default: // they are men, they can deal with the tracebacks .tell("Error encountered:"); .tell_traceback(traceback()); } } . method add_command_cmd arg cmd, str; var syn, sref, ref, template; .perms(sender(), 'this); syn = ("`" + cmd) + " <template> [for] <object.method>`"; if (!str) $parse.tell_error("No arguments specified.", syn); if ((str[1]) != "\"") $parse.tell_error("No template given (must be enclosed in quotes).", syn); str = substr(str, 2); sref = explode(substr(str, ("\"" in str) + 1)); template = substr(str, 1, ("\"" in str) - 1); sref = sref[listlen(sref)]; ref = (| $parse.full_reference(sref, this()) |); if (!ref) $parse.tell_error(("\"" + sref) + "\" is an invalid object.method() reference.", syn); if (!(ref[3])) $parse.tell_error(("No method specified on " + ((ref[2]).dbref())) + ".", syn); if (!template) $parse.tell_error("No template specified.", syn); catch any { (ref[2]).add_command(template, ref[3]); } with handler { .tell_traceback(traceback()); switch (error()) { case ~perm: $parse.tell_error(strsub((traceback()[1])[2], "%O", ((traceback()[1])[3]).namef('xref)), syn); default: $parse.tell_error((traceback()[1])[2], syn); } } .tell(((((("Command " + template) + " added for the method ") + toliteral(ref[3])) + " on ") + ((ref[2]).namef('xref))) + "."); . method eval_as_cmd arg cmd, objname, prep, line; var obj, result; (> .perms(sender(), 'this) <); line = line + ";"; obj = .match_env_nice(objname); result = obj.eval([line]); if ((result[1]) == 'errors) .tell(result[2]); else .tell((("eval as " + (obj.dbref())) + " => ") + ($data.unparse(result[2]))); . method eval_as_to_cmd arg cmd, objname, this, targetname, eval, line; var obj, target, result; (> .perms(sender(), 'this) <); line = line + ";"; obj = .match_env_nice(objname); target = .match_env_nice(targetname); result = obj.eval([line], target); if ((result[1]) == 'errors) .tell(result[2]); else .tell((((((((cmd + " ") + objname) + " ") + this) + " ") + targetname) + " eval => ") + ($data.unparse(result[2]))); . method teleport arg dest; var m1, m2, source, vars; (> .perms(sender(), 'this) <); source = .location(); if (!(| .move_to(dest) |)) return 0; vars = $base_evaluator.fix_values(#[["actor name", .name()], ["actor", this()], ["source name", source.name()], ["source", source], ["dest name", dest.name()], ["dest", dest]]); m1 = .eval_message("teleport.source", vars); m2 = .eval_message("teleport", vars); dest.announce(m2); source.announce(m1, this()); . method join_cmd arg com, who; var loc, p, user; (> .perms(sender(), 'this) <); if (!who) { .tell("Specify a user to join."); return; } catch any { user = $user_db.find(who); } with handler { .tell((traceback[1])[2]); return; } loc = user.location(); if (loc == (.location())) { .tell(("You are already with " + (user.name())) + "!"); return; } if (!(.teleport(loc))) { .tell("Sorry."); } else { .tell(("You join " + (user.name())) + "."); user.tell((.name()) + " joins you."); } . method local_edit_cmd arg cmd, args; var syn, ref, edited, why, epref, spref, line, code, ancestor; syn = cmd + " <obj>.<method> [-edited] [comments]"; args = $parse.options(args, #[["edited", [1, ""]]]); edited = ((args[2])["edited"])[1]; args = args[1]; if (!args) $parse.tell_error("No <object>.<method> reference specified.", syn); catch any { ref = $parse.full_reference(args[1], this(), [this(), 'match_environment]); } with handler { $parse.tell_error((traceback()[1])[2], syn); } if ((ref[1]) != 'method) $parse.tell_error("Invalid <object>.<method> reference.", syn); if ((!edited) && (!($sys.is_admin(this())))) { .tell("Only administrators can compile without history comments."); edited = 1; } if ((ref[2]) && (!((ref[2]).is_writable_by(this())))) $parse.tell_error("You cannot program on that object."); why = sublist(args, 2).to_string(); catch any { ancestor = (ref[2]).find_method(ref[3]); code = ancestor.list_method(ref[3]); } with handler { switch (error()) { case ~methodnf: line = ((((ref[2]).dbref()) + ".") + tostr(ref[3])) + "()"; $parse.tell_error(line + " not found.", syntax); default: $parse.tell_error((traceback()[1])[2], syntax); } $parse.tell_error((traceback()[1])[2], syntax); } .tell((((((("#$# edit name: " + ((ref[2]).name())) + ".") + tostr(ref[3])) + " upload: @program ") + (ancestor.dbref())) + ".") + tostr(ref[3])); .tell(code); .tell("."); . method xdisplay_cmd arg cmd, args; var opts, syn, ref; (> .perms(sender(), 'this) <); // syn = cmd + " <object reference> [options]"; opts = #[["c", [1, ""]]]; args = $parse.options(args, opts); opts = args[2]; args = args[1]; if (!args) $parse.tell_error("No object reference specified.", syn); catch any { ref = $parse.xreference(args[1], this(), [this(), 'match_environment]); } with handler { $parse.tell_error((traceback()[1])[2], syn); } .tell(._display_object_detail(ref[2], 0)); .tell(pad("", .linelen(), "-")); .(tosym("_display_" + tostr(ref[1])))(sublist(args, 2), opts); . method _display_object_detail arg obj, chop; var len, out, line, tmp; (> .perms(sender(), 'this) <); len = .linelen(); line = ("Object: " + (obj.namef('xref))) + " "; line = line + ($object.see_perms(obj)); out = [((line.left((len / 3) * 2)) + " Size: ") + ((obj.size()).to_english())]; line = obj.owners(); if (listlen(line) > 1) line = "Owners: " + ((line.map('dbref)).to_english()); else line = "Owner: " + ((line[1]).namef('xref)); if (chop) line = line.chop(len); out = [@out, line]; line = obj.parents(); if (listlen(line) > 1) line = "Parents: " + ((line.map('dbref)).to_english()); else line = "Parent: " + ((line[1]).namef('xref)); if (chop) line = line.chop(len); out = [@out, line]; out = [@out, "Location: " + ($object.get_name(.location(), 'namef, ['xref]))]; return out; . method eval_offset return eval_offset || #[['mtime, 0], ['time, 0], ['ticks, 0]]; .