found and fixed some very strange code in IRCParser.c and solved the duplicate event...
authorpk910 <philipp@zoelle1.de>
Sun, 23 Oct 2011 18:27:16 +0000 (20:27 +0200)
committerpk910 <philipp@zoelle1.de>
Sun, 23 Oct 2011 18:31:55 +0000 (20:31 +0200)
src/ChanNode.c
src/ChanUser.c
src/ChanUser.h
src/IRCParser.c

index 480baed5ee70ef5fe4d07fba015b48b21cd2f914..82198e76eeb02c6727bd6102b454dfb120b9010b 100644 (file)
@@ -48,9 +48,7 @@ void free_ChanNode() {
             next = chan->next;
             for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next_chanuser) {
                 next_chanuser = getChannelUsers(chan, chanuser);
-                if(chanuser->spamnode)
-                    free(chanuser->spamnode);
-                free(chanuser);
+                freeChanUser(chanuser);
             }
             freeChanNode(chan);
         }
@@ -246,9 +244,7 @@ void checkChannelVisibility(struct ChanNode* chan) {
             //free the user (no more channels)
             delUser(chanuser->user, 1);
         }
-        if(chanuser->spamnode)
-            free(chanuser->spamnode);
-        free(chanuser);
+        freeChanUser(chanuser);
     }
     chan->user = NULL;
     delChannel(chan, 1);
index 05dbd88f0f609f63cde3a90a3d4367c422ec0c46..7638d6fe8c782e4fc141aea995e018af74dfa131 100644 (file)
@@ -96,7 +96,7 @@ struct ChanUser* getUserChannels(struct UserNode *user, struct ChanUser *last) {
         return last->next_chan;
 }
 
-void delChanUser(struct ChanUser *chanuser, int freeChanUser) {
+void delChanUser(struct ChanUser *chanuser, int do_freeChanUser) {
     struct ChanUser *cchanuser, *last;
     //remove it from the user's channel-list
     if(!(chanuser->flags & CHANUSERFLAG_INVISIBLE)) {
@@ -127,17 +127,15 @@ void delChanUser(struct ChanUser *chanuser, int freeChanUser) {
             last = cchanuser;
     }
     
-    if(freeChanUser) {
-        if(chanuser->spamnode)
-            free(chanuser->spamnode);
-        free(chanuser);
+    if(do_freeChanUser) {
+        freeChanUser(chanuser);
     } else {
         chanuser->next_chan = NULL;
         chanuser->next_user = NULL;
     }
 }
 
-void removeChanUserFromLists(struct ChanUser *chanuser, int remove_from_userlist, int remove_from_channellist, int freeChanUser) {
+void removeChanUserFromLists(struct ChanUser *chanuser, int remove_from_userlist, int remove_from_channellist, int do_freeChanUser) {
     struct ChanUser *cchanuser, *last;
     if(remove_from_userlist) {
         //remove it from the channel's user-list
@@ -171,10 +169,14 @@ void removeChanUserFromLists(struct ChanUser *chanuser, int remove_from_userlist
         chanuser->next_chan = NULL;
     }
     
-    if(freeChanUser) {
-        if(chanuser->spamnode)
-            free(chanuser->spamnode);
-        free(chanuser);
+    if(do_freeChanUser) {
+        freeChanUser(chanuser);
     }
 }
 
+void freeChanUser(struct ChanUser *chanuser) {
+    if(chanuser->spamnode)
+        free(chanuser->spamnode);
+    free(chanuser);
+}
+
index 65ef133c3ff298515cd8a7fa34b6cc99cfc19982..caf845c41db41fb2c781647fe16498c4233d3b84 100644 (file)
@@ -50,5 +50,6 @@ struct ChanUser* getChannelUsers(struct ChanNode *chan, struct ChanUser *last);
 struct ChanUser* getUserChannels(struct UserNode *user, struct ChanUser *last);
 void delChanUser(struct ChanUser *chanuser, int freeChanUser);
 void removeChanUserFromLists(struct ChanUser *chanuser, int remove_from_userlist, int remove_from_channellist, int freeChanUser);
+void freeChanUser(struct ChanUser *chanuser);
 
 #endif
\ No newline at end of file
index 55f3713b15483cd406f15a27bbea7de7d94423b4..b96acea7c0eb1bbcef943e8592c132e089e69377 100644 (file)
@@ -117,11 +117,38 @@ static IRC_CMD(raw_001) {
     return 1;
 }
 
+static int is_firstBotSeeUser(struct ClientSocket *client, struct UserNode *user) {
+    struct ClientSocket *bot, *pref_bot = NULL, *unpref_bot = NULL;
+    struct ChanUser *chanuser;
+    int found;
+    for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+        found = 0;
+        for(chanuser = getUserChannels(bot->user, NULL); chanuser; chanuser = getUserChannels(bot->user, chanuser)) {
+            if(isUserOnChan(user, chanuser->chan)) {
+                found = 1;
+                break;
+            }
+        }
+        if(!found) continue;
+        if(bot->flags & SOCKET_FLAG_PREFERRED) {
+            pref_bot = bot;
+            break;
+        } else
+            unpref_bot = bot;
+    }
+    bot = (pref_bot ? pref_bot : unpref_bot);
+    if(client == bot)
+        return 1;
+    else
+        return 0;
+}
+
 static IRC_CMD(raw_join) {
     if(from == NULL || argc < 1) return 0;
     struct UserNode *user = getUserByMask(from);
     struct ChanNode *chan = getChanByName(argv[0]);
     if(!chan && !(user->flags & USERFLAG_ISBOT)) return 0;
+    if(chan && chan->chanbot != client->user) return 1; //we ignore it - but it's not a parse error
     if(user == NULL) {
         user = addUserMask(from);
     }
@@ -146,11 +173,12 @@ static IRC_CMD(raw_part) {
     if(user == NULL) return 0;
     struct ChanNode *chan = getChanByName(argv[0]);
     if(chan == NULL) return 0;
+    if(chan->chanbot != client->user) return 1; //we ignore it - but it's not a parse error
     if(isUserOnChan(user, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
         struct ChanUser *chanuser = getChanUser(user, chan);
         delChanUser(chanuser, 0); //we need to free the chanuser manually!
         event_part(chanuser, (argc > 1 ? argv[1] : NULL));
-        free(chanuser);
+        freeChanUser(chanuser);
         if(chan->chanbot == user) {
             //check if theres another bot in the channel - otherwise free it
             checkChannelVisibility(chan);
@@ -167,6 +195,7 @@ static IRC_CMD(raw_quit) {
     if(from == NULL || argc < 1) return 0;
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) return 0;
+    if(!is_firstBotSeeUser(client, user)) return 1; //we ignore it - but it's not a parse error
     delUser(user, 0); //a little bit crazy, but we want to delete the user on the channel's userlists - but not the users channel list
     event_quit(user, argv[0]);
     if(user->flags & USERFLAG_ISBOT) {
@@ -174,7 +203,16 @@ static IRC_CMD(raw_quit) {
         struct ChanUser *chanuser, *next;
         for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next) {
             next = getUserChannels(user, chanuser);
-            checkChannelVisibility(chanuser->chan);
+            if(chanuser->chan->chanbot == user)
+                checkChannelVisibility(chanuser->chan);
+        }
+        //search the user representing the bot in the world of IRC
+        struct ClientSocket *bot;
+        for(bot = getBots(0, NULL); bot; bot = getBots(0, bot)) {
+            if(bot->user == user) {
+                bot->user = NULL;
+                break;
+            }
         }
     }
     delUser(user, 1); //now we fully free the user
@@ -184,14 +222,19 @@ static IRC_CMD(raw_quit) {
 void bot_disconnect(struct ClientSocket *client) {
     struct UserNode *user = client->user;
     struct ChanUser *chanuser, *next;
-    delUser(user, 0);
-    event_quit(user, "disconnected");
-    for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next) {
-        next = getUserChannels(user, chanuser);
-        checkChannelVisibility(chanuser->chan);
-        free(chanuser);
+    if(user) {
+        delUser(user, 0);
+        event_quit(user, "disconnected");
+        for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next) {
+            next = getUserChannels(user, chanuser);
+            if(chanuser->chan->chanbot == user)
+                checkChannelVisibility(chanuser->chan);
+            freeChanUser(chanuser);
+        }
+        user->channel = NULL;
+        delUser(user, 1); //now we fully free the user
+        client->user = NULL;
     }
-    user->channel = NULL;
 }
 
 static IRC_CMD(raw_kick) {
@@ -200,6 +243,7 @@ static IRC_CMD(raw_kick) {
     struct UserNode *target = getUserByNick(argv[1]);
     struct ChanNode *chan = getChanByName(argv[0]);
     if(chan == NULL || target == NULL) return 0;
+    if(chan->chanbot != client->user) return 1; //we ignore it - but it's not a parse error
     if(isUserOnChan(target, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
         if(user == NULL) {
             user = createTempUser(from);
@@ -208,8 +252,8 @@ static IRC_CMD(raw_kick) {
         struct ChanUser *chanuser = getChanUser(target, chan);
         delChanUser(chanuser, 0); //we need to free the chanuser manually!
         event_kick(user, chanuser, argv[1]);
-        free(chanuser);
-        if(target->flags & USERFLAG_ISBOT) {
+        freeChanUser(chanuser);
+        if(chanuser->chan->chanbot == user) {
             //check if theres another bot in the channel - otherwise free it
             checkChannelVisibility(chan);
         }
@@ -304,6 +348,7 @@ static IRC_CMD(raw_nick) {
     if(from == NULL || argc == 0) return 0;
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) return 0;
+    if(!is_firstBotSeeUser(client, user)) return 1; //we ignore it - but it's not a parse error
     event_nick(user, argv[0]);
     renameUser(user, argv[0]);
     return 1;