/
;var p, new; if(!(| valid($irc_connection) |)) { new = $connection.spawn(); new.set_objname('irc_connection);}
;var p, new; if(!(| valid($irc) |)) { new = $connection_interface.spawn(); new.set_objname('irc);} $irc.chparents($connection_interface,$daemon);
;as $irc<$root>;trusted_by = [$irc_connection];
;as $irc<$root>;flags = ['variables, 'methods, 'code];
;as $irc<$root>;created_on = 857088844;
;as $irc<$root>;inited = 1;
;as $irc<$has_commands>;shortcuts = #[];
;as $irc<$has_commands>;remote = #[];
;as $irc<$has_commands>;local = #[];
@av $irc,connection = 0
;as $irc<$irc>;connection = 0;
;as $irc<$has_settings>;defined_settings = #[];
;as $irc<$has_settings>;local_settings = #[];
;as $irc<$has_settings>;settings = #[];
@program $irc.close() +access=pub
  (> .perms(sender()) <);
  (> $sys.destroy_sender() <);
  
  // $#Edited: 27 Feb 97 15:08 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.port() +access=pub
  return 6667;
  
  // $#Edited: 27 Feb 97 15:44 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.server() +access=prot
  return "phoenix.az.us.undernet.org";
  
  // $#Edited: 10 Feb 97 17:21 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.do_ping() +access=prot
  arg conn, args, text;
  
  conn.write_string("PONG :" + text + "\n");
  
  // $#Edited: 11 Feb 97 02:52 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.connection_going_away() +access=pub
  arg [args];
  
  (> .close() <);
  
  // $#Edited: 27 Feb 97 15:08 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.connection() +access=pub
  return connection;
  
  // $#Edited: 27 Feb 97 15:08 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.new() +access=pub
  arg [ignored];
  
  throw(~no, "Don't use .new on a child of $irc.");
  
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.new_connection() +access=pub
  arg this, host, port;
  
  // $#Edited: 27 Feb 97 15:08 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.set_connection() +access=pub
  arg c;
  
  (> .perms(caller(), definer()) <);
  connection = c;
  
  // $#Edited: 27 Feb 97 15:08 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.daemon_shutdown() +access=pub
  var i;
  
  throw(~no, "$irc doesn't work that way.");
  
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.connection_starting() +access=pub
  arg addr, port;
  
  // $#Edited: 27 Feb 97 15:08 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.open_irc_connection() +access=pub
  arg [args];
  var line;
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  .set_connection($irc_connection.new());
  catch any {
    .connection().open_connection($network.ip(.server()), .port());
  } with {
    line = "Can't connect to IRC server: " + traceback()[1][2];
    (| .connection().close() |);
    return line;
  }
  .connection().write_string("NICK " + $motd.server_name() + "\n");
  .connection().write_string("USER " + $motd.server_name() + " unused1 unused2 :" + $motd.server_title() + "\n");
  return .connection();
  
  // $#Edited: 09 Feb 97 02:15 $user_neale
  // $#Edited: 09 Feb 97 22:06 $user_neale
  // $#Edited: 27 Feb 97 15:48 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.
@program $irc.parse_line() +access=pub
  arg buf;
  var conn, line, args, text, ctcp, func;
  
  if (buf[1] == 58) {
    buf = subbuf(buf, 2, buf.length() - 1);
  } else {
    func = 1;
  }
  line = buf.to_string();
  if (line.match_regexp("shit|fuck|bitch|cunt|asshole|asswipe|clit")) {
    return;
  }
  conn = sender();
  args = explode(explode(line, ":")[1], " ");
  
  // extract text and check for CTCP stuff
  catch any {
    text = (line.regexp("^.[^:]+:(.*)$"))[1];
    ctcp = subbuf(buf, (`[58] in buf) + 1, buf.length() - (`[58] in buf));
    ctcp = ctcp[1] == 1 && ctcp[ctcp.length()] == 1;
  }
  if (func) {
    func = args[1];
  } else if ((args[2] == "PRIVMSG" || args[2] == "NOTICE") && ctcp) {
    func = "C" + args[2];
  } else {
    func = args[2];
  }
  .(tosym("do_" + lowercase(func)))(conn, args, text);
  
  // $#Edited: 09 Feb 97 22:41 $user_neale
  // $#Edited: 25 Feb 97 18:05 $user_neale
  // $#Edited: 25 Feb 97 19:52 $user_neale
  // $#Edited: 27 Feb 97 17:47 $user_neale
.











;var p, new; if(!(| valid($irc_connection) |)) { new = $connection.spawn(); new.set_objname('irc_connection);}
;as $irc_connection<$root>;manager = $irc_connection;
;as $irc_connection<$root>;inited = 1;
;as $irc_connection<$root>;created_on = 855612795;
;as $irc_connection<$root>;managed = [$irc_connection];
;as $irc_connection<$root>;trusted = [$irc];
;as $irc_connection<$root>;quota = 10000;
;as $irc_connection<$root>;quota_exempt = 1;
;as $irc_connection<$root>;child_index = 123;
;as $irc_connection<$root>;writes = [];
;as $irc_connection<$root>;flags = ['methods, 'code];
;as $irc_connection<$connection>;buffer = `[];
;as $irc_connection<$connection>;remote_addr = "";
;as $irc_connection<$connection>;local_addr = "";
;as $irc_connection<$connection>;line_buffer = [];
;as $irc_connection<$connection>;timeout = 300;
;as $irc_connection<$connection>;tid = -1;
@av $irc_connection,buffer = 0
;as $irc_connection<$irc_connection>;buffer = 0;
@av $irc_connection,line_buffer = 0
;as $irc_connection<$irc_connection>;line_buffer = 0;
@program $irc_connection.connect() +access=driver
  arg task_id;
  
  $scheduler.resume(task_id, 'success);
  
  // $#Edited: 10 Feb 97 23:26 $user_neale
.
@program $irc_connection.failed() +access=driver
  arg task_id, reason;
  
  $scheduler.resume(task_id, reason);
  
  // $#Edited: 10 Feb 97 23:26 $user_neale
.
@program $irc_connection.open_connection() +access=pub
  arg host, port;
  
  (> .perms(sender()) <);
  (> pass(host, port) <);
  buffer = `[];
  line_buffer = [];
  return $scheduler.suspend(this());
  
  // $#Edited: 10 Feb 97 23:26 $user_neale
.
@program $irc_connection.new() +access=pub
  var child, daemon, port, i;
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  child = .spawn();
  
  // do perms stuff
  child.add_writer(sender());
  child.add_writer(this());
  child.new_interface(sender());
  return child;
  
  // $#Edited: 10 Feb 97 23:26 $user_neale
.
@program $irc_connection.parse() +access=driver
  arg incoming;
  var lines, line, index;
  
  lines = (buffer + incoming + `[10]).break_lines();
  index = lines.length();
  buffer = lines[index];
  lines = lines.delete(index);
  line_buffer += lines;
  while (line_buffer) {
    line = line_buffer[1];
    line_buffer = line_buffer.delete(1);
    (| .parse_line(line) |);
  }
  
  // $#Edited: 11 Feb 97 02:18 $user_neale
.









;var p, new; if(!(| valid($irc_user) |)) { new = $body.spawn(); new.set_objname('irc_user);}
;as $irc_user<$root>;quota_exempt = 1;
;as $irc_user<$root>;flags = ['variables, 'methods, 'code, 'fertile];
;as $irc_user<$root>;created_on = 855660002;
;as $irc_user<$root>;inited = 1;
;as $irc_user<$root>;child_index = 2832;
;as $irc_user<$root>;quota = 75000;
;as $irc_user<$has_commands>;shortcuts = #[];
;as $irc_user<$has_commands>;remote = #[];
;as $irc_user<$has_commands>;local = #[];
;as $irc_user<$has_settings>;defined_settings = #[];
;as $irc_user<$has_settings>;local_settings = #[];
;as $irc_user<$has_settings>;settings = #[];
;as $irc_user<$has_name>;name = ['prop, "Generic IRC User", "Generic IRC User"];
;as $irc_user<$has_gender>;gender = $gender_neuter;
;as $irc_user<$described>;prose = [];
;as $irc_user<$location>;contents = [];
;as $irc_user<$located>;location = $body_cave;
;as $irc_user<$located>;obvious = 1;
@av $irc_user,uhost = 0
;as $irc_user<$irc_user>;uhost = 0;
@av $irc_user,real_name = 0
;as $irc_user<$irc_user>;real_name = 0;
@av $irc_user,server = 0
;as $irc_user<$irc_user>;server = 0;
@av $irc_user,ircop = 0
;as $irc_user<$irc_user>;ircop = 0;
@av $irc_user,lag = 0
;as $irc_user<$irc_user>;lag = 0;
@av $irc_user,lag_timestamp = 0
;as $irc_user<$irc_user>;lag_timestamp = 0;
@program $irc_user._tell() +access=pub
  arg [args];
  
  return;
  
  // $#Edited: 11 Feb 97 04:27 $user_neale
.
@program $irc_user.set_real_name() +access=pub
  arg text;
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  real_name = text;
  
  // $#Edited: 12 Feb 97 03:24 $user_neale
.
@program $irc_user.set_server() +access=pub
  arg text;
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  server = text;
  
  // $#Edited: 12 Feb 97 03:24 $user_neale
.
@program $irc_user.set_ircop() +access=pub
  arg bool;
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  ircop = bool;
  
  // $#Edited: 12 Feb 97 03:24 $user_neale
.
@program $irc_user.uhost() +access=pub
  return uhost;
  
  // $#Edited: 12 Feb 97 03:25 $user_neale
.
@program $irc_user.real_name() +access=pub
  return real_name;
  
  // $#Edited: 12 Feb 97 03:25 $user_neale
.
@program $irc_user.server() +access=pub
  return server;
  
  // $#Edited: 12 Feb 97 03:25 $user_neale
.
@program $irc_user.ircop() +access=pub
  return ircop;
  
  // $#Edited: 12 Feb 97 03:25 $user_neale
.
@program $irc_user.description() +access=pub
  arg flags;
  var line, desc;
  
  desc = [(<$ctext_frob, [[(<$format, ["subj", [], [.name()], 'do_subj]>)], #[]]>)];
  line = .name() + " is an IRC user from " + .uhost();
  if (.real_name()) {
    line += " (" + .real_name() + ")";
  }
  desc += [line];
  if (.server()) {
    desc += ["They are on the IRC server " + .server()];
  }
  if (.lag() > -1) {
    desc += ["They are " + $time.to_english(.lag() / 2) + " lagged; this was last verified " + $time.to_english(time() - .lag_timestamp()) + " ago."];
  }
  return desc;
  
  // $#Edited: 12 Feb 97 03:30 $user_neale
.
@program $irc_user.set_uhost() +access=pub
  arg text;
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  uhost = text;
  
  // $#Edited: 12 Feb 97 03:35 $user_neale
.
@program $irc_user.set_lag() +access=pub
  arg time;
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  lag = time() - time + 1;
  lag_timestamp = time;
  
  // $#Edited: 13 Feb 97 21:27 $user_neale
.
@program $irc_user.lag() +access=pub
  if (lag == 0) {
    return -1;
  } else {
    return lag - 1;
  }
  
  // $#Edited: 13 Feb 97 21:54 $user_neale
.
@program $irc_user.lag_timestamp() +access=pub
  return lag_timestamp;
  
  // $#Edited: 14 Feb 97 03:44 $user_neale
.
@program $irc_user.irc_name() +access=pub
  var name;
  
  name = .name();
  return substr(name, 1, name.length() - 1);
.











;var p, new; if(!(| valid($irc_room) |)) { new = $place.spawn(); new.set_objname('irc_room);} $irc_room.chparents($place,$irc);
;as $irc_room<$root>;flags = ['variables, 'methods, 'code];
;as $irc_room<$root>;created_on = 854679629;
;as $irc_room<$root>;inited = 1;
;as $irc_room<$root>;quota_exempt = 1;
;as $irc_room<$root>;trusted = [];
;as $irc_room<$root>;managed = [];
;as $irc_room<$root>;writes = [];
;as $irc_room<$command_cache>;shortcut_cache = [];
;as $irc_room<$command_cache>;local_cache = #[["@kick", ["@kick"]]];
;as $irc_room<$command_cache>;remote_cache = #[["@rewho", [["@rewho"], #[[$irc_room, 1]]]], ["@lock", [["@lock"], #[[$thing, 666], [$exit, 1]]]], ["@unlock", [["@unlock"], #[[$thing, 666], [$exit, 1]]]], ["@boot", [["@boot"], #[[$thing, 666]]]]];
;as $irc_room<$has_commands>;shortcuts = #[];
;as $irc_room<$has_commands>;remote = #[["@rewho", [["@rewho", "*", "@rewho <this>", 'rewho, #[[1, ['this, []]]]]]]];
;as $irc_room<$has_commands>;local = #[["@kick", [["@kick", "*", "@kick <descendant of $irc_user>", 'kick_cmd, #[[1, ['descendant, [$irc_user]]]]]]]];
;as $irc_room<$has_settings>;defined_settings = #[];
;as $irc_room<$has_settings>;local_settings = ["realm"];
;as $irc_room<$has_settings>;settings = #[];
;as $irc_room<$has_name>;name = ['uniq, "IRC Room", "the IRC Room"];
;as $irc_room<$has_gender>;gender = $gender_neuter;
;as $irc_room<$described>;prose = <$ctext_frob, [["Holograms of people are projected into this otherwise empty white room from an unknown source; their voices are expertly made to originate from the people they correspond to."], #[['this, $irc_room]]]>;
;as $irc_room<$location>;contents = [];
;as $irc_room<$place>;entrances = [];
;as $irc_room<$place>;exits = [];
@av $irc_room,real_nick = 0
;as $irc_room<$irc_room>;real_nick = 0;
@av $irc_room,users = #[]
;as $irc_room<$irc_room>;users = #[];
@av $irc_room,connected = 0
;as $irc_room<$irc_room>;connected = 0;
@av $irc_room,channel = "#testing_123"
;as $irc_room<$irc_room>;channel = "#testing_123";
@av $irc_room,lag_times = 0
;as $irc_room<$irc_room>;lag_times = 0;
;as $irc_room<$irc>;connection = 0;
@program $irc_room.quad2num +access=pub
  arg quad;
  var a, b, c, d, ah, al, ip, iph, ipl;

  [a, b, c, d] = explode(quad, ".").mmap('to_number);
  ah = a / 128;
  al = a % 128;
  ip = ((al * 256 + b) * 256 + c) * 256 + d;
  if (ah > 0) {
    iph = ip / 1000000000;
    ip = ip % 1000000000;
    ip = ip + 147483648;
    iph = iph + ip / 1000000000 + 2;
    ipl = ip % 1000000000;
    return iph.to_string() + ipl.to_string();
  } else {
    return ip.to_string();
  }

  // $#Edited: 08 Feb 97 18:25 $user_neale
.
@program $irc_room.dcc_chat() +access=prot
  arg conn, nick;
  
  .ctcp(conn, 'msg, nick, "DCC CHAT chat " + .quad2num($sys.server_info('server_ip)) + " " + $login_daemon.current_port().to_string());
  
  // $#Edited: 11 Feb 97 15:44 $user_neale
  // $#Edited: 11 Feb 97 23:04 $user_neale
.
@program $irc_room.do_quit() +access=prot
  arg conn, args, text;
  var nick;
  
  nick = .get_nick(args);
  if (text.match_regexp("^([A-Za-z0-9*_-]+\.)+[A-Za-z0-9_-]+ ([A-Za-z0-9*_-]+\.)+[A-Za-z0-9_-]+$")) {
    text = "'s image goes on the fritz and fuzzes out.";
  } else {
    text = " " + $code_lib.punctuation_type(text) + "s, \"" + text + "\"; then disappears.";
  }
  .say(nick + text);
  .del_user(nick);
  
  // $#Edited: 10 Feb 97 23:48 $user_neale
.
@program $irc_room.do_002() +access=prot
  arg conn, args, text;
  
  conn.write_string("JOIN " + .channel() + "\n");
  
  // $#Edited: 09 Feb 97 22:35 $user_neale
  // $#Edited: 10 Feb 97 23:48 $user_neale
.
@program $irc_room.do_nick() +access=prot
  arg conn, args, text;
  var nick, newnick;
  
  nick = .get_nick(args);
  newnick = text + "*";
  .say(nick + " is now known as " + newnick + ".");
  .user(nick).set_name(newnick, 'prop);
  users = users.add(newnick, users[nick]).del(nick);
  
  // $#Edited: 10 Feb 97 23:48 $user_neale
.
@program $irc_room.do_privmsg() +access=prot
  arg conn, args, text;
  var split;
  
  if (args[3] == .channel()) {
    .say(.get_nick(args) + " " + $code_lib.punctuation_type(text) + "s, \"" + text + "\"");
  } else {
    switch (text) {
      case "chat":
        .dcc_chat(conn, explode(args[1], "!")[1]);
      case "who":
        conn.write_string("PRIVMSG " + explode(args[1], "!")[1] + " :");
        conn.write_string(.contents().english_name_list());
        conn.write_string("\n");
    }
  }
  
  // $#Edited: 11 Feb 97 23:02 $user_neale
.
@program $irc_room.do_join() +access=prot
  arg conn, args, text;
  var nick, host;
  
  [nick, host] = explode(args[1], "!");
  if (nick == real_nick) {
    return;
  }
  nick = .get_nick(args);
  .say(nick + " (" + host + ") appears.");
  return .add_user(conn, nick, host);
  
  // $#Edited: 11 Feb 97 13:53 $user_neale
.
@program $irc_room.do_part() +access=prot
  arg conn, args, text;
  var nick;
  
  nick = .get_nick(args);
  .say(nick + " disappears.");
  .del_user(nick);
  
  // $#Edited: 10 Feb 97 02:25 $user_neale
  // $#Edited: 10 Feb 97 23:48 $user_neale
.
@program $irc_room.kick_cmd() +access=pub
  arg cmdstr, com, luser;
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  if (!$irc_user in luser.parents()) {
    sender().tell(luser.name() + " is not an IRC user.");
    return;
  }
  .connection().write_string("KICK " + .channel() + " " + luser.irc_name() + " :" + sender().name() + "\n");
  sender().tell("Attempting to kick " + luser.name() + " off.");
.
@program $irc_room.say() +access=prot
  arg text;
  
  // use this for announcing messages that you don't want to go to IRC.
  .announce('say, text);
  
  // $#Edited: 10 Feb 97 02:32 $user_neale
  // $#Edited: 10 Feb 97 02:34 $user_neale
  // $#Edited: 10 Feb 97 23:48 $user_neale
.
@program $irc_room.do_mode() +access=prot
  arg conn, args, text;
  var nick, plus, i, j;
  
  nick = .get_nick(args);
  plus = 1;
  j = 1;
  for i in [1 .. args[4].length()] {
    switch (args[4][i]) {
      case "+":
        plus = 1;
      case "-":
        plus = 0;
      case "o":
        if (plus) {
          .say(nick + " gives " + args[4 + j] + "* ops.");
        } else {
          .say(nick + " takes away " + args[4 + j] + "*'s ops.");
        }
        ++j;
      case "b", "l", "v", "k":
        .say(nick + " fiddles with the 3-D projector.");
        ++j;
      default:
        .say(nick + " fiddles with the 3-D projector.");
    }
  }
  
  //.say("You hear the distant churning of machinery.");
  //["Cubbi!dsmr@yu-nmr.chem.msu.su", "MODE", "#disney", "+bb", "foo!*bar@bar.foo", "and!the*@other.one", 0]
  //["W!cservice@undernet.org", "MODE", "#disney", "+o", "Copper", 0]
  // $#Edited: 11 Feb 97 23:05 $user_neale
.
@program $irc_room.do_cnotice() +access=prot
  arg conn, args, text;
  var split;
  
  split = text.regexp("^([A-Z]+) (.*)$");
  if (split[1] == "DCC") {
    split = text.regexp("^(DCC [A-Z]+) (.*)$");
  }
  if (args[3] == real_nick && split[1] == "PING") {
    (| .user(.get_nick(args)).set_lag(split[2].to_number()) |);
  } else {
    throw(~ctcp, "unknown notice");
  }
  
  // $#Edited: 13 Feb 97 21:57 $user_neale
.
@program $irc_room.do_kick() +access=prot
  arg conn, args, text;
  var nick;
  
  nick = .get_nick(args);
  if (nick == .real_nick() + "*") {
    .say(text + " kicks " + args[4] + "* out.");
  } else {
    .say(nick + " kicks " + args[4] + "* out, " + $code_lib.punctuation_type(text) + "ing, \"" + text + "\"");
  }
  .del_user(args[4] + "*");
  
  // $#Edited: 10 Feb 97 23:48 $user_neale
.
@program $irc_room.do_topic() +access=prot
  arg conn, args, text;
  
  .say(.get_nick(args) + " sets the topic to: " + text);
  
  // $#Edited: 10 Feb 97 20:47 $user_neale
  // $#Edited: 10 Feb 97 23:48 $user_neale
.
@program $irc_room.announce() +access=pub
  arg line, [rest];
  var buf;
  
  if (line != 'say) {
    if (!.connected()) {
      return (> pass(line, @rest) <);
    }
    catch any {
      switch (type(line)) {
        case 'string:
          .connection().write_string("PRIVMSG " + .channel() + " :" + strsub(line, "fnord", "") + "\n");
        case 'frob:
          buf = ("PRIVMSG " + .channel() + " :").to_buffer();
          buf += $parse_lib.filter_ctext(line, #[['formatter, $text_format]]);
          .connection().write_buffer(buf);
      }
    }
    return (> pass(line, @rest) <);
  } else {
    return (> pass(@rest) <);
  }
  
  // $#Edited: 11 Feb 97 02:22 $user_neale
.
@program $irc_room.do_cprivmsg() +access=prot
  arg conn, args, text;
  var split, buf;
  
  split = text.regexp("^([A-Z]+) (.*)$");
  if (split[1] == "DCC") {
    split = text.regexp("^(DCC [A-Z]+) (.*)$");
  }
  if (split[1] == "PING") {
    buf = ("NOTICE " + explode(args[1], "!")[1] + " :").to_buffer();
    buf += `[1];
    buf += text.to_buffer();
    buf += `[1, 13];
    conn.write_buffer(buf);
    .ping(conn, explode(args[1], "!")[1]);
  } else if (args[3] == .channel()) {
    if (split[1] == "ACTION") {
      .say(.get_nick(args) + " " + split[2]);
    }
  } else if (split[1] == "DCC CHAT") {
    .dcc_chat(conn, explode(args[1], "!")[1]);
  } else {
    throw(~ctcp, "no response");
  }
  
  // $#Edited: 11 Feb 97 03:18 $user_neale
.
@program $irc_room.del_user() +access=prot
  arg nick;
  
  (| .user(nick).destroy() |);
  (| (users = users.del(nick)) |);
  
  // $#Edited: 12 Feb 97 01:08 $user_neale
.
@program $irc_room.ctcp() +access=prot
  arg conn, type, nick, text;
  
  switch (type) {
    case 'msg:
      conn.write_string("PRIVMSG");
    case 'notice:
      conn.write_string("NOTICE");
    default:
      throw(~type, "unknown type");
  }
  conn.write_string(" " + nick + " :");
  conn.write_buffer(`[1]);
  conn.write_string(text);
  conn.write_buffer(`[1, 13]);
  
  // $#Edited: 11 Feb 97 15:58 $user_neale
  // $#Edited: 11 Feb 97 23:04 $user_neale
.
@program $irc_room.add_user() +access=prot
  arg conn, nick, uhost;
  var body;
  
  if (nick in users.keys()) {
    return .user(nick);
  }
  if (nick == real_nick + "*") {
    return 0;
  }
  body = $irc_user.spawn();
  body.set_name(nick, 'prop);
  body.set_uhost(uhost);
  body.move_to(this());
  users = users.add(nick, body);
  
  // Launch a WHOIS on the nick to get extended information, and ping them to calculate lag
  nick = substr(nick, 1, nick.length() - 1);
  conn.write_string("WHOIS " + nick + "\n");
  .ping(conn, nick);
  return body;
  
  // $#Edited: 12 Feb 97 01:23 $user_neale
.
@program $irc_room.do_001() +access=prot
  arg conn, args, text;
  
  // 001 is the first message we get.  It tells us what our nick really is.
  real_nick = args[3];
  .say("The IRC connection has been re-established.");
  .set_connected(1);
  
  // $#Edited: 12 Feb 97 02:39 $user_neale
.
@program $irc_room.do_352() +access=prot
  arg conn, args, text;
  
  // 352 is the result of a WHO command, it lists usernames and real names.  We just want the username, .add_user will launch a whois to get the rest.
  .add_user(conn, args[8] + "*", args[5] + "@" + args[6]);
  
  // $#Edited: 12 Feb 97 03:10 $user_neale
.
@program $irc_room.connection() +access=prot
  var conn;
  
  conn = pass();
  if (!valid(conn)) {
    .say("The IRC connection has been lost.  I will try to reconnect.");
    .set_connected(0);
    .open_irc_connection();
    return pass();
  }
  return conn;
  
  // $#Edited: 12 Feb 97 02:30 $user_neale
  // $#Edited: 27 Feb 97 21:58 $user_neale
.
@program $irc_room.server() +access=pub
  //return "irc.wisp.net";
  return "lowell.ma.us.undernet.org";
  
  // $#Edited: 27 Feb 97 15:11 $user_neale
.
@program $irc_room.pulse() +access=pub
  if (caller() != $heart) {
    throw(~perm, "go away.");
  }
  if (.connected()) {
    .ping(.connection(), .channel());
  }
  
  // $#Edited: 13 Feb 97 20:27 $user_neale
.
@program $irc_room.do_311() +access=prot
  arg conn, args, text;
  
  // 311 RPL_WHOISUSER
  .user(args[4] + "*").set_real_name(text);
  
  // $#Edited: 13 Feb 97 18:15 $user_neale
.
@program $irc_room.do_312() +access=prot
  arg conn, args, text;
  
  // 312 RPL_WHOISSERVER
  .user(args[4] + "*").set_server(args[5] + " (" + text + ")");
  
  // $#Edited: 13 Feb 97 18:11 $user_neale
.
@program $irc_room.rewho() +access=pub
  arg [ignored];
  
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  .reap();
  .connection().write_string("WHO " + .channel() + "\n");
  sender().tell("Rewhoing.");
  
  // $#Edited: 12 Feb 97 20:29 $user_neale
.
@program $irc_room.reap() +access=prot
  var a;
  
  for a in (users.keys()) {
    .del_user(a);
  }
  
  // $#Edited: 12 Feb 97 18:21 $user_neale
.
@program $irc_room.do_333() +access=prot
  arg conn, args, text;
  
  .rewho();
  
  // $#Edited: 13 Feb 97 20:52 $user_neale
.
@program $irc_room.do_366() +access=prot
  arg conn, args, text;
  
  // 366, end of NAMES, is a good time to recount the users on the channel, since it gets sent when we first join.
  .rewho();
  
  // $#Edited: 13 Feb 97 20:54 $user_neale
.
@program $irc_room.open_irc_connection() +access=pub
  (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
  .set_connected(0);
  $heart.add_heartbeat(420);
  (> pass() <);
  
  // $#Edited: 13 Feb 97 21:37 $user_neale
  // $#Edited: 27 Feb 97 15:28 $user_neale
.
@program $irc_room.connected() +access=pub
  return connected;
  
  // $#Edited: 13 Feb 97 21:51 $user_neale
.
@program $irc_room.ping() +access=prot
  arg conn, nick;
  var buf;
  
  buf = ("PRIVMSG " + nick + " :").to_buffer();
  buf += `[1];
  buf += "PING ".to_buffer();
  buf += time().to_string().to_buffer();
  buf += `[1, 13];
  conn.write_buffer(buf);
  
  // $#Edited: 13 Feb 97 22:23 $user_neale
.
@program $irc_room.channel() +access=pub
  return channel;
  
  // $#Edited: 13 Feb 97 22:23 $user_neale
.
@program $irc_room.set_connected() +access=pub
  arg bool;
  
  connected = bool;
  if (connected == 0) {
    .reap();
  }
  
  // $#Edited: 13 Feb 97 23:00 $user_neale
.
@program $irc_room.description() +access=pub
  arg flags;
  var open, desc, lag, laggers, user, line;
  
  for user in (.contents()) {
    if ($irc_user in user.parents() && user.lag() > 0 && time() - user.lag_timestamp() < 1200) {
      lag += user.lag();
      ++laggers;
    }
  }
  if (.connected()) {
    open = "open";
    if (laggers > 0) {
      open += ", with " + $time.to_english(lag / laggers / 2) + " average recent lag";
    }
  } else {
    open = "closed";
  }
  line = .name() + " (the connection is " + open + ")";
  desc = [(<$ctext_frob, [[(<$format, ["subj", [], [line], 'do_subj]>)], #[]]>)];
  if ((| flags['prose] |)) {
    desc += [.prose()];
  }
  desc += .format_contents(flags) + .format_exits(.visible_exits(), flags);
  return desc;
  
  // $#Edited: 14 Feb 97 01:55 $user_neale
.
@program $irc_room.do_313() +access=pub
  arg conn, args, text;
  
  // 313 RPL_WHOISOPERATOR
  .user(args[4] + "*").set_ircop(1);
  
  // $#Edited: 14 Feb 97 03:29 $user_neale
.
@program $irc_room.get_nick() +access=prot
  arg args;
  
  return explode(args[1], "!")[1] + "*";
  
  // $#Edited: 14 Feb 97 13:50 $user_neale
.
@program $irc_room.user() +access=prot
  arg nick;
  
  return users[nick];
  
  // $#Edited: 14 Feb 97 14:36 $user_neale
.
@program $irc_room.real_nick() +access=pub
  return real_nick;
  
  // $#Edited: 25 Feb 97 14:42 $user_neale
.
@program $irc_room.wallop() +access=prot
  arg line;
  var i;
  
  for i in (.contents()) {
    if ($admin in i.parents()) {
      i.tell("< " + line + " >");
    }
  }
  
  // $#Edited: 25 Feb 97 19:24 $user_neale
.
@program $irc_room.parse_line() +access=pub
  arg buf;
  var err;
  
  //.wallop("| " + buf.to_string() + " |");
  catch any {
    pass(buf);
  } with {
    if ((err = traceback()[1])[1] != ~methodnf) {
      .wallop(err[1] + ": " + err[2] + " [ " + buf.to_string() + " ]");
    }
  }
  
  // $#Edited: 25 Feb 97 18:57 $user_neale
  // $#Edited: 25 Feb 97 19:20 $user_neale
.
@program $irc_room.connection_going_away() +access=pub
  arg [args];
  
  if (!(this() in sender().parents())) {
    throw(~perms, sender() + " is not a child of " + this());
  }
  
  //(> pass() <);
  .say("The IRC connection has been lost.");
  .say("(is_going_away) was called!  Tell Neale!");
  
  // $#Edited: 27 Feb 97 15:08 $user_neale
  // $#Edited: 27 Feb 97 15:24 $user_neale
.
@program $irc_room.do_error() +access=prot
  arg [ignored];
  
  .say("The IRC connection punts.");
  
  // $#Edited: 27 Feb 97 16:56 $user_neale
.
@program $irc_room.port() +access=pub
  return 6668;
  
  // $#Edited: 27 Feb 97 22:01 $user_neale
.