X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fmodcmd.c;h=8b9c72c4573ab60000075d2e6a14e20df36861f9;hb=5eee43a7cfa37d5dd8d8a612a94de09a048b30c0;hp=eeaee94974644a18764c2aca0a1b69a7d82dddaa;hpb=2d9db1adb1946aba00b203f40eff7d5db8163f01;p=NeonServV5.git diff --git a/src/modcmd.c b/src/modcmd.c index eeaee94..8b9c72c 100644 --- a/src/modcmd.c +++ b/src/modcmd.c @@ -1,4 +1,4 @@ -/* modcmd.c - NeonServ v5.1 +/* modcmd.c - NeonServ v5.2 * Copyright (C) 2011 Philipp Kreil (pk910) * * This program is free software: you can redistribute it and/or modify @@ -35,19 +35,27 @@ struct trigger_callback { struct trigger_callback *next; }; +struct cmd_bot_alias { + int botid; + char *alias; + + struct cmd_bot_alias *next; +}; + struct command_check_user_cache { struct ClientSocket *client, *textclient; struct UserNode *user; struct ChanNode *chan, *sent_chan; char **argv; int argc; - char *message; + char *message, *args_buffer; struct cmd_binding *cbind; }; static struct cmd_binding **cmd_binds; static struct cmd_function *cmd_functions = NULL; static struct trigger_callback *trigger_callbacks = NULL; +static struct cmd_bot_alias *bot_aliases = NULL; static struct ClientSocket *tmp_text_client; static const struct default_language_entry msgtab[] = { @@ -103,7 +111,7 @@ static char* get_channel_trigger(int botid, struct ChanNode *chan) { return 0; } trigger->botid = botid; - trigger->trigger = strdup(triggerStr); + trigger->trigger = (triggerStr[0] ? strdup(triggerStr) : NULL); trigger->next = chan->trigger; chan->trigger = trigger; return trigger->trigger; @@ -116,6 +124,9 @@ static USERAUTH_CALLBACK(command_checked_auth) { tmp_text_client = cache->textclient; handle_command_async(cache->client, user, cache->chan, cache->sent_chan, cache->cbind, cache->argv, cache->argc); free(cache->message); + if(cache->args_buffer) + free(cache->args_buffer); + free(cache->argv); free(cache); } @@ -134,6 +145,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s message = strdup(message); int bind_index = get_binds_index(message[0]); char *args = strstr(message, " "); + char *args_buffer = NULL; //we need this to save a possible pointer to a allocation we need to free if(args) { *args = '\0'; args++; @@ -141,6 +153,11 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { if(cbind->botid == client->botid && stricmp(cbind->cmd, message) == 0) { + if((cbind->flags & CMDFLAG_FUNCMD)) { + if(!sent_chan) + break; + chan = sent_chan; + } //get a text bot tmp_text_client = get_prefered_bot(client->botid); //parse the arguments... @@ -170,6 +187,8 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s } if(cbind->paramcount) { //userdefined parameters... + args_buffer = malloc(MAXLEN * 2 * sizeof(*args_buffer)); + int args_pos = 0; char *uargs[MAXNUMPARAMS]; int uargc = 0; char *b; @@ -185,25 +204,48 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s argi = atoi(b); b[allargs] = '-'; allargs = 1; + } else if(b[strlen(b)-1] == '+') { + allargs = strlen(b)-1; + b[allargs] = '\0'; + argi = atoi(b); + b[allargs] = '+'; + allargs = 2; } else { allargs = 0; argi = atoi(b); } if(argi > 0) { if(argi <= argc) { - uargs[uargc++] = argv[argi-1]; - if(allargs) { - for(argi++; argi <= argc; argi++) - uargs[uargc++] = argv[argi-1]; + uargs[uargc++] = args_buffer + args_pos; + if(allargs == 0) { + args_pos += sprintf(args_buffer + args_pos, "%s", argv[argi-1]) + 1; + } else if(allargs == 1) { + args_pos += sprintf(args_buffer + args_pos, "%s", argv[argi-1]) + 1; + for(argi++; argi <= argc; argi++) { + uargs[uargc++] = args_buffer + args_pos; + args_pos += sprintf(args_buffer + args_pos, "%s", argv[argi-1]) + 1; + } + } else if(allargs == 2) { + for(;argi <= argc; argi++) { + args_pos += sprintf(args_buffer + args_pos, (allargs ? "%s" : " %s"), argv[argi-1]); + allargs = 0; + } + args_pos++; } + } else if((cbind->func->flags & CMDFLAG_EMPTY_ARGS)) { + uargs[uargc++] = args_buffer + args_pos; + args_buffer[args_pos++] = '\0'; } } else if(!strcmp(b, "c")) { - uargs[uargc++] = (chan ? chan->name : NULL); + uargs[uargc++] = args_buffer + args_pos; + args_pos += sprintf(args_buffer + args_pos, "%s", (chan ? chan->name : "")) + 1; } else if(!strcmp(b, "n")) { - uargs[uargc++] = user->nick; + uargs[uargc++] = args_buffer + args_pos; + args_pos += sprintf(args_buffer + args_pos, "%s", user->nick) + 1; } } else { - uargs[uargc++] = b; + uargs[uargc++] = args_buffer + args_pos; + args_pos += sprintf(args_buffer + args_pos, "%s", b) + 1; } } argv = uargs; @@ -233,6 +275,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s data->chan = chan; data->sent_chan = sent_chan; data->message = message; + data->args_buffer = args_buffer; data->cbind = cbind; data->textclient = tmp_text_client; get_userauth(user, command_checked_auth, data); @@ -243,6 +286,8 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s } } free(message); + if(args_buffer) + free(args_buffer); } static void handle_command_async(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct ChanNode *sent_chan, struct cmd_binding *cbind, char **argv, int argc) { @@ -259,8 +304,8 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u printf_mysql_query("SELECT `channel_pubcmd` FROM `channels` WHERE `channel_name` = '%s'", escape_string(sent_chan->name)); res = mysql_use(); if ((row = mysql_fetch_row(res)) != NULL) { - uaccess = getChannelAccess(user, sent_chan, 1); - if(row[0] && uaccess < atoi(row[0])) { //NOTE: HARDCODED DEFAULT: pubcmd = 0 + uaccess = getChannelAccess(user, sent_chan); + if(row[0] && uaccess < atoi(row[0]) && !isGodMode(user)) { //NOTE: HARDCODED DEFAULT: pubcmd = 0 reply(tmp_text_client, user, "MODCMD_PUBCMD", sent_chan->name); return; } @@ -319,7 +364,7 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u chan->flags |= CHANFLAG_CHAN_REGISTERED; chan->channel_id = atoi(row[0]); if((sent_chan && sent_chan == chan) || access_count || minaccess) { - uaccess = getChannelAccess(user, chan, 0); + uaccess = getChannelAccess(user, chan); if(uaccess < minaccess && isGodMode(user)) { eventflags |= CMDFLAG_OPLOG; } else if(uaccess < minaccess) { @@ -390,7 +435,7 @@ static void got_chanmsg(struct UserNode *user, struct ChanNode *chan, char *mess if(isUserOnChan(client->user, chan) && (client->flags & SOCKET_FLAG_PREFERRED) && !FD_ISSET(client->botid, &fds)) { FD_SET(client->botid, &fds); trigger = get_channel_trigger(client->botid, chan); - if(stricmplen(message, trigger, strlen(trigger)) == 0) { + if(trigger && stricmplen(message, trigger, strlen(trigger)) == 0) { handle_command(client, user, chan, message + strlen(trigger)); } } @@ -399,7 +444,7 @@ static void got_chanmsg(struct UserNode *user, struct ChanNode *chan, char *mess if(isUserOnChan(client->user, chan) && !FD_ISSET(client->botid, &fds)) { FD_SET(client->botid, &fds); trigger = get_channel_trigger(client->botid, chan); - if(stricmplen(message, trigger, strlen(trigger)) == 0) { + if(trigger && stricmplen(message, trigger, strlen(trigger)) == 0) { handle_command(client, user, chan, message + strlen(trigger)); } } @@ -418,7 +463,7 @@ static void got_privmsg(struct UserNode *user, struct UserNode *target, char *me int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, char *channel_access, int global_access, unsigned int flags) { struct cmd_function *cmdfunc; for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) { - if(cmdfunc->botid == botid && strcmp(cmdfunc->name, name) == 0) + if((cmdfunc->botid == botid || cmdfunc->botid == 0) && strcmp(cmdfunc->name, name) == 0) return 0; } cmdfunc = malloc(sizeof(*cmdfunc)); @@ -496,8 +541,22 @@ int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func) { int bind_cmd_to_command(int botid, char *cmd, char *func) { struct cmd_function *cmdfunc; + int fbotid = botid; + char *c; + if((c = strstr(func, "."))) { + *c = '\0'; + struct cmd_bot_alias *botalias; + for(botalias = bot_aliases; botalias; botalias = botalias->next) { + if(!stricmp(botalias->alias, func)) { + fbotid = botalias->botid; + break; + } + } + *c = '.'; + func = c+1; + } for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) { - if(cmdfunc->botid == botid && strcmp(cmdfunc->name, func) == 0) + if((cmdfunc->botid == fbotid || cmdfunc->botid == 0) && strcmp(cmdfunc->name, func) == 0) break; } if(!cmdfunc) return 0; @@ -549,8 +608,21 @@ int unbind_cmd(int botid, char *cmd) { struct cmd_function *find_cmd_function(int botid, char *name) { struct cmd_function *cmdfunc; + char *c; + if((c = strstr(name, "."))) { + *c = '\0'; + struct cmd_bot_alias *botalias; + for(botalias = bot_aliases; botalias; botalias = botalias->next) { + if(!stricmp(botalias->alias, name)) { + botid = botalias->botid; + break; + } + } + *c = '.'; + name = c+1; + } for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) { - if(cmdfunc->botid == botid && stricmp(cmdfunc->name, name) == 0) + if((cmdfunc->botid == botid || cmdfunc->botid == 0) && stricmp(cmdfunc->name, name) == 0) break; } return cmdfunc; @@ -596,8 +668,15 @@ void free_modcmd() { next_cb = cb->next; free(next_cb); } + struct cmd_bot_alias *botalias, *next_botalias; + for(botalias = bot_aliases; botalias; botalias = next_botalias) { + next_botalias = botalias->next; + free(botalias->alias); + free(botalias); + } cmd_functions = NULL; trigger_callbacks = NULL; + bot_aliases = NULL; } void bind_set_parameters(int botid, char *cmd, char *parameters) { @@ -669,3 +748,62 @@ struct cmd_binding *find_cmd_binding(int botid, char *cmd) { return NULL; } +void bind_unbound_required_functions(int botid) { + struct cmd_function *cmdfunc; + int i, found; + struct cmd_binding *cbind; + for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) { + if((cmdfunc->flags & CMDFLAG_REQUIRED)) { + found = 0; + for(i = 0; i < 27; i++) { + for(cbind = cmd_binds[i]; cbind; cbind = cbind->next) { + if(cbind->botid == botid && cbind->func == cmdfunc) { + found = 1; + break; + } + } + if(found) + break; + } + if(!found && bind_cmd_to_function(botid, cmdfunc->name, cmdfunc)) { + cbind = find_cmd_binding(botid, cmdfunc->name); + cbind->flags |= CMDFLAG_TEMPONARY_BIND; + } + } + } +} + +void register_command_alias(int botid, char *alias) { + struct cmd_bot_alias *botalias; + for(botalias = bot_aliases; botalias; botalias = botalias->next) { + if(!stricmp(botalias->alias, alias)) + return; + } + botalias = malloc(sizeof(*botalias)); + if (!botalias) { + perror("malloc() failed"); + return; + } + botalias->botid = botid; + botalias->alias = strdup(alias); + botalias->next = bot_aliases; + bot_aliases = botalias; +} + +struct cmd_binding *getAllBinds(struct cmd_binding *last) { + int bind_index; + if(last) { + if(last->next) + return last->next; + bind_index = get_binds_index(last->cmd[0]) + 1; + if(bind_index > 26) + return NULL; + } else + bind_index = 0; + do { + if(cmd_binds[bind_index]) + return cmd_binds[bind_index]; + bind_index++; + } while(bind_index < 27); + return NULL; +}