parent $utilities object $channels var $root child_index 0 var $root owners [$channels] var $root fertile 0 var $root inited 1 var $channels channels ['all, 'chatter, 'System, 'Admins] var $root blessed [$interaction] var $channels tuners #[['all, 0], ['chatter, 1], ['System, 1], ['Admins, 1]] var $channels senders #[['all, 'admins], ['chatter, 1], ['System, 'admins], ['Admins, 1]] var $channels owners #[] var $channels channel_owner #[['all, $channels], ['chatter, $channels], ['System, $channels], ['Admins, $channels]] var $channels listeners #[['all, 'connected], ['chatter, []], ['System, []], ['Admins, []]] var $channels max_channels_owned 3 var $root owned [$channels] var $root manager $channels var $root writable [$channels] var $root readable ['parameters, 'methods, 'code] var $root trusted [$housekeeper] var $root dbref 'channels method __admins return ($sys.system()) + [$login_interface]; . method del_channel arg channel; var c; if ((sender() != (channel_owner[channel])) && (!(.is_writable_by(sender())))) throw(~perm, "Sender is not the owner of the channel"); ._del_channel(channel); c = owners[sender()]; if (c == 1) owners = dict_del(owners, sender()); else owners = dict_add(owners, sender(), c - 1); . method validate_channel arg channel, [rest]; var x, chars; // receives a string, returns a symbol if valid chars = $string.strip($string.non_alphanumeric(), "-_"); for x in [1 .. strlen(chars)] { if ((chars[x]) in channel) throw(~type, "Channel name can only contain alphanumeric characters"); } if (!channel) throw(~type, "Channel cannot be blank"); if (!rest) { channel = .match_channel(channel); if (!channel) throw(~channenf, "Channel does not exist"); if (listlen(channel) > 1) throw(~ambig, "Channel matches all of: " + ($data.unparse(channel))); channel = channel[1]; } else { channel = tosym(channel); } return channel; . method all_owners if (!(.is_writable_by(sender()))) throw(~perm, "Sender not an owner"); return owners; . method all_listeners if (!(.is_writable_by(sender()))) throw(~perm, "Sender not an owner"); return listeners; . method all_senders if (!(.is_writable_by(sender()))) throw(~perm, "Sender not an owner"); return senders; . method listeners arg channel; var ret; // if (!.is_writable_by(sender())) // throw(~perm, "Sender not an owner"); if (type(listeners[channel]) == 'symbol) ret = .(tosym("__" + tostr(listeners[channel])))(); else ret = listeners[channel]; if (!((sender() == this()) || (sender() in ret))) return []; else return ret; . method senders arg channel; if (sender() != this()) throw(~perm, "Sender not an owner"); if (type(senders[channel]) == 'symbol) return .(tosym("__" + tostr(senders[channel])))(); return senders[channel]; . method match_channel arg channel_name; var channel_matches, channel; channel_matches = []; channel = tosym(channel_name) in channels; if (channel) return [channels[channel]]; for channel in (channels) { if (match_begin(tostr(channel), channel_name)) channel_matches = [@channel_matches, channel]; } return channel_matches; . method allow_send_to arg channel, who, [caller]; var senders; senders = .senders(channel); if (senders == 0) throw(~locked, "Channel is locked"); if (senders == 1) return 1; if (type(senders) == 'list) { if (who in senders) return 1; } if (who == (channel_owner[channel])) return 1; if ((channel == 'System) && caller) return (caller[1]) in senders; return 0; . method allow_tune_in arg channel, who; if ((.senders(channel)) == 0) throw(~locked, "Channel is locked"); if ((tuners[channel]) == 1) return 1; if (type(tuners[channel]) == 'list) { if (who in (tuners[channel])) return 1; } if (who == (channel_owner[channel])) return 1; return 0; . method channels return channels; . method set_channel arg channel_str, [args]; var channel, allowed, senders, listeners; // args: channel_str, allowed, senders, listeners // channel setup: #[['namef, [[allowed], [senders], owner, [listeners]]]]; channel = .validate_channel(channel_str); // basic checks if (!(channel in channels)) throw(~perm, "That channel doesn't exist"); if ((sender() != (channel_owner[channel])) && (!(.is_writable_by(sender())))) throw(~perm, "You are not the owner of the channel"); // get the settings allowed = [@args, 1][1]; senders = [@args, 1, 1][2]; listeners = [@args, [sender()], [sender()], [sender()]][3]; if ((type(senders) == 'symbol) || (type(listeners) == 'symbol)) throw(~type, "Cannot use symbols"); // send it off ._set_channel(channel, allowed, senders, sender(), listeners); . method _del_user_from_channel arg channel, who; var data; if (sender() != this()) throw(~perm, "Sender is not this"); listeners = dict_add(listeners, channel, setremove(listeners[channel], who)); . method _add_user_to_channel arg channel, who; var data; if (sender() != this()) throw(~perm, "Sender is not this"); listeners = dict_add(listeners, channel, (listeners[channel]) + [who]); . method tune_out arg channel; if (!(sender() in (listeners[channel]))) throw(~putz, "You are not tuned into that channel."); ._del_user_from_channel(channel, sender()); . method tune_in arg channel; if (!(channel in channels)) throw(~chnlnf, "Channel is not available, create it first"); if (!(.allow_tune_in(channel, sender()))) throw(~perm, "That is a restricted channel."); if (sender() in (listeners[channel])) throw(~putz, "You are already tuned into that channel"); ._add_user_to_channel(channel, sender()); . method __connected return $user_db.connected(); . method _del_channel arg channel; if (sender() != this()) throw(~perm, "Sender is not this"); tuners = dict_del(tuners, channel); channels = setremove(channels, channel); senders = dict_del(senders, channel); channel_owner = dict_del(channel_owner, channel); listeners = dict_del(listeners, channel); . method new_channel arg channel, allowed, senders, owner, listeners; var c; if (!(.is_writable_by(caller()))) throw(~perm, "Sender not an owner"); // send channel as a string channel = .validate_channel(channel, 'no_search); if (channel in channels) throw(~perm, "That channel already exists"); if (((| owners[sender()] |) == max_channels_owned) && (!(.is_writable_by(sender())))) throw(~perm, ("You can only have " + tostr(max_channels_owned)) + " channels at a time."); ._set_channel(channel, allowed, senders, owner, listeners); // increment ownership c = (owner in dict_keys(owners)) ? (owners[owner]) + 1 | c; owners = dict_add(owners, owner, c); . method init_channels if (sender() != $root) throw(~perm, "Sender is not $root."); tuners = #[['System, 1], ['all, 0], ['Admins, 1]]; channels = ['System, 'all, 'Admins]; senders = #[['System, 'admins], ['all, 'admins], ['Admins, 1]]; owners = #[[$no_one, 3]]; channel_owner = #[['System, $no_one], ['all, $no_one], ['Admins, $no_one]]; listeners = #[['System, []], ['all, 'connected], ['Admins, []]]; max_channels_owned = 3; . method valid_channel arg channel; channel = .validate_channel(channel); if (!(channel in channels)) throw(~chnlnf, "Channel doesn't exist"); return 1; . method all_tuners return tuners; . method _set_channel arg name, tune, send, owner, who; if (sender() != this()) throw(~perm, "Sender is not this"); channels = [@channels, name]; tuners = dict_add(tuners, name, tune); senders = dict_add(senders, name, send); channel_owner = dict_add(channel_owner, name, owner); listeners = dict_add(listeners, name, who); . method announce arg channel, text; var status, who, person, id, x; if (type(channel) == 'string) channel = .validate_channel(channel); if (!(channel in channels)) throw(~chnlnf, "Channel doesn't exist"); if (!(.allow_send_to(channel, sender(), caller()))) throw(~perm, "Sender is not allowed to send to that channel."); for person in (.listeners(channel)) { id = (("<" + tostr(channel)) + " - ") + (sender().namef()); id = (id + ((sender() in (.listeners(channel))) ? "" | ((!(sender().has_ancestor($user))) ? "" | " (tuned out)"))) + "> "; (| person.tell(id + text) |); } . method coreify_channels (| .perms(caller(), $sys) |); channels = ['all, 'chatter, 'System, 'Admins]; tuners = #[['all, 0], ['chatter, 1], ['System, 1], ['Admins, 1]]; senders = #[['all, 'admins], ['chatter, 1], ['System, 'admins], ['Admins, 1]]; owners = #[]; channel_owner = #[['all, this()], ['chatter, this()], ['System, this()], ['Admins, this()]]; listeners = #[['all, 'connected], ['chatter, []], ['System, []], ['Admins, []]]; .