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";
}
}