new object $channel_ui: $user_interfaces; var $channel_ui active_channels = #[]; var $channel_ui channel_creation = 1; var $channel_ui channel_dict = #[]; var $channel_ui credits = ["Chuck and Brad"]; var $has_commands local = \ #[["@desc-c?hannel", [["@desc-c?hannel", "* as *", "@desc-c?hannel <any> as <any>", 'describe_channel_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]],\ ["@join-lock-channel|@jlc",\ [["@join-lock-channel|@jlc", "* with|to *", "@join-lock-channel|@jlc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]],\ ["@leave-lock-channel|@llc",\ [["@leave-lock-channel|@llc", "* with|to *", "@leave-lock-channel|@llc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]],\ ["@use-lock-channel|@ulc",\ [["@use-lock-channel|@ulc", "* with|to *", "@use-lock-channel|@ulc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]],\ ["@add-channel-manager|@acm",\ [["@add-channel-manager|@acm", "* to *", "@add-channel-manager|@acm <user> to <any>", 'channel_add_manager, #[[1, ['user, []]], [3, ['any, []]]]]]],\ ["@del-channel-manager|@dcm",\ [["@del-channel-manager|@dcm", "* from *", "@del-channel-manager|@dcm <user> from <any>", 'channel_del_manager, #[[1, ['user, []]], [3, ['any, []]]]]]],\ ["@add-ch?annel|@addcom",\ [["@add-ch?annel|@addcom", "*", "@add-ch?annel|@addcom <any>", 'addcom_cmd, #[[1, ['any, []]]]]]],\ ["@del-ch?annel|@delcom",\ [["@del-ch?annel|@delcom", "*", "@del-ch?annel|@delcom <any>", 'delcom_cmd, #[[1, ['any, []]]]]]],\ ["@purge-channel",\ [["@purge-channel", "*", "@purge-channel <any>", 'channel_purge_cmd, #[[1, ['any, []]]]]]],\ ["@ch?annels",\ [["@ch?annels", "*", "@ch?annels <any:+f?ull +d?etailed>", 'channels_cmd, #[[1, ['any_opt, ["f?ull", "d?etailed"]]]]]]]]; var $has_commands remote = #[]; var $has_commands shortcuts = #[]; var $root created_on = 838251646; var $root flags = ['variables, 'methods, 'code, 'command_cache, 'fertile, 'core]; var $root inited = 1; var $root managed = [$channel_ui]; var $root manager = $channel_ui; var $root trusted_by = [$channel_db]; public method ._broadcast() { arg channel, message; var q; if (!(caller() in [$channel_ui, $user, $sys])) throw(~perm, "You are not allowed to call $channel_ui._broadcast() directly"); for q in ($user_db.connected()) q.channel_msg(channel, message); }; private method ._del_active_channel() { arg key; active_channels = active_channels.del(key); }; public method ._del_channel_dict() { arg key; channel_dict = channel_dict.del(key); }; public method .active_channels() { return active_channels; }; protected method .addcom_cmd() { arg cmdstr, cmd, args; var elements, db, channel, lowerchannel, msg; (> .perms(caller(), 'command) <); elements = args.explode("="); if ((elements.length()) != 2) { return "Syntax: @addcom <alias>=<channel_name>"; } else if (channel_dict.contains(elements[1])) { return "You are already using that alias for a channel."; } else { channel = tosym(elements[2]); lowerchannel = tosym((elements[2]).lowercase()); db = (| $channel_db.search(lowerchannel) |) || 0; if (type(db) == 'list) { if ((type(db[3]) == 'frob) && ((!((db[3]).try(sender()))) && (!($sys.is_system(sender()))))) return ("Sorry, channel " + (db[1])) + " is join-locked."; msg = (("Channel " + (elements[2])) + " added with alias ") + (elements[1]); } else if (.can_create_channel()) { db = [channel, 0, 0, 0, sender(), [sender()], 0, 0]; $channel_db.insert(lowerchannel, db); msg = (("Channel " + (elements[2])) + " created with alias ") + (elements[1]); } else { return "Sorry, that channel doesn't exist, and you are not authorized to create new channels."; } } $channel_db.value_changed(lowerchannel, db.replace(2, (db[2]) + 1)); channel_dict = channel_dict.add(elements[1], db[1]); .channel_on(db[1]); return msg; }; public method .broadcast() { arg channel, msg; var q, spammer_name, message; (> .perms(sender()) <); // is this really a command?. If so, do the command. catch any { switch (msg) { case "who": if ((channel in ($channel_db.system_channels())) && (!($sys.is_system(sender())))) return "Sorry, that's a listen only channel."; return .channel_members(channel); case "off": .channel_off(channel); return; case "on": .channel_on(channel); return; } } with { return (traceback()[1])[2]; } if ((channel in ($channel_db.system_channels())) && (channel != 'All)) return "Sorry, that's a listen only channel."; if (!(active_channels.contains(channel))) return "You must be on a channel to send a message to it."; // check for poses, thinking, etc. spammer_name = .name(); switch (msg[1]) { case ":": message = (spammer_name + " ") + (msg.subrange(2)); case "%": message = ((spammer_name + " . o O ( ") + (msg.subrange(2))) + " )"; case "!": (> .channel_moderator_ok() <); message = msg.subrange(2); default: message = (spammer_name + ": ") + msg; } ._broadcast(channel, message); }; public method .can_create_channel() { if ((sender().has_ancestor($user)) && (($channel_ui.channel_creation()) || ($sys.is_system(sender())))) return 1; else return 0; }; protected method .channel_add_lock_cmd() { arg cmdstr, cmd, this, prep, str; var channel, db, lock, mode, modestr; (> .perms(caller(), 'command) <); if ((cmd[2]) == "j") { mode = 3; modestr = "join"; } else if ((cmd[2]) == "l") { mode = 4; modestr = "leave"; } else { mode = 8; modestr = "use"; } channel = tosym(this.lowercase()); db = (| $channel_db.search(channel) |) || 0; if (type(db) == 'list) { if ((!(sender() in (db[6]))) && (!($sys.is_system(sender())))) { return "Sorry, you're not on the manager list for that channel."; } else if ((str.length()) == 0) { $channel_db.value_changed(channel, db.replace(mode, 0)); return ((("You un-" + modestr) + "lock channel ") + (db[1])) + "."; } else { catch ~objnf, ~parse { lock = $lock_parser.parse(str, sender()); $channel_db.value_changed(channel, db.replace(mode, lock)); return ((((("You " + modestr) + "lock channel ") + (db[1])) + " with ") + (lock.lock_name('thing))) + "."; } with { switch (error()) { case ~objnf: return "Object not found in lock string."; case ~parse: return "Invalid lock string."; } } } } else { return "Channel not found, nothing locked."; } }; public method .channel_add_manager() { arg cmdstr, cmd, user, prep, channel; var db, channel; channel = (| tosym(channel.lowercase()) |) || 0; if (channel == 0) return "@add-channel-manager|@acm <user> to <channel>"; db = (| $channel_db.search(channel) |) || 0; if (db == 0) return "That channel does not exist."; if ((sender() != (db[5])) && (!($sys.is_system(sender())))) return "You are not the channel owner."; if (user in (db[6])) return ((user.name()) + " is already a manager of channel ") + (db[1]); $channel_db.value_changed(channel, db.replace(6, [@db[6], user])); return "Manager added."; }; public method .channel_alias() { arg ch_alias; return (| channel_dict[ch_alias] |) || ""; }; public method .channel_command() { arg cmd, args, opts, detailed, full; var ch, syn, cmd; syn = ("Syntax: " + cmd) + " <channel> <command>"; if (listlen(args) < 2) return [syn, "Where <command> is one of: WHO, OFF, ON, or INFO"]; [ch, cmd, @args] = args; switch (cmd) { case "who": if ((ch in ($channel_db.system_channels())) && (!($sys.is_system(this())))) return "Sorry, that's a listen only channel."; return .channel_members(ch, full); case "off": .channel_off(ch); return; case "on": .channel_on(ch); return; case "info": return; default: return ("Unknown @channel command: " + cmd) + ", should be: WHO, OFF, ON or INFO"; } }; public method .channel_creation() { return channel_creation; }; public method .channel_del_manager() { arg cmdstr, cmd, user, prep, channel; var db, channel; channel = (| tosym(channel.lowercase()) |) || 0; if (channel == 0) return "@add-channel-manager|@acm <user> from <channel>"; db = (| $channel_db.search(channel) |) || 0; if (db == 0) return "That channel does not exist."; if ((sender() != (db[5])) && (!($sys.is_system(sender())))) return "You are not the channel owner."; if (!(user in (db[6]))) return ((user.name()) + " is not a manager of channel ") + (db[1]); $channel_db.value_changed(channel, db.replace(6, (db[6]).del(user))); return "Manager deleted."; }; public method .channel_dict() { return channel_dict; }; public method .channel_member() { arg channel; return channel in dict_values(channel_dict || #[]); }; public method .channel_members() { arg channel, @full; var q, members, name, who, line; members = []; [(full ?= 0)] = full; if (full) { line = ("All members of channel " + channel) + " ('*'=listening, '!'=not connected):"; who = $user_db.user_dbrefs(); } else { line = ("Connected members of channel " + channel) + " ('*'=listening):"; who = $user_db.connected(); } for q in (who) { if (!valid(q)) continue; if (q.channel_member(channel)) { if (q.connected()) name = " " + (q.name()); else name = "!" + (q.name()); if (q.listen_channel(channel)) members += ["*" + name]; else members += [" " + name]; } } return ([line] + ((members.vcolumnize(4, (.linelen()) - 4)).prefix(" "))) + ["---"]; }; public method .channel_moderator_ok() { (> .check_mojo() <); return 1; }; public method .channel_msg() { arg channel, msg; (caller() == definer()) || (> .perms(sender(), 'system) <); if ((channel == 'All) || (active_channels.contains(channel))) .tell((("<" + channel) + "> ") + msg); }; protected method .channel_off() { arg channel; if (active_channels.contains(channel)) { if (channel in ($channel_db.system_channels())) .tell(("<" + channel) + "> You have left this channel."); else .broadcast(channel, ":has left this channel."); active_channels = active_channels.del(channel); } else { .tell("You are not on this channel."); } }; protected method .channel_on() { arg channel; if (!(active_channels.contains(channel))) { active_channels = active_channels.add(channel, 1); if (channel in ($channel_db.system_channels())) .tell(("<" + channel) + "> You have joined this channel"); else .broadcast(channel, ":has joined this channel."); } else { .tell("You are already on this channel."); } }; public method .channel_purge_cmd() { arg cmdstr, cmd, channel; var db, channel, connected, u; channel = (| tosym(channel.lowercase()) |) || 0; if (channel == 0) return "@purge-channel <channel>"; db = (| $channel_db.search(channel) |) || 0; if (db == 0) return "That channel does not exist."; if ((sender() != (db[5])) && (!($sys.is_system(sender())))) return "You are not the channel owner."; $channel_db.remove(channel); connected = $user_db.connected(); for u in ((((($user_db.database()).to_dict()).to_list()).slice(2)).compress()) { if ((u in connected) && (((u.channel_dict()).invert()).contains(db[1]))) u.tell((("<" + (db[1])) + "> Channel deleted by ") + (sender().name())); (| u._del_active_channel(db[1]) |); (| u._del_channel_dict(((u.channel_dict()).invert())[db[1]]) |); pause(); } return "Channel deleted."; }; protected method .channels_cmd() { arg cmdstr, cmd, args; var opts, f, d, cur_channels, cd_keys, cd_values, i, alias, db, active, msg, match_with, match_pattern, tmp, form, add, o; (> .perms(caller(), 'command) <); [args, opts] = args; o = opts.slice(1); if ((f = (| "f?ull" in o |))) f = (opts[f])[3]; if ((d = (| "d?etailed" in o |))) d = (opts[d])[3]; if (listlen(args) > 1) { catch any { cmd = (| ($channel_db.search(args[1]))[1] |); return .channel_members(cmd, f); } with { return (traceback()[1])[2]; } } cd_keys = channel_dict.keys(); cd_values = channel_dict.values(); cur_channels = f ? ((($channel_db.database()).values()).slice(1)) : cd_values; if (args) { match_with = (| .get_setting("match-with", $programmer) |) || 'match_pattern; match_pattern = (| (args[1])[1] |) || ((| .get_setting("match-default", $programmer) |) || "*"); cur_channels = filter f in (cur_channels) where ((f.to_string()).(match_with)(match_pattern) != 0); } if (!cur_channels) return "No channels found."; msg = []; add = []; for i in (cur_channels) { alias = (| cd_keys[i in cd_values] |) || ""; db = (| $channel_db.search(tostr(i)) |); if (type(db) == 'list) { msg += [[(active_channels.contains(i)) ? "*" : " ", alias, tostr(db[1]), (db[7]) || "<no description>"]]; form = "%26r: %50l"; if (d) { tmp = [form.format("Number of users", tostr(db[2])), form.format("Owner", (db[5]).name()), form.format("Managers", ((db[6]).mmap('namef, 'name)).to_english())]; if (db[3]) tmp += [form.format("Join Lock", (db[3]).lock_name())]; if (db[4]) tmp += [form.format("Leave Lock", (db[4]).lock_name())]; if (db[8]) tmp += [form.format("Use Lock", (db[8]).lock_name())]; add += [tmp]; } } else { msg += [[(active_channels.contains(i)) ? "*" : " ", alias, "", "Channel not in database!"]]; } refresh(); } msg = (msg.transpose()).tabulate([["", ""], ["Alias", "-----"], ["Channel", "-------"], ["Description", "-----------"]]); if (d) msg = [msg[1], msg[2], @map i in [3 .. msg.length()] to ([msg[i]] + (add[i - 2])).sum()]; return [@msg, " -----"]; }; protected method .delcom_cmd() { arg cmdstr, cmd, args; var db, channel, del_from_db, msg, dict_var; (> .perms(caller(), 'command) <); del_from_db = 1; msg = ("Channel alias " + args) + " deleted."; if (!args) return ("Syntax: " + cmd) + " <channel>"; dict_var = channel_dict[args]; channel = (| (((channel_dict[args]).to_string()).lowercase()).to_symbol() |) || 0; if (type(channel) == 'symbol) { db = (| $channel_db.search(channel) |) || 0; if (type(db) == 'list) { if ((type(db[4]) == 'frob) && ((!((db[4]).try(sender()))) && (!($sys.is_system(sender()))))) return "Channel leave locked, you can't leave it!"; } else { del_from_db = 0; msg = ("That channel does not seem to be in the channel database. Channel alias " + args) + " deleted."; } } else { return "You do not have that channel alias defined."; } if (del_from_db) $channel_db.value_changed(channel, db.replace(2, (db[2]) - 1)); if (active_channels.contains(dict_var)) .channel_off(dict_var); channel_dict = channel_dict.del(args); return msg; }; protected method .describe_channel_cmd() { arg cmdstr, cmd, channel, prep, desc; var db, channel; (> .perms(caller(), 'command) <); channel = (| tosym(channel.lowercase()) |) || 0; if (channel == 0) return "@desc-ch?annel <channel> as <description>"; db = (| $channel_db.search(channel) |) || 0; if (db == 0) return "That channel does not exist."; if ((!(sender() in (db[6]))) && (!($sys.is_system(sender())))) return "You are not a manager for channel " + (db[1]); $channel_db.value_changed(channel, db.replace(7, desc)); return "Description updated."; }; protected method .init_channel_ui() { channel_dict = #[]; active_channels = #[]; }; public method .listen_channel() { arg channel; if (active_channels.contains(channel)) return 1; return 0; }; public method .uninit_channel_ui() { var c, channel, db; for c in (.channel_dict()) { if ((| active_channels[c[2]] |) || 0) .channel_off(c[2]); channel = (| tosym(((c[2]).to_string()).lowercase()) |) || 0; if (type(channel) == 'symbol) { db = (| $channel_db.search(channel) |) || 0; if (type(db) == 'list) $channel_db.value_changed(channel, db.replace(2, (db[2]) - 1)); } } active_channels = #[]; channel_dict = #[]; };