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, []]];
.