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], ["@descend?ants *", 'descendants_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], ["@teval *", 'tick_eval_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]]
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 $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 $has_settings setting_templates #[["@list-options", 'string]]
var $programmer eval_tick_offset 0
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, vars, pkeys, v, evalp, adjust, ticks, time;
.perms(sender(), 'this);
evalp = .eval_prefix();
pkeys = dict_keys(evalp);
adjust = !str;
vars = ("var " + ($list.to_string(pkeys, ", "))) + "; ";
for v in (pkeys)
vars = (vars + (evalp[v])) + "; ";
// perform escape substitution
str = .eval_subs(str);
// Evaluate the line.
if (str && ((str[1]) == ";"))
str = substr(str, 2);
else
str = ((vars + " return ") + str) + ";";
time = time();
ticks = tick();
result = .eval([str]);
ticks = (tick() - ticks) - eval_tick_offset;
time = time() - time;
if (adjust && ((result[1]) != 'errors)) {
eval_tick_offset = eval_tick_offset + ticks;
.tell(("Eval tick offset adjusted by " + tostr(ticks)) + " ticks.");
return;
}
// Display the errors, or the result.
if ((result[1]) == 'errors) {
.tell(result[2]);
} else {
.tell("=> " + ($data.unparse(result[2], 'full)));
.tell(((("[ ticks: " + tostr(ticks)) + " seconds: ") + tostr(time)) + " ]");
}
.
method program_cmd
arg com, [args];
var syntax, obj, ref, add_hist, why, x;
.perms(sender(), 'this);
syntax = "Syntax: `@program <obj>.<method>`";
args = explode(args[1]);
if (!args)
$parse.tell_error("You must give an object and method to program", syntax);
ref = $parse.reference(args[1]);
obj = .match_env_nice(ref[1], syntax);
ref = (ref[2]) || ($parse.tell_error("No method name given.", syntax));
why = "";
add_hist = 1;
for x in [2 .. listlen(args)] {
if (match_begin("-edited", args[x])) {
if (!($sys.is_admin(this())))
.tell("! Only administrators can compile without history comments.");
else
add_hist = 0;
} else {
why = (why + " ") + (args[x]);
}
}
args = ['compile, obj, tosym(ref), add_hist, why];
if (!(obj.is_writable_by(this()))) {
.tell("! You cannot program that object; ignoring code.");
args = replace(args, 1, 'ignore);
}
.read('programming_done, @args);
.tell(((("-- Enter text for " + (obj.dbref())) + ".") + ref) + " --");
.
method show_cmd
arg com, name;
var obj;
.perms(sender(), 'this);
if (!name)
$parse.tell_error("Must specify an object to show.", com + " <object>");
obj = .match_env_nice(name);
if (!(| .tell(obj.show()) |))
.tell("Permission denied.");
.
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, str;
var code, nums, line, ref, syntax, ancestor, opt;
.perms(sender(), 'this);
nums = com == "@nlist";
syntax = com + " <object>.<method>";
// figure out the object/reference
catch any {
ref = $parse.full_reference(str);
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 verb, what;
var thing;
thing = .match_env_nice(what);
if (!thing)
return;
.tell(("Descendants of " + (thing.namef('ref))) + ":");
.tell(thing._display_descendants());
.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 ($dict.to_list(obj.verbs())) {
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, r;
if (sender() != this())
throw(~perm, "Sender not this");
loc = (| .match_environment(where) |);
if (!loc) {
catch any {
loc = $room_db.match_room(where);
} with handler {
switch (error()) {
case ~ambig:
// check aliases for the hell of it
for r in ((traceback()[1])[3]) {
if (r.name_match(where)) {
loc = r;
break;
}
}
if (!loc)
$parse.tell_error("Several rooms match that name: " + ($list.to_english($list.map((traceback()[1])[3], 'namef))));
default:
$parse.tell_error((traceback()[1])[2]);
}
}
}
(.location()).announce((.namef()) + " @go'd elsewhere", this());
.move_to(loc);
(.location()).announce((.namef()) + " @go'd here", this());
.tell("You @go'd");
.
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 $dict.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(caller(), $input);
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 tick_eval_cmd
arg com, str;
.eval_cmd(com, (";var ticks,x,y,z; ticks = ticks_left(); " + str) + " ; return ticks-ticks_left()-4;");
.
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])));
.