}
}
+void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...) {
+ //following
+}
+
#define _IRCParser_h
#include "main.h"
-#include "ClientSocket.h"
+
+struct ClientSocket;
+struct UserNode;
#define IRC_CMD(NAME) int NAME(struct ClientSocket *client, UNUSED_ARG(const char *from), UNUSED_ARG(char **argv), UNUSED_ARG(unsigned int argc))
typedef IRC_CMD(irc_cmd_t);
void bot_disconnect(struct ClientSocket *client);
void init_parser();
void free_parser();
+void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...) PRINTF_LIKE(3, 4);
#endif
\ No newline at end of file
#define WHOQUEUETYPE_ISONQUEUE 0x01
#define WHOQUEUETYPE_USERLIST 0x02
+#define WHOQUEUETYPE_USERAUTH 0x04
struct WHOQueueEntry {
char type;
struct ChanNode *chan;
struct UserNode *user;
struct WHOQueueEntry *next;
- userlist_callback_t *callback;
+ void *callback;
void *data;
};
putsock(bot, "WHO %s,%d %%tuhnaf,%d", chan->name, entry->type, entry->type);
}
+void get_userauth(struct UserNode *user, userauth_callback_t callback, void *data) {
+ struct ClientSocket *bot;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(isUserOnChan(bot->user, chan))
+ break;
+ }
+ if(bot == NULL) return;
+ struct WHOQueueEntry* entry = addWHOQueueEntry(bot);
+ entry->type = WHOQUEUETYPE_ISONQUEUE | WHOQUEUETYPE_USERAUTH;
+ entry->user = user;
+ entry->callback = callback;
+ entry->data = data;
+ //WHO ".$user->getNick().",".$id." %tuhna,".$id
+ putsock(bot, "WHO %s,%d %%tuhna,%d", user->nick, entry->type, entry->type);
+}
+
void recv_whohandler_354(struct ClientSocket *client, char **argv, unsigned int argc) {
int i;
if(argc < 2) return;
strcpy(user->auth, argv[6]);
user->flags |= USERFLAG_ISAUTHED;
}
+ } else if(type & WHOQUEUETYPE_USERAUTH) {
+ //:OGN2.OnlineGamesNet.net 354 Skynet 1 pk910 2001:41d0:2:1d3b::babe Skynet pk910
+ if(!strcmp(argv[5], "0") && !(entry->user->flags & USERFLAG_ISAUTHED)) {
+ strcpy(entry->user->auth, argv[5]);
+ entry->user->flags |= USERFLAG_ISAUTHED;
+ }
+ userauth_callback_t *callback = entry->callback;
+ callback(client, entry->user, entry->data);
}
}
if(type & WHOQUEUETYPE_USERLIST) {
//:OGN2.OnlineGamesNet.net 315 skynet #pk910,1 :End of /WHO list.
entry->chan->flags |= CHANFLAG_RECEIVED_USERLIST;
- entry->callback(client, entry->chan, entry->data);
+ userlist_callback_t *callback = entry->callback;
+ callback(client, entry->chan, entry->data);
}
free(entry);
}
#define USERLIST_CALLBACK(NAME) void NAME(UNUSED_ARG(struct ClientSocket *client), UNUSED_ARG(struct ChanNode *chan), UNUSED_ARG(void *data))
typedef USERLIST_CALLBACK(userlist_callback_t);
+#define USERAUTH_CALLBACK(NAME) void NAME(UNUSED_ARG(struct ClientSocket *client), UNUSED_ARG(struct UserNode *user), UNUSED_ARG(void *data))
+typedef USERAUTH_CALLBACK(userauth_callback_t);
+
void recv_whohandler_354(struct ClientSocket *client, char **argv, unsigned int argc);
void recv_whohandler_315(struct ClientSocket *client, char **argv, unsigned int argc);
void get_userlist(struct ChanNode *chan, userlist_callback_t callback, void *data);
+void get_userauth(struct UserNode *user, userauth_callback_t callback, void *data);
void free_whoqueue();
#endif
\ No newline at end of file
static void start_bots() {
struct UserNode *user;
struct ClientSocket *client;
- MYSQL_RES *res;
+ MYSQL_RES *res, *res2;
MYSQL_ROW row;
printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `whoisbot`, `id` FROM `bots` WHERE `botclass` = '%s' AND `active` = '1'", escape_string(CLASSNAME));
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
-
+ printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access` FROM `bot_binds` WHERE `botid` = '%d'", client->clientid);
+ res2 = mysql_use();
+ while ((row = mysql_fetch_row(res2)) != NULL) {
+
+ }
}
}
void init_NeonServ() {
check_mysql();
- start_bots();
- bind_bot_ready(neonserv_bot_ready);
- set_trigger_callback(BOTID, neonserv_trigger_callback);
-
register_command(BOTID, "users", neonserv_cmd_users);
register_command(BOTID, "modes", neonserv_cmd_modes);
+ start_bots();
+ bind_bot_ready(neonserv_bot_ready);
+ set_trigger_callback(BOTID, neonserv_trigger_callback);
bind_cmd_to_command(BOTID, "users", "users");
bind_cmd_to_command(BOTID, "modes", "modes");
}
struct trigger_callback *next;
};
+struct command_check_user_cache {
+ struct ClientSocket *client;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char **argv;
+ int argc;
+ char *message;
+ struct cmd_binding *cbind;
+};
+
static struct cmd_binding **cmd_binds;
static struct cmd_function *cmd_functions = NULL;
static struct trigger_callback *trigger_callbacks = NULL;
return trigger->trigger;
}
+static USERAUTH_CALLBACK(command_checked_auth) {
+ struct command_check_user_cache *cache = data;
+ int execute_cmd = 1;
+ if((cbind->func->flags & CMDFLAG_REQUIRE_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) {
+ //AUTH_REQUIRED
+ execute_cmd = 0;
+ }
+ if(execute_cmd) {
+ cbind->func->func(cache->client, user, cache->chan, cache->argv, cache->argc);
+ }
+ free(cache->message);
+ free(cache);
+}
+
static void handle_command(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) {
if(message[0] == '#') {
char *chanName = message;
if(chan2)
chan = chan2;
}
+ message = strdup(message);
int bind_index = get_binds_index(message[0]);
char *args = strstr(message, " ");
if(args) {
chan = chan2;
}
}
+ if(cbind->func->parameters) {
+ //userdefined parameters...
+ char *uarga[MAXNUMPARAMS];
+ char params[strlen(cbind->func->parameters)+1];
+ strcpy(params, cbind->func->parameters);
+ int uargpos = 0, argi, allargs = 0;
+ char *ppos = params, *prev_ppos = params;
+ while(ppos = strstr(ppos, " ")) {
+ ppos = '\0';
+ if(prev_ppos[0] == '%') {
+ prev_ppos++;
+ if(prev_ppos[strlen(prev_ppos)-1] == '-') {
+ allargs = 1;
+ prev_ppos[strlen(prev_ppos)-1] = '\0';
+ } else
+ allargs = 0;
+ if((argi = atoi(prev_ppos)) > 0) {
+ if(argi <= argc) continue;
+ uarga[uargpos++] = argv[argi-1]
+ if(allargs) {
+ for(;argi < argc; argi++)
+ uarga[uargpos++] = argv[argi-1]
+ }
+ } else if(!strcmp(prev_ppos, "c"))
+ uarga[uargpos++] = (chan ? chan->name : NULL);
+ else if(!strcmp(prev_ppos, "n"))
+ uarga[uargpos++] = user->nick;
+ } else {
+ uarga[uargpos++] = prev_ppos;
+ }
+ ppos = ' ';
+ ppos++;
+ prev_ppos = ppos;
+ }
+ argv = uarga;
+ argc = uargpos;
+ }
+ if(argc < cbind->func->paramcount) {
+ //LESS_PARAM_COUNT
+ break;
+ }
+ if((cbind->func->flags & CMDFLAG_REQUIRE_CHAN) && !chan) {
+ //CHAN_REQUIRED
+ break;
+ }
+ if((cbind->func->flags & CMDFLAG_CHECK_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) {
+ //check auth...
+ struct command_check_user_cache *data = malloc(sizeof(*data));
+ char **temp_argv = malloc(argc*sizeof(*temp_argv));
+ if (!data || !temp_argv) {
+ perror("malloc() failed");
+ break;
+ }
+ memcpy(temp_argv, argv, argc*sizeof(*temp_argv));
+ data->argv = temp_argv;
+ data->argc = argc;
+ data->client = client;
+ data->user = user;
+ data->chan = chan;
+ data->message = message;
+ data->cbind = cbind;
+ get_userauth(user, command_checked_auth, data)
+ return;
+ }
+ if((cbind->func->flags & CMDFLAG_REQUIRE_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) {
+ //AUTH_REQUIRED
+ break;
+ }
cbind->func->func(client, user, chan, argv, argc);
- return;
+ break;
}
}
+ free(message);
}
static void got_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) {
}
}
-int register_command(int botid, char *name, cmd_bind_t *func) {
+int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, unsigned int flags) {
struct cmd_function *cmdfunc;
for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) {
if(cmdfunc->botid == botid && strcmp(cmdfunc->name, name) == 0)
cmdfunc->botid = botid;
cmdfunc->name = strdup(name);
cmdfunc->func = func;
+ cmdfunc->flags = 0;
+ cmdfunc->paramcount = paramcount;
cmdfunc->next = cmd_functions;
cmd_functions = cmdfunc;
return 1;
cbind->botid = botid;
cbind->cmd = strdup(cmd);
cbind->func = func;
+ cbind->parameters = NULL;
+ cbind->flags = 0;
cbind->next = cmd_binds[bind_index];
cmd_binds[bind_index] = cbind;
return 1;
cbind->cmd = strdup(cmd);
cbind->func = cmdfunc;
cbind->next = cmd_binds[bind_index];
+ cbind->parameters = NULL;
+ cbind->flags = 0;
cmd_binds[bind_index] = cbind;
return 1;
}
else
cmd_binds[bind_index] = cbind->next;
free(cbind->cmd);
+ if(cbind->parameters)
+ free(cbind->parameters);
free(cbind);
return 1;
} else
for(cbind = cmd_binds[i]; cbind; cbind = next) {
next = cbind->next;
free(cbind->cmd);
+ if(cbind->parameters)
+ free(cbind->parameters);
free(cbind);
}
}
#define _modcmd_h
#include "main.h"
+#define CMDFLAG_REQUIRE_CHAN 0x01
+#define CMDFLAG_REQUIRE_AUTH 0x02
+#define CMDFLAG_REQUIRE_GOD 0x04
+#define CMDFLAG_CHECK_AUTH 0x08
+#define CMDFLAG_OVERRIDE_ACCESS 0x10
+
struct ClientSocket;
struct UserNode;
struct ChanNode;
char *name;
int botid;
cmd_bind_t *func;
+ unsigned int flags;
+ int paramcount;
struct cmd_function *next;
};
char *cmd;
int botid;
struct cmd_function *func;
+ unsigned int flags;
+ char *parameters;
struct cmd_binding *next;
};
void init_modcmd();
void free_modcmd();
struct ClientSocket* get_prefered_bot(int botid);
-int register_command(int botid, char *name, cmd_bind_t *func);
+int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, unsigned int flags);
int set_trigger_callback(int botid, trigger_callback_t *func);
int changeChannelTrigger(int botid, struct ChanNode *chan, char *new_trigger);
int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func);