muc_commands.vala
author Stiletto <blasux@blasux.ru>
Mon, 05 Nov 2012 23:54:44 +0400
changeset 12 d3e36b368fc5
permissions -rw-r--r--
iq, commands, makefile up

using Gee;

class ModuleMucCommands : Module {
    protected weak ModuleMuc muc;
    public delegate void CommandHandler(ModuleMuc.Conference conf, ModuleMuc.Occupant user, string command, string? arguments);
    public class Command : Object {
        public weak Module mod;
        public CommandHandler hnd;
    }
    protected HashMap<string,Command> commands;

    public string getconf(string jid, string key, string? def) {
        var res = cfg["muc "+jid, key];
        if (res==null) res = cfg["muc", key];
        if (res==null) res = def;
        return res;
    }
    public bool register(string command, Module mod, CommandHandler handler) {
        var cmd = new Command();
        cmd.mod = mod; /* this will cause "copying delegates is discouraged" warning. that's okay, this delegate's data needs no destroy notify */
        cmd.hnd = handler;
        if (commands.has_key(command))
            log("muc_commands", LogLevelFlags.LEVEL_WARNING, "Command '%s' defined by '%s' was redefined by '%s'.",
                command, commands[command].mod.name(), mod.name());
        commands[command] = cmd;
        return true;
    }
    public bool unregister(string command) {
        return commands.unset(command);
    }

    protected void hnd_modules(ModuleMuc.Conference conf, ModuleMuc.Occupant user, string command, string? arguments) {
        var sb = new StringBuilder();
        sb.append("Loaded modules:");
        muc.name();
        foreach (var mod in conn.modules)
            sb.append(" "+mod.name());
        user.public_message(sb.str);
    }

    protected void hnd_status(ModuleMuc.Conference conf, ModuleMuc.Occupant user, string command, string? arguments) {
        var sb = new StringBuilder();
        sb.append("Status:");
        foreach (var room in muc.rooms.values) {
            sb.append(" ");
            sb.append(room.jid.split("@",2)[0]);
            sb.append("[");
            sb.append(room.enabled ? "EN":"DIS");
            sb.append(":");
            switch (room.state) {
                case ModuleMuc.State.CONNECTED: sb.append("C"); break;
                case ModuleMuc.State.DISCOVERING: sb.append("DS"); break;
                case ModuleMuc.State.CONNECTING: sb.append(">C"); break;
                case ModuleMuc.State.DISCONNECTING: sb.append(">D"); break;
                case ModuleMuc.State.DISCONNECTED: sb.append("D"); break;
            }
            sb.append("]");
        }
        user.public_message(sb.str);
    }

    public ModuleMucCommands(Config cfg, Connection conn) {
        base(cfg, conn);
        commands = new HashMap<string,Command>();
        foreach (var module in conn.modules) {
            if (module.name()=="muc")
                muc = (ModuleMuc)module;
        }
        if (muc==null)
            log("muc_log", LogLevelFlags.LEVEL_ERROR, "Module 'muc' is not loaded");

        muc.on_message.connect( (conf, user, message, body) => {
            if ((user!=null)&&(body!=null)&&(message.get_child("delay")==null)) {
                if (getconf(conf.jid, "commands", "no")!="yes")
                    return;
                if (body.has_prefix(conf.nick)) {
                    var txt = body[conf.nick.length:body.length];
                    if (txt.has_prefix(": ")||txt.has_prefix(", ")) {
                        var command_n_args = txt[2:txt.length].split(" ",2);
                        var command = commands[command_n_args[0]];
                        if (command!=null)
                            command.hnd(conf, user, command_n_args[0], (command_n_args.length > 1) ? command_n_args[1] : null);
                    }
                }
            }
        });
        
        register("modules", this, hnd_modules);
        register("status", this, hnd_status);
    }
    public override string name() {
        return "muc_commands";
    }
}