added OPER support (let the bots try to op themselves)
authorpk910 <philipp@zoelle1.de>
Sat, 31 Mar 2012 23:42:48 +0000 (01:42 +0200)
committerpk910 <philipp@zoelle1.de>
Sat, 31 Mar 2012 23:42:48 +0000 (01:42 +0200)
15 files changed:
database.sql
database.upgrade.sql
src/IRCParser.c
src/UserNode.c
src/UserNode.h
src/bots.c
src/modules.c
src/modules/DummyServ.mod/bot_DummyServ.c
src/modules/NeonFun.mod/bot_NeonFun.c
src/modules/NeonHelp.mod/bot_NeonHelp.c
src/modules/NeonServ.mod/bot_NeonServ.c
src/modules/NeonSpam.mod/bot_NeonSpam.c
src/modules/module.h
src/mysqlConn.c
src/version.h

index 45cb784168f73ee4bb9beac0e927da41b13b5d9b..d913d55e36c782340ef10f77194970a7464832ab 100644 (file)
@@ -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,
index c8f34f3cd15c902ccf4fde86b0dc692032442e7e..437b5f7d6e119788f4703e233402e4f0d5ea5e80 100644 (file)
@@ -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
index cf98cc182c4875762068d04daebccf360b6754e4..2ff95c8ba066b3e2b440d1b6250e4242060e1042 100644 (file)
@@ -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;
index 0f10b532e27f24d0cbc4f83741d0666995e1529d..7f82a475305220786f5a29ef4add3c168cabb426 100644 (file)
 
 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;
             }
index cf20df28d36f8fcbe59aeadd82cb1221e49d7003..992ef0737eddfe9df6ce44407bb8388e774ba4d5 100644 (file)
@@ -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);
index 353abc5a4d1cf7bd39b520f2499d18dce096d085..7ada74312aac2d40f3dfa190f0d0f7cca9f9494f 100644 (file)
@@ -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);
+        }
     }
 }
 
index ba3a43a6b8fb32937ad4665bc464d74bb3de053b..4372c48433d1bec7140922c977e862a754acffce 100644 (file)
@@ -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;
index 5eeff5a6fcf02b4fc220612147d3e8622f5cab7d..2911b23f7e399f55cb4507dc340ecef1604a2376 100644 (file)
@@ -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]);
     }
     
index ebb0cc58dc4ac17d7d2cdffcb060d41b468a874f..e5706ae8cc875f2d059f01a23a2e73817270fce9 100644 (file)
@@ -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]);
     }
     
index db1321dffac7e491630eda0c7b6db349e096b600..614d0df4a6b346edcae945cf7959bc0248fe9dad 100644 (file)
@@ -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]);
     }
     
index 6fa5236862437e0e059533ec0839721dc71cce97..8421fdbd840cadf7df7a039f4913bb0477cc4ad2 100644 (file)
@@ -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]);
     }
     
index 10b4083e9010e81d811f879d41ba209f01437361..f29cb903e7c98ba8ba92fb096cc2f79480a1861f 100644 (file)
@@ -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]);
     }
     
index 89bf781a89e3b5bedac202929ac99dd07844e6af..b780ac16a495499d43c009373e586c0226052443 100644 (file)
@@ -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; \
index c2f3fcb69604378d7fa0fc96c2408ee51df64825..d8e3066599d3b3eef719e5ff142d3ac3b52d6915 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #include "mysqlConn.h"
-#define DATABASE_VERSION "17"
+#define DATABASE_VERSION "18"
 
 static void show_mysql_error();
 
index 85900e200dff8d277196d709ad434a355861c86c..063c73d5d0631e46bc692ca6a8d143a6f994fa1a 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "main.h"
 
-#define MODULE_VERSION 2
+#define MODULE_VERSION 3
 
 #ifndef DND_FUNCTIONS
 extern const char *compilation;