Mail Room (#48)(an instance of Generic Editor made by Hacker)VERB SOURCE CODE: working_on:
return this:ok(who = args[1]) && tostr("a letter ", this.sending[who] ? "(in transit)
" | "", "to ", this:recipient_names(who), (subject = this.subjects[who]) && tostr("
entitled \"", subject, "\""));
.
parse_invoke:
"invoke(rcptstrings,verb[,subject]) for a @send";
"invoke(1,verb,rcpts,subject,replyto,body) if no parsing is needed";
"invoke(2,verb,msg,flags,replytos) for an @answer";
if (!(which = args[1]))
player:tell_lines({tostr("Usage: ", args[2], "
init_session:
if (this:ok(who = args[1]))
this.sending[who] = 0;
this.recipients[who] = args[2];
this.subjects[who] = args[3];
this.replytos[who] = args[4] || {};
this:load(who, args[5]);
this.active[who]:tell("Composing ", this:working_on(who));
p = this.active[who];
if (p:mail_option("enter"))
if (typeof(lines = $command_utils:read_lines()) == ERR)
p:tell(lines);
else
this:insert_line(p in this.active, lines, 0);
endif
endif
endif
.
pri*nt:
if (!dobjstr)
plyr = player;
elseif ($command_utils:player_match_result(plyr = $string_utils:match_player(dobjstr),
dobjstr)[1])
return;
endif
if (typeof(msg = this:message_with_headers(plyr in this.active)) != LIST)
if (player == plyr)
player:tell(msg);
else
player:tell(plyr.name, "(", plyr, ") has not published anything here.");
endif
return;
else
player:display_message({((plyr == player) ? "Your" | tostr(plyr.name, "(", plyr,
")'s")) + " message so far:", ""}, player:msg_text(@msg));
endif
.
message_with_headers:
return (this:readable(who = args[1]) || this:ok(who)) && $mail_agent:make_message(this.active[who],
this.recipients[who], {this.subjects[who], this.replytos[who]}, this:text(who));
.
subj*ect::
if (!(who = this:loaded(player)))
player:tell(this:nothing_loaded_msg());
elseif (!argstr)
player:tell(this.subjects[who]);
elseif (ERR == typeof(subj = this:set_subject(who, argstr)))
player:tell(subj);
else
player:tell(subj ? ("Setting the subject line for your message to \"" + subj)
+ "\"." | "Deleting the subject line for your message.");
endif
.
set_subject:
if (!(fuckup = this:ok(who = args[1])))
return fuckup;
else
this.subjects[who] = subj = args[2];
this:set_changed(who, 1);
return subj;
endif
.
to*::
if (!(who = this:loaded(player)))
player:tell(this:nothing_loaded_msg());
elseif (!args)
player:tell("Your message is currently to ", this:recipient_names(who), ".");
else
this.recipients[who] = this:parse_recipients({}, args);
this:set_changed(who, 1);
player:tell("Your message is now to ", this:recipient_names(who), ".");
endif
.
also*-to: cc*::
if (!(who = this:loaded(player)))
player:tell(this:nothing_loaded_msg());
else
this.recipients[who] = this:parse_recipients(this.recipients[who], args);
this:set_changed(who, 1);
player:tell("Your message is now to ", this:recipient_names(who), ".");
endif
.
parse_recipients:
"parse_recipients(prev_list,list_of_strings) -- parses list of strings and adds any
resulting player objects to prev_list. Optional 3rd arg is prefixed to any mismatch
error messages";
recips = args[1];
cmd_id = {@args, ""}[3] || "";
for s in ((typeof(l = args[2]) == LIST) ? l | {l})
if (typeof(s) != STR)
if ($mail_agent:is_recipient(s))
recips = setadd(recips, s);
else
player:tell(cmd_id, s, " is not a valid mail recipient.");
endif
elseif (!$mail_agent:match_failed(md = $mail_agent:match_recipient(s), s, cmd_id))
recips = setadd(recips, md);
endif
endfor
return recips;
.
recipient_names: return this:ok(who = args[1]) && $mail_agent:name_list(@this.recipients[who]); . make_message: return $mail_agent:make_message(@args); . name_list: "(obsolete verb... see $mail_agent:name_list)"; return $mail_agent:(verb)(@args[1]); . parse_msg_headers:
"parse_msg_headers(msg,flags)";
" parses msg to extract reply recipients and construct a subject line";
" if the \"all\" flag is present, reply goes to all of the original recipients";
" returns a list {recipients, subjectline} or 0 in case of error.";
msg = args[1];
replyall = "all" in args[2];
objects = {};
if ("followup" in args[2])
"...look for first non-player recipient in To: line...";
for o in ($mail_agent:parse_address_field(msg[3]))
if (objects)
"...damn, we need BREAK...";
elseif ($object_utils:isa(o, $mail_recipient))
objects = {o};
endif
endfor
endif
objects = objects || $mail_agent:parse_address_field(msg[2] + (replyall ? msg[3]
| ""));
for line in (msg[5..("" in {@msg, ""}) - 1])
if (rt = index(line, "Reply-to:") == 1)
objects = $mail_agent:parse_address_field(line);
endif
endfor
recips = {};
for o in (objects)
if (o == #0)
player:tell("Sorry, but I can't parse the header of that message.");
return 0;
elseif ((!valid(o)) || (!(is_player(o) || ($mail_recipient in $object_utils:ancestors(o)))))
player:tell(o, " is no longer a valid player or maildrop; ignoring that recipient.");
elseif (o != player)
recips = setadd(recips, o);
endif
endfor
subject = msg[4];
if (subject == " ")
subject = "";
elseif (subject && (index(subject, "Re: ") != 1))
subject = "Re: " + subject;
endif
return {recips, subject};
.
check_answer_flags:
flags = {};
for o in ({"all", "include", "followup"})
if (player:mail_option(o))
flags = {@flags, o};
endif
endfor
reply_to = player:mail_option("replyto") || {};
flaglist = "+1#include -1#noinclude +2#all -2#sender 0#replyto +3#followup ";
for a in (args)
if (i = index(a, "="))
value = a[i + 1..length(a)];
a = a[1..i - 1];
else
value = "";
endif
if ((typeof(a) != STR) || ((i = index(flaglist, "#" + a)) < 3))
player:tell("Unrecognized answer/reply option: ", a);
return 0;
elseif (i != rindex(flaglist, "#" + a))
player:tell("Ambiguous answer/reply option: ", a);
return 0;
elseif (j = index("0123456789", flaglist[i - 1]) - 1)
if (value)
player:tell("Flag does not take a value: ", a);
return 0;
endif
f = {"include", "all", "followup"}[j];
flags = (flaglist[i - 2] == "+") ? setadd(flags, f) | setremove(flags, f);
if (f == "all")
flags = setremove(flags, "followup");
endif
elseif ((!value) || (value = this:parse_recipients({}, $string_utils:explode(value),
"replyto flag: ")))
reply_to = value || {};
endif
endfor
return {flags, reply_to};
.
reply-to*: replyto*::
if (!(who = this:loaded(player)))
player:tell(this:nothing_loaded_msg());
else
if (args)
this.replytos[who] = rt = this:parse_recipients({}, args);
this:set_changed(who, 1);
else
rt = this.replytos[who];
endif
player:tell(rt ? ("Replies will go to " + $mail_agent:name_list(@this.replytos[who]))
+ "." | "Reply-to field is empty.");
endif
.
send:
"WIZARDLY";
if (!(who = this:loaded(player)))
player:notify(this:nothing_loaded_msg());
elseif (!(recips = this.recipients[who]))
player:notify("Umm... your message isn't addressed to anyone.");
elseif (this.sending[who])
player:notify("Again? ... relax... it'll get there eventually.");
else
msg = this:message_with_headers(who);
this.sending[who] = old_sending = task_id();
this:set_changed(who, 0);
player:notify("Sending...");
"... this sucker can suspend BIG TIME...";
result = $mail_agent:raw_send(msg, recips, player);
"... the world changes...";
who = player in this.active;
if (who && (this.sending[who] == old_sending))
"... same editing session; no problemo...";
previous = "";
this.sending[who] = 0;
else
"... uh oh, different session... tiptoe quietly out...";
"... Don't mess with the session.";
previous = "(prior send) ";
endif
if (!(e = result[1]))
player:notify(tostr(previous, (typeof(e) == ERR) ? e | ("Bogus recipients:
" + $string_utils:from_list(result[2]))));
player:notify(tostr(previous, "Mail not sent."));
previous || this:set_changed(who, 1);
elseif (length(result) == 1)
player:notify(tostr(previous, "Mail not actually sent to anyone."));
previous || this:set_changed(who, 1);
else
player:notify(tostr(previous, "Mail actually sent to ", $mail_agent:name_list(@listdelete(result,
1))));
if (previous)
"...don't even think about it...";
elseif (player.location == this)
if (ticks_left() < 10000)
suspend(0);
endif
this:done();
elseif (!this:changed(who))
"... player is gone, no further edits...";
this:kill_session(who);
endif
endif
endif
.
who:
if (dobjstr)
if (!(recips = this:parse_recipients({}, args)))
"parse_recipients has already complained about anything it doesn't like";
return;
endif
elseif (caller != player)
return E_PERM;
elseif (!(who = this:loaded(player)))
player:tell(this:nothing_loaded_msg());
return;
else
recips = this.recipients[who];
endif
resolve = $mail_agent:resolve_addr(recips, player);
if (resolve[1])
player:tell("Bogus addresses: ", $string_utils:english_list(resolve[1]));
else
player:tell(dobjstr ? ("Mail to " + $mail_agent:name_list(@recips)) + " actually
goes to " | "Your mail will actually go to ", $mail_agent:name_list(@resolve[2]));
endif
.
showlists:
player:tell_lines({"Available aliases:", ""});
for c in ((dobjstr == "all") ? $object_utils:descendants($mail_recipient) | $mail_agent.contents)
if (c:is_usable_by(player) || c:is_readable_by(player))
c:look_self();
endif
endfor
.
subsc*ribe:
player:tell("This command is obsolete. Use @subscribe instead. See `help @subscribe'");
return;
if (!iobjstr)
player:tell("Usage: ", verb, " [
unsubsc*ribe:
if (!iobjstr)
player:tell("Usage: ", verb, " [
parse_msg_headers(slow):
"parse_msg_headers(msg,flags)";
" parses msg to extract reply recipients and construct a subject line";
" if the \"all\" flag is present, reply goes to all of the original recipients";
" returns a list {recipients, subjectline} or 0 in case of error.";
msg = args[1];
replyall = "all" in args[2];
recipients = $mail_agent:parse_address_field(msg[2] + (replyall ? msg[3] | ""));
subject = msg[4];
if (subject == " ")
subject = "";
endif
noreplyto = 1;
for line in (msg[1..("" in msg) || length(msg)])
if (typeof(line) != STR)
"Skip it";
elseif (index(line, "Subject:") == 1)
subject = $string_utils:triml(line[9..length(line)]);
elseif ((rt = index(line, "Reply-to:") == 1) || (noreplyto && ((index(line, "From:")
== 1) || (replyall && (index(line, "To:") == 1)))))
if (rt)
noreplyto = 0;
recipients = {};
endif
recipients = {@recipients, @$mail_agent:parse_address_field(line)};
endif
endfor
if (subject && (index(subject, "Re: ") != 1))
subject = "Re: " + subject;
endif
recips = {};
for o in (recipients)
if (o == #0)
player:tell("Sorry, but I can't parse the header of that message.");
return 0;
elseif ((!valid(o)) || (!(is_player(o) || ($mail_recipient in $object_utils:ancestors(o)))))
player:tell(o, " is no longer a valid player or maildrop; ignoring that recipient.");
elseif (o != player)
recips = setadd(recips, o);
endif
endfor
return {recips, subject};
.
retain_session_on_exit: return this:ok(who = args[1]) && (this.sending[who] || pass(@args)); . no_littering_msg:
"recall that this only gets called if :retain_session_on_exit returns true";
return (this:ok(who = player in this.active) && (!this:changed(who))) ? {"Your message
is in transit."} | this.(verb);
.
local_editing_info:
lines = {"To: " + (toline = $mail_agent:name_list(@args[1])), "Subject: "
+ $string_utils:trim(subject = args[2])};
if (args[3])
lines = {@lines, "Reply-to: " + $mail_agent:name_list(@args[3])};
endif
lines = {@lines, "", @args[4]};
return {tostr("MOOMail", subject ? ("(" + subject) + ")" | (("-to(" + toline) + ")")),
lines, "@@sendmail"};
.
not-to*: uncc*::
if (!(who = this:loaded(player)))
player:tell(this:nothing_loaded_msg());
else
recips = this.recipients[who];
nonmrs = {};
mrs = {};
for o in (recips)
if ($object_utils:isa(o, $mail_recipient))
mrs = {@mrs, o};
else
nonmrs = {@nonmrs, o};
endif
endfor
for a in (args)
if (!a)
player:tell("\"\"?");
return;
elseif (valid(aobj = $mail_agent:match_recipient(a)) && (aobj in recips))
elseif ($failed_match != (aobj = $string_utils:literal_object(a)))
if (!(aobj in recips))
player:tell(aobj, " was not a recipient.");
return;
endif
elseif ((a[1] == "*") && valid(aobj = $string_utils:match(a[2..length(a)],
mrs, "aliases")))
elseif ((a[1] != "*") && valid(aobj = $string_utils:match(a, nonmrs, "aliases")))
elseif (valid(aobj = $string_utils:match(a, recips, "aliases")))
else
player:tell("couldn't find \"", a, "\" in To: list.");
return;
endif
recips = setremove(recips, aobj);
endfor
this.recipients[who] = recips;
this:set_changed(who, 1);
player:tell("Your message is now to ", this:recipient_names(who), ".");
endif
.
PROPERTY DATA:       replytos       recipients       subjects       sending |