From 4929b3cfa489f3fc5868bf768479f30fff18a272 Mon Sep 17 00:00:00 2001 From: pk910 Date: Sun, 1 Apr 2012 01:42:48 +0200 Subject: [PATCH] added OPER support (let the bots try to op themselves) --- database.sql | 2 + database.upgrade.sql | 7 ++- src/IRCParser.c | 5 ++ src/UserNode.c | 70 +++++++++++++++++++++++ src/UserNode.h | 4 +- src/bots.c | 13 +++-- src/modules.c | 4 +- src/modules/DummyServ.mod/bot_DummyServ.c | 5 +- src/modules/NeonFun.mod/bot_NeonFun.c | 5 +- src/modules/NeonHelp.mod/bot_NeonHelp.c | 5 +- src/modules/NeonServ.mod/bot_NeonServ.c | 5 +- src/modules/NeonSpam.mod/bot_NeonSpam.c | 5 +- src/modules/module.h | 1 + src/mysqlConn.c | 2 +- src/version.h | 2 +- 15 files changed, 121 insertions(+), 14 deletions(-) diff --git a/database.sql b/database.sql index 45cb784..d913d55 100644 --- a/database.sql +++ b/database.sql @@ -33,6 +33,8 @@ CREATE TABLE IF NOT EXISTS `bots` ( `ident` varchar(12) NOT NULL, `realname` varchar(255) NOT NULL, `automodes` varchar(20) NOT NULL, + `oper_user` varchar(50) DEFAULT NULL, + `oper_pass` varchar(50) DEFAULT NULL, `botclass` int(10) NOT NULL, `textbot` tinyint(1) NOT NULL, `queue` tinyint(1) NOT NULL, diff --git a/database.upgrade.sql b/database.upgrade.sql index c8f34f3..437b5f7 100644 --- a/database.upgrade.sql +++ b/database.upgrade.sql @@ -172,4 +172,9 @@ UPDATE `channels` SET `channel_badword_reaction` = '0', `channel_badword_reaction_duration` = '60', `channel_badword_except` = '400' WHERE `channel_name` = 'defaults'; ---version: 17 +-- version: 17 + +ALTER TABLE `bots` ADD `oper_user` VARCHAR( 50 ) NULL AFTER `automodes` , +ADD `oper_pass` VARCHAR( 50 ) NULL AFTER `oper_user`; + +-- version: 18 diff --git a/src/IRCParser.c b/src/IRCParser.c index cf98cc1..2ff95c8 100644 --- a/src/IRCParser.c +++ b/src/IRCParser.c @@ -668,6 +668,11 @@ static IRC_CMD(raw_mode) { event_mode(user, chan, argv[1], argv+2, argc-2); } else { //UserMode + if(stricmp(client->user->nick, argv[0])) { + DESYNCHRONIZE(cache_sync); + return 0; + } + parseUserModes(client->user, argv[1]); } DESYNCHRONIZE(cache_sync); return 1; diff --git a/src/UserNode.c b/src/UserNode.c index 0f10b53..7f82a47 100644 --- a/src/UserNode.c +++ b/src/UserNode.c @@ -23,8 +23,36 @@ static struct UserNode **userList; +unsigned int valid_user_modes[] = { + 1, 'o', + 2, 'O', + 3, 'i', + 4, 'w', + 5, 's', + 6, 'd', + 7, 'k', + 8, 'g', + 9, 'n', + 10, 'I', + 11, 'X', + 12, 'S', + 13, 'H', + 14, 'c', + 15, 'W', + 16, 't', + 17, 'D', + 18, 'x', +// ^ maximum is 32!!! + 0x00, 0x00 +}; + void init_UserNode() { + unsigned int *mode, flag = 1; userList = calloc(VALID_NICK_CHARS_FIRST_LEN+1, sizeof(*userList)); + for (mode = valid_user_modes; mode[1]; mode += 2) { + mode[0] = flag; + flag = flag << 1; + } } void free_UserNode() { @@ -65,6 +93,43 @@ static int get_nicklist_entry(int nick) { return -1; //ERROR! } +static unsigned int* getUserModeOptions(char mode) { + unsigned int *cmode; + for (cmode = valid_user_modes; cmode[1]; cmode += 2) { + if(cmode[1] == mode) + return cmode; + } + return NULL; +} + +int isUserModeSet(struct UserNode *user, char modeChar) { + unsigned int *modeOpt = getUserModeOptions(modeChar); + return (user->usermode & modeOpt[0]); +} + +void parseUserModes(struct UserNode* user, char *modeStr) { + int i, add = 1; + unsigned int *modeOpt; + for(i = 0; i < strlen(modeStr); i++) { + if(modeStr[i] == '+') { + add = 1; + continue; + } + if(modeStr[i] == '-') { + add = 0; + continue; + } + modeOpt = getUserModeOptions(modeStr[i]); + if(!modeOpt) continue; // unknown mode? + if(add) { + user->usermode |= modeOpt[0]; + } else { + user->usermode &= ~modeOpt[0]; + } + } +} + + struct UserNode* getUserByNick(const char *nick) { //case sensitive int userListIndex = get_nicklist_entry(*nick); if(userListIndex == -1 || userList[userListIndex] == NULL) @@ -235,6 +300,7 @@ struct UserNode* addUser(const char *nick) { user->flags = 0; user->channel = NULL; user->last_who = 0; + user->usermode = 0; SYNCHRONIZE(cache_sync); user->next = userList[userListIndex]; userList[userListIndex] = user; @@ -293,6 +359,7 @@ struct UserNode* createTempUser(const char *nick) { user->realname[0] = 0; user->flags = 0; user->channel = NULL; + user->usermode = 0; user->last_who = 0; } else user->flags &= ~USERFLAG_FREETMPUSER; @@ -340,6 +407,7 @@ struct UserNode* createTempUserMask(const char *mask) { user->realname[0] = 0; user->flags = 0; user->channel = NULL; + user->usermode = 0; user->last_who = 0; } else user->flags &= ~USERFLAG_FREETMPUSER; @@ -366,6 +434,7 @@ struct UserNode* createTempUserMask(const char *mask) { user->realname[0] = 0; user->flags = USERFLAG_ISSERVER; user->channel = NULL; + user->usermode = 0; user->last_who = 0; break; } else if(cmask[i] == '@') { @@ -390,6 +459,7 @@ struct UserNode* createTempUserMask(const char *mask) { user->realname[0] = 0; user->flags = 0; user->channel = NULL; + user->usermode = 0; user->last_who = 0; break; } diff --git a/src/UserNode.h b/src/UserNode.h index cf20df2..992ef07 100644 --- a/src/UserNode.h +++ b/src/UserNode.h @@ -46,7 +46,7 @@ struct UserNode { char realname[REALLEN+1]; char auth[AUTHLEN+1]; struct IPNode *ip; - unsigned int flags; + unsigned int flags, usermode; time_t created, last_who; struct ChanUser *channel; struct language *language; @@ -62,6 +62,8 @@ struct UserNode { #ifndef DND_FUNCTIONS void init_UserNode(); void free_UserNode(); +/* MODULAR ACCESSIBLE */ int isUserModeSet(struct UserNode *user, char modeChar); +void parseUserModes(struct UserNode* user, char *modeStr); /* MODULAR ACCESSIBLE */ int is_valid_nick(const char *nick); /* MODULAR ACCESSIBLE */ struct UserNode* getUserByNick(const char *nick); /* MODULAR ACCESSIBLE */ struct UserNode* getUserByMask(const char *mask); diff --git a/src/bots.c b/src/bots.c index 353abc5..7ada743 100644 --- a/src/bots.c +++ b/src/bots.c @@ -135,20 +135,25 @@ struct ClientSocket *getChannelBot(struct ChanNode *chan, int botid) { } void requestOp(struct UserNode *user, struct ChanNode *chan) { - struct ClientSocket *bot; + struct ClientSocket *bot, *userbot = NULL; struct ChanUser *chanuser = getChanUser(user, chan); char opped = 0; if(!chanuser) return; if((chanuser->flags & CHANUSERFLAG_OPPED)) return; for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { - if((chanuser = getChanUser(bot->user, chan)) != NULL && (chanuser->flags & CHANUSERFLAG_OPPED)) { + if(!opped && (chanuser = getChanUser(bot->user, chan)) != NULL && (chanuser->flags & CHANUSERFLAG_OPPED)) { opped = 1; putsock(bot, "MODE %s +o %s", chan->name, user->nick); - break; + } + if(bot->user == user) { + userbot = bot; } } if(!opped) { - //self op? + if(userbot && (isUserModeSet(user, 'o') || isUserModeSet(user, 'O') || isUserModeSet(user, 'k') || isUserModeSet(user, 'X'))) { + putsock(userbot, "MODE %s +o %s", chan->name, user->nick); + putsock(userbot, "OPMODE %s +o %s", chan->name, user->nick); + } } } diff --git a/src/modules.c b/src/modules.c index ba3a43a..4372c48 100644 --- a/src/modules.c +++ b/src/modules.c @@ -45,6 +45,7 @@ /* 181-183 */ #include "WHOHandler.h" /* 184-188 */ #include "version.h" /* 189 */ /* modules.h */ +/* 190 */ /* UserNode.h */ #define Function void * @@ -249,7 +250,8 @@ void *global_functions[] = { /* 186 */ (Function) get_revision, /* 187 */ (Function) get_codelines, /* 188 */ (Function) get_patchlevel, -/* 189 */ (Function) get_module_name +/* 189 */ (Function) get_module_name, +/* 190 */ (Function) isUserModeSet }; static int module_id_counter = 1; diff --git a/src/modules/DummyServ.mod/bot_DummyServ.c b/src/modules/DummyServ.mod/bot_DummyServ.c index 5eeff5a..2911b23 100644 --- a/src/modules/DummyServ.mod/bot_DummyServ.c +++ b/src/modules/DummyServ.mod/bot_DummyServ.c @@ -45,9 +45,12 @@ static void dummyserv_bot_ready(struct ClientSocket *client) { MYSQL_RES *res; MYSQL_ROW row; - printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid); + printf_mysql_query("SELECT `automodes`, `oper_user`, `oper_pass` FROM `bots` WHERE `id` = '%d'", client->clientid); res = mysql_use(); if ((row = mysql_fetch_row(res)) != NULL) { + if(row[1] && row[2]) { + putsock(client, "OPER %s %s", row[1], row[2]); + } putsock(client, "MODE %s +%s", client->user->nick, row[0]); } diff --git a/src/modules/NeonFun.mod/bot_NeonFun.c b/src/modules/NeonFun.mod/bot_NeonFun.c index ebb0cc5..e5706ae 100644 --- a/src/modules/NeonFun.mod/bot_NeonFun.c +++ b/src/modules/NeonFun.mod/bot_NeonFun.c @@ -47,9 +47,12 @@ static void neonfun_bot_ready(struct ClientSocket *client) { MYSQL_RES *res; MYSQL_ROW row; - printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid); + printf_mysql_query("SELECT `automodes`, `oper_user`, `oper_pass` FROM `bots` WHERE `id` = '%d'", client->clientid); res = mysql_use(); if ((row = mysql_fetch_row(res)) != NULL) { + if(row[1] && row[2]) { + putsock(client, "OPER %s %s", row[1], row[2]); + } putsock(client, "MODE %s +%s", client->user->nick, row[0]); } diff --git a/src/modules/NeonHelp.mod/bot_NeonHelp.c b/src/modules/NeonHelp.mod/bot_NeonHelp.c index db1321d..614d0df 100644 --- a/src/modules/NeonHelp.mod/bot_NeonHelp.c +++ b/src/modules/NeonHelp.mod/bot_NeonHelp.c @@ -73,9 +73,12 @@ static void neonhelp_bot_ready(struct ClientSocket *client) { MYSQL_RES *res; MYSQL_ROW row; - printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid); + printf_mysql_query("SELECT `automodes`, `oper_user`, `oper_pass` FROM `bots` WHERE `id` = '%d'", client->clientid); res = mysql_use(); if ((row = mysql_fetch_row(res)) != NULL) { + if(row[1] && row[2]) { + putsock(client, "OPER %s %s", row[1], row[2]); + } putsock(client, "MODE %s +%s", client->user->nick, row[0]); } diff --git a/src/modules/NeonServ.mod/bot_NeonServ.c b/src/modules/NeonServ.mod/bot_NeonServ.c index 6fa5236..8421fdb 100644 --- a/src/modules/NeonServ.mod/bot_NeonServ.c +++ b/src/modules/NeonServ.mod/bot_NeonServ.c @@ -419,9 +419,12 @@ static void neonserv_bot_ready(struct ClientSocket *client) { MYSQL_RES *res; MYSQL_ROW row; - printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid); + printf_mysql_query("SELECT `automodes`, `oper_user`, `oper_pass` FROM `bots` WHERE `id` = '%d'", client->clientid); res = mysql_use(); if ((row = mysql_fetch_row(res)) != NULL) { + if(row[1] && row[2]) { + putsock(client, "OPER %s %s", row[1], row[2]); + } putsock(client, "MODE %s +%s", client->user->nick, row[0]); } diff --git a/src/modules/NeonSpam.mod/bot_NeonSpam.c b/src/modules/NeonSpam.mod/bot_NeonSpam.c index 10b4083..f29cb90 100644 --- a/src/modules/NeonSpam.mod/bot_NeonSpam.c +++ b/src/modules/NeonSpam.mod/bot_NeonSpam.c @@ -132,9 +132,12 @@ static void neonspam_bot_ready(struct ClientSocket *client) { MYSQL_RES *res; MYSQL_ROW row; - printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid); + printf_mysql_query("SELECT `automodes`, `oper_user`, `oper_pass` FROM `bots` WHERE `id` = '%d'", client->clientid); res = mysql_use(); if ((row = mysql_fetch_row(res)) != NULL) { + if(row[1] && row[2]) { + putsock(client, "OPER %s %s", row[1], row[2]); + } putsock(client, "MODE %s +%s", client->user->nick, row[0]); } diff --git a/src/modules/module.h b/src/modules/module.h index 89bf781..b780ac1 100644 --- a/src/modules/module.h +++ b/src/modules/module.h @@ -219,6 +219,7 @@ extern int module_id; /* 187 */ #define get_codelines ((const char * (*)(void))global[187]) /* 188 */ #define get_patchlevel ((const int (*)(void))global[188]) /* 189 */ #define get_module_name ((char * (*)(int))global[189]) +/* 190 */ #define isUserModeSet ((int (*)(struct UserNode *, char))global[190]) #define MODULE_HEADER(initfunc,startfunc,loopfunc,stopfunc) \ void **global = NULL; \ diff --git a/src/mysqlConn.c b/src/mysqlConn.c index c2f3fcb..d8e3066 100644 --- a/src/mysqlConn.c +++ b/src/mysqlConn.c @@ -16,7 +16,7 @@ */ #include "mysqlConn.h" -#define DATABASE_VERSION "17" +#define DATABASE_VERSION "18" static void show_mysql_error(); diff --git a/src/version.h b/src/version.h index 85900e2..063c73d 100644 --- a/src/version.h +++ b/src/version.h @@ -19,7 +19,7 @@ #include "main.h" -#define MODULE_VERSION 2 +#define MODULE_VERSION 3 #ifndef DND_FUNCTIONS extern const char *compilation; -- 2.20.1