rewrote IRC cache parser to be (hopefully) more stable v5.4
authorpk910 <philipp@zoelle1.de>
Sun, 12 Aug 2012 13:15:16 +0000 (15:15 +0200)
committerpk910 <philipp@zoelle1.de>
Sun, 12 Aug 2012 13:59:44 +0000 (15:59 +0200)
25 files changed:
src/ChanNode.c
src/ChanNode.h
src/ChanUser.c
src/ChanUser.h
src/DBHelper.c
src/IRCEvents.c
src/IRCEvents.h
src/IRCParser.c
src/IRCParser.h
src/UserNode.h
src/modules.c
src/modules/NeonFun.mod/bot_NeonFun.c
src/modules/NeonFun.mod/game_4wins.c
src/modules/NeonFun.mod/game_4wins.h
src/modules/NeonFun.mod/game_uno.c
src/modules/NeonFun.mod/game_uno.h
src/modules/NeonHelp.mod/bot_NeonHelp.c
src/modules/NeonServ.mod/bot_NeonServ.c
src/modules/NeonServ.mod/event_neonserv_join.c
src/modules/NeonServ.mod/event_neonserv_part.c
src/modules/NeonServ.mod/event_neonserv_quit.c [deleted file]
src/modules/NeonSpam.mod/event_neonspam_join.c
src/modules/module.h
src/tools.c
src/version.h

index fddde4c10598cbd2d01e0762e0e4467af20619c0..23543c497273c88fff9d118db7fffc0005f268aa 100644 (file)
@@ -138,7 +138,6 @@ struct ChanNode* addChannel(const char *name) {
     chan->bans = NULL;
     chan->spam_settings = NULL;
     chan->usercount = 0;
-    chan->chanbot = NULL;
     chan->topic[0] = 0;
     chan->flags = 0;
     /* mode lists */
@@ -236,10 +235,8 @@ void freeChanNode(struct ChanNode* chan) {
 int checkChannelVisibility(struct ChanNode* chan) {
     struct ChanUser *chanuser, *next;
     for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
-        if(chanuser->user->flags & USERFLAG_ISBOT) {
-            chan->chanbot = chanuser->user;
+        if(chanuser->user->flags & USERFLAG_ISBOT)
             return 1;
-        }
     }
     //free the channel...
     SYNCHRONIZE(cache_sync);
index 756a6b4a28571f3d9243c8b726bdf8a63e5a4650..4d7a348465e9b7f26e70774a60da6694606b5b4e 100644 (file)
@@ -40,7 +40,6 @@ struct ChanNode {
     struct ModeNode *modes;
     struct BanNode *bans;
     
-    struct UserNode *chanbot;
     struct trigger_cache *trigger;
     int channel_id;
     
index ff29b70c8d4d2baae1970c899345ba71ef52b952..0d370c1dcd25ef9e55b127fcd58813c32d32471d 100644 (file)
@@ -30,6 +30,7 @@ struct ChanUser* addChanUser(struct ChanNode *chan, struct UserNode *user) {
     chanuser->flags = 0;
     chanuser->user = user;
     chanuser->chan = chan;
+    chanuser->visCount = 0;
     
     chanuser->changeTime = 0;
     chanuser->spamnode = NULL;
@@ -58,6 +59,7 @@ struct ChanUser* addInvisibleChanUser(struct ChanNode *chan, struct UserNode *us
     chanuser->flags = CHANUSERFLAG_INVISIBLE;
     chanuser->user = user;
     chanuser->chan = chan;
+    chanuser->visCount = 0;
     
     chanuser->changeTime = 0;
     chanuser->spamnode = NULL;
index f9f71633accae00bb96c0069fd56dc7a377bbd97..43a6b7d7a7a514e448f1f43e73255947cf92e5fc 100644 (file)
@@ -34,6 +34,8 @@ struct ChanUser {
     struct ChanNode *chan;
     struct UserNode *user;
     
+    int visCount; //visible counter - if this is 0, the ChanUser gets removed
+    
     int chageEvents;
     time_t changeTime;
     
index 787b336845451821833f9303eba792ae1b87ac18..40d3be3506e34f4673f08270bd1e422aae2456bc 100644 (file)
@@ -262,28 +262,35 @@ int renameAccount(char *oldauth, char *newauth) {
 static AUTHLOOKUP_CALLBACK(event_user_registered_auth_lookup);
 
 struct event_user_registered_cache {
-    struct UserNode *new_user;
+    struct UserNode *user;
     char *oldauth;
 };
 
-static int event_user_registered(struct UserNode *old_user, struct UserNode *new_user) {
+static void event_user_registered(struct UserNode *user, char *new_mask) {
     //check if there is a fakehost on both sides...
-    if(!isFakeHost(old_user->host) || !isFakeHost(new_user->host)) return 0;
+    //extract host from new_mask
+    char *new_host = strchr(new_mask, '@');
+    if(new_host)
+        new_host++;
+    else
+        return;
+    if(!isFakeHost(user->host) || !isFakeHost(new_host)) 
+        return;
     //extract user names
     char oldauth[AUTHLEN], newauth[AUTHLEN];
     char *p;
-    if((p = strstr(old_user->host, "."))) {
+    if((p = strstr(user->host, "."))) {
         *p = '\0';
-        strcpy(oldauth, old_user->host);
+        strcpy(oldauth, user->host);
         *p = '.';
     }
-    if((p = strstr(new_user->host, "."))) {
+    if((p = strstr(new_host, "."))) {
         *p = '\0';
-        strcpy(newauth, new_user->host);
+        strcpy(newauth, new_host);
         *p = '.';
     }
     if(!stricmp(oldauth, newauth))
-        return 0;
+        return;
     //check if we know this user; then check the new auth
     MYSQL_RES *res;
     MYSQL_ROW row;
@@ -293,21 +300,21 @@ static int event_user_registered(struct UserNode *old_user, struct UserNode *new
         struct event_user_registered_cache *cache = malloc(sizeof(*cache));
         if (!cache) {
             perror("malloc() failed");
-            return 1;
+            return;
         }
-        cache->new_user = new_user;
+        cache->user = user;
         cache->oldauth = strdup(oldauth);
         lookup_authname(newauth, 0, event_user_registered_auth_lookup, cache);
     }
-    return 1;
+    return;
 }
 
 static AUTHLOOKUP_CALLBACK(event_user_registered_auth_lookup) {
     struct event_user_registered_cache *cache = data;
     if(exists) {
         renameAccount(cache->oldauth, auth);
-        strcpy(cache->new_user->auth, auth);
-        cache->new_user->flags |= USERFLAG_ISAUTHED;
+        strcpy(cache->user->auth, auth);
+        cache->user->flags |= USERFLAG_ISAUTHED;
     }
     free(cache->oldauth);
     free(cache);
index 7d41de5b1145a3f9f4ee697b4e88d01fd3c742f9..56bc57e16e51b06ac89ef9836157cdfb85f78ad5 100644 (file)
@@ -160,11 +160,7 @@ FUNC_EVENT(nick, nick_func_t, BIND_TYPE_NICK, (struct UserNode *user, char *new_
 
 FUNC_BIND(part, part_func_t, BIND_TYPE_PART)
 FUNC_UNBIND(part, part_func_t, BIND_TYPE_PART)
-FUNC_EVENT(part, part_func_t, BIND_TYPE_PART, (struct ChanUser *chanuser, char *reason), (chanuser, reason))
-
-FUNC_BIND(quit, quit_func_t, BIND_TYPE_QUIT)
-FUNC_UNBIND(quit, quit_func_t, BIND_TYPE_QUIT)
-FUNC_EVENT(quit, quit_func_t, BIND_TYPE_QUIT, (struct UserNode *user, char *reason), (user, reason))
+FUNC_EVENT(part, part_func_t, BIND_TYPE_PART, (struct ChanUser *chanuser, int quit, char *reason), (chanuser, quit, reason))
 
 FUNC_BIND(kick, kick_func_t, BIND_TYPE_KICK)
 FUNC_UNBIND(kick, kick_func_t, BIND_TYPE_KICK)
@@ -216,17 +212,7 @@ FUNC_EVENT(bot_ready, bot_ready_func_t, BIND_TYPE_BOT_READY, (struct ClientSocke
 
 FUNC_BIND(registered, registered_func_t, BIND_TYPE_REGISTERED)
 FUNC_UNBIND(registered, registered_func_t, BIND_TYPE_REGISTERED)
-int event_registered(struct UserNode *old_user, struct UserNode *new_user) {
-    struct binding *cbind;
-    int ret = 0;
-    pre_event(BIND_TYPE_REGISTERED);
-    for(cbind = binds[BIND_TYPE_REGISTERED]; cbind; cbind = cbind->next) {
-        registered_func_t *func = cbind->func;
-        ret |= func(old_user, new_user);
-    }
-    post_event(BIND_TYPE_REGISTERED);
-    return ret;
-}
+FUNC_EVENT(registered, registered_func_t, BIND_TYPE_REGISTERED, (struct UserNode *user, char *new_mask), (user, new_mask))
 
 FUNC_BIND(freeuser, freeuser_func_t, BIND_TYPE_FREEUSER)
 FUNC_UNBIND(freeuser, freeuser_func_t, BIND_TYPE_FREEUSER)
index f7b6ce0f46ea8544eaaaa24ce9b9f3d2571bbf06..5c7783424656e993fb0aab86a7a606f0201f0652 100644 (file)
@@ -44,18 +44,11 @@ typedef void nick_func_t(struct UserNode *user, char *new_nick);
 int event_nick(struct UserNode *user, char *new_nick);
 #endif
 
-typedef void part_func_t(struct ChanUser *chanuser, char *reason);
+typedef void part_func_t(struct ChanUser *chanuser, int quit, char *reason);
 #ifndef DND_FUNCTIONS
 /* MODULAR ACCESSIBLE */ int bind_part(part_func_t *func, int module_id);
 /* MODULAR ACCESSIBLE */ void unbind_part(part_func_t *func);
-int event_part(struct ChanUser *chanuser, char *reason);
-#endif
-
-typedef void quit_func_t(struct UserNode *user, char *reason);
-#ifndef DND_FUNCTIONS
-/* MODULAR ACCESSIBLE */ int bind_quit(quit_func_t *func, int module_id);
-/* MODULAR ACCESSIBLE */ void unbind_quit(quit_func_t *func);
-int event_quit(struct UserNode *user, char *reason);
+int event_part(struct ChanUser *chanuser, int quit, char *reason);
 #endif
 
 typedef void kick_func_t(struct UserNode *user, struct ChanUser *target, char *reason);
@@ -142,11 +135,11 @@ typedef void bot_ready_func_t(struct ClientSocket *client);
 int event_bot_ready(struct ClientSocket *client);
 #endif
 
-typedef int registered_func_t(struct UserNode *old_user, struct UserNode *new_user);
+typedef void registered_func_t(struct UserNode *user, char *new_mask);
 #ifndef DND_FUNCTIONS
 /* MODULAR ACCESSIBLE */ int bind_registered(registered_func_t *func, int module_id);
 /* MODULAR ACCESSIBLE */ void unbind_registered(registered_func_t *func);
-int event_registered(struct UserNode *old_user, struct UserNode *new_user);
+int event_registered(struct UserNode *user, char *new_mask);
 #endif
 
 typedef int freeuser_func_t(struct UserNode *user);
index 2c30d6992dfe32f89abe3fd6b944d97b3e8652c4..3d410a471824b392016cbd8bb08b74b8208a8480 100644 (file)
@@ -30,7 +30,7 @@
 #include "bots.h"
 
 struct irc_cmd *irc_commands = NULL;
-static struct UserNode *registering_users = NULL;
+//static struct UserNode *registering_users = NULL;
 int statistics_privmsg = 0;
 int statistics_network_users = 0;
 int statistics_network_channels = 0;
@@ -132,105 +132,46 @@ static IRC_CMD(raw_002) { //fixed: ZNC fakes a 001 raw even if we're not connect
     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 int is_onlyBotSeeUser(struct ClientSocket *client, struct UserNode *user) {
-    struct ClientSocket *bot;
-    struct ChanUser *chanuser;
-    for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
-        if(bot == client) continue;
-        for(chanuser = getUserChannels(bot->user, NULL); chanuser; chanuser = getUserChannels(bot->user, chanuser)) {
-            if(isUserOnChan(user, chanuser->chan)) {
-                return 0;
-            }
-        }
-    }
-    return 1;
-}
-
 static IRC_CMD(raw_join) {
     if(from == NULL || argc < 1) return 0;
     SYNCHRONIZE(cache_sync);
     struct UserNode *user = getUserByMask(from);
     struct ChanNode *chan = getChanByName(argv[0]);
+    struct ChanUser *chanuser;
     if(!chan && (!user || !(user->flags & USERFLAG_ISBOT))) {
+        //parse error if the channel is not known, yet and it's not a bot joining
         DESYNCHRONIZE(cache_sync);
         return 0;
     }
-    if(chan && (((!user || !isBot(user)) && chan->chanbot != client->user) || ((user && isBot(user)) && client->user != user))) {
-        DESYNCHRONIZE(cache_sync);
-        return 1; //we ignore it - but it's not a parse error
-    }
-    //let Bots always add themselves! (maybe they join invisible)
-    if(user == NULL) {
+    if(user == NULL)
         user = addUserMask(from);
-    }
-    struct UserNode *registering, *last_registering = NULL, *next_registering;
-    int noEvent = 0, wasRegistering = 0;
-    for(registering = registering_users; registering; registering = next_registering) {
-        next_registering = registering->next;
-        if(!strcmp(registering->nick, user->nick)) {
-            noEvent = event_registered(registering, user);
-            wasRegistering = 1;
-            if(last_registering)
-                last_registering->next = registering->next;
-            else
-                registering_users = registering->next;
-            delUser(registering, 1);
-        } else if(time(0) - registering->created > 2) {
-            if(last_registering)
-                last_registering->next = registering->next;
-            else
-                registering_users = registering->next;
-            delUser(registering, 1);
-        } else
-            last_registering = registering;
-    }
     if(chan == NULL) {
+        //new channel
         chan = addChannel(argv[0]);
-        //request member list
-        chan->chanbot = user;
-        struct ChanUser *chanuser = addChanUser(chan, user); //it must be a bot
+        chanuser = addChanUser(chan, user);
+        chanuser->visCount = 1;
         get_userlist_with_invisible(chan, 0, got_channel_userlist, chanuser);
         putsock(client, "MODE %s", chan->name);
         putsock(client, "MODE %s +b", chan->name);
-    } else if(!isUserOnChan(user, chan) && ((chan->flags & CHANFLAG_RECEIVED_USERLIST) || isBot(user))) {
-        struct ChanUser *chanuser = addChanUser(chan, user);
+    } else if((user->flags & USERFLAG_WAS_REGISTERING)) {
+        //user rejoined after registering (should still be present in the channel)
+        if(!(chanuser = getChanUser(user, chan)))
+            chanuser = addChanUser(chan, user);
+        chanuser->visCount++;
+        
+        event_registered(user, from);
+        user->flags &= ~USERFLAG_WAS_REGISTERING;
+    } else if(!isUserOnChan(user, chan)) {
+        //join user to an existing channel
+        chanuser = addChanUser(chan, user);
+        chanuser->visCount = 1;
         if(isBot(user) && isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
             chanuser->flags |= CHANUSERFLAG_INVISIBLE;
-        if(!noEvent) {
-            if(wasRegistering)
-                user->flags |= USERFLAG_WAS_REGISTRING;
-            event_join(chanuser);
-            if(wasRegistering)
-                user->flags &= ~USERFLAG_WAS_REGISTRING;
-        }
+        
+        event_join(chanuser);
+        
         if(!(user->flags & USERFLAG_ISBOT) && (chan->flags & CHANFLAG_REJOINING)) {
-            //ABORT REJOIN (security break)
+            //ABORT AUTOMATIC REJOIN (security break)
             struct ClientSocket **clients = chan->rejoin_array;
             while(*clients) {
                 putsock(*clients, "JOIN %s", chan->name);
@@ -239,11 +180,12 @@ static IRC_CMD(raw_join) {
             free(chan->rejoin_array);
             chan->flags &= ~CHANFLAG_REJOINING;
         }
-    } else if(isUserOnChan(user, chan)) { //user is already in the channel? ^^
-        //first bot rejoined
-        chan->flags &= ~CHANFLAG_RECEIVED_USERLIST;
-        struct ChanUser *chanuser = getChanUser(user, chan);
-        get_userlist_with_invisible(chan, 0, got_channel_userlist, chanuser);
+    } else { 
+        //user is already in the channel
+        chanuser = getChanUser(user, chan);
+        chanuser->visCount++;
+        //if multiple bots see the user, it can't be invisible
+        chanuser->flags &= ~CHANUSERFLAG_INVISIBLE;
     }
     DESYNCHRONIZE(cache_sync);
     return 1;
@@ -263,21 +205,26 @@ static void check_full_rejoin(struct ChanNode *chan) {
     }
     if(do_rejoin) {
         struct ClientSocket **clients = calloc(botcount, sizeof(*clients));
-        struct ClientSocket *bot, *chanbot;
+        struct ClientSocket *bot, *chanbot = NULL;
         int i = 0;
         for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
-            if(bot->user != chan->chanbot && isUserOnChan(bot->user, chan)) {
+            if(!isUserOnChan(bot->user, chan))
+                continue;
+            if(!chanbot && ((bot->flags & SOCKET_FLAG_PREFERRED) || !getBots(SOCKET_FLAG_READY, bot)))
+                chanbot = bot;
+            else {
                 clients[i++] = bot;
                 putsock(bot, "PART %s :rejoining", chan->name);
-            } else if(bot->user == chan->chanbot)
-                chanbot = bot;
+            }
         }
-        chan->flags |= CHANFLAG_REJOINING;
-        chan->rejoin_array = clients;
         if(botcount == 1) {
             //we're alone
+            free(clients);
             putsock(chanbot, "PART %s :magic hop", chan->name);
             putsock(chanbot, "JOIN %s", chan->name);
+        } else {
+            chan->flags |= CHANFLAG_REJOINING;
+            chan->rejoin_array = clients;
         }
     }
 }
@@ -286,53 +233,104 @@ static IRC_CMD(raw_part) {
     if(from == NULL || argc < 1) return 0;
     SYNCHRONIZE(cache_sync);
     struct UserNode *user = getUserByMask(from);
-    if(user == NULL) {
-        DESYNCHRONIZE(cache_sync);
-        return 0;
-    }
     struct ChanNode *chan = getChanByName(argv[0]);
-    if(chan == NULL) {
+    struct ChanUser *chanuser;
+    if(user == NULL || chan == NULL || !(chanuser = getChanUser(user, chan))) {
         DESYNCHRONIZE(cache_sync);
         return 0;
     }
-    if((!isBot(user) && chan->chanbot != client->user) || (isBot(user) && client->user != user)) {
-        DESYNCHRONIZE(cache_sync);
-        return 1; //we ignore it - but it's not a parse error
+    chanuser->visCount--;
+    if(chanuser->visCount == 0) {
+        delChanUser(chanuser, 0); //not free, yet!
+        event_part(chanuser, 0, (argc > 1 ? argv[1] : NULL));
+        freeChanUser(chanuser);
     }
+    
+    //check if channel is still present
     int keep_channel = 1;
-    if(chan->chanbot == user && (chan->flags & CHANFLAG_REJOINING)) {
-        struct ClientSocket **clients = chan->rejoin_array;
-        while(*clients) {
-            putsock(*clients, "JOIN %s", chan->name);
-            clients++;
+    if(chan->usercount == 0) {
+        if((chan->flags & CHANFLAG_REJOINING)) {
+            struct ClientSocket **clients = chan->rejoin_array;
+            while(*clients) {
+                putsock(*clients, "JOIN %s", chan->name);
+                clients++;
+            }
+            free(chan->rejoin_array);
+            chan->flags &= ~CHANFLAG_REJOINING;
         }
-        free(chan->rejoin_array);
-        chan->flags &= ~CHANFLAG_REJOINING;
+        delChannel(chan, 1);
+        keep_channel = 0;
+    } else if(isBot(user)) //bot parted - check if theres another bot in the channel
+        keep_channel = checkChannelVisibility(chan);
+    
+    // free user if he/she is in no other channel
+    if(user->channel == NULL && !(user->flags & USERFLAG_ISBOT))
+        delUser(user, 1);
+
+    if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING))
+        check_full_rejoin(chan);
+    else if(keep_channel && (chan->flags & CHANFLAG_REJOINING) && chan->usercount == 1) {
+        //bot is alone... rejoin!
+        struct ClientSocket *bot;
+        //find the last bot in the channel
+        for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+            if(isUserOnChan(bot->user, chan)) {
+                putsock(bot, "PART %s :magic hop", chan->name);
+                putsock(bot, "JOIN %s", chan->name);
+            }
+        }
+    }
+    DESYNCHRONIZE(cache_sync);
+    return 1;
+}
+
+static IRC_CMD(raw_kick) {
+    if(from == NULL || argc < 3) return 0;
+    SYNCHRONIZE(cache_sync);
+    struct UserNode *user = getUserByMask(from);
+    struct UserNode *target = getUserByNick(argv[1]);
+    struct ChanNode *chan = getChanByName(argv[0]);
+    struct ChanUser *chanuser;
+    if(chan == NULL || target == NULL || !(chanuser = getChanUser(target, chan))) {
         DESYNCHRONIZE(cache_sync);
         return 0;
-    } else 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));
-        freeChanUser(chanuser);
-        if(chan->chanbot == user) {
-            //check if theres another bot in the channel - otherwise free it
-            keep_channel = checkChannelVisibility(chan);
-        }
     }
-    if(user->channel == NULL && !(user->flags & USERFLAG_ISBOT)) {
-        //remove the user
-        delUser(user, 1);
+    chanuser->visCount--;
+    if(chanuser->visCount == 0) {
+        delChanUser(chanuser, 0); //not free, yet!
+        event_kick(user, chanuser, argv[2]);
+        freeChanUser(chanuser);
     }
-    if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING)) {
+    
+    //check if channel is still present
+    int keep_channel = 1;
+    if(chan->usercount == 0) {
+        if((chan->flags & CHANFLAG_REJOINING)) {
+            struct ClientSocket **clients = chan->rejoin_array;
+            while(*clients) {
+                putsock(*clients, "JOIN %s", chan->name);
+                clients++;
+            }
+            free(chan->rejoin_array);
+            chan->flags &= ~CHANFLAG_REJOINING;
+        }
+        delChannel(chan, 1);
+        keep_channel = 0;
+    } else if(isBot(target)) //bot parted - check if theres another bot in the channel
+        keep_channel = checkChannelVisibility(chan);
+    
+    // free user if he/she is in no other channel
+    if(target->channel == NULL && !(target->flags & USERFLAG_ISBOT))
+        delUser(target, 1);
+
+    if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING))
         check_full_rejoin(chan);
-    }
     else if(keep_channel && (chan->flags & CHANFLAG_REJOINING) && chan->usercount == 1) {
         //bot is alone... rejoin!
         struct ClientSocket *bot;
         //find the last bot in the channel
         for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
-            if(bot->user == chan->chanbot) {
+            if(isUserOnChan(bot->user, chan)) {
                 putsock(bot, "PART %s :magic hop", chan->name);
                 putsock(bot, "JOIN %s", chan->name);
             }
@@ -350,125 +348,82 @@ static IRC_CMD(raw_quit) {
         DESYNCHRONIZE(cache_sync);
         return 0;
     }
-    if(!is_firstBotSeeUser(client, user)) {
+    
+    if(client->user == user) {
         DESYNCHRONIZE(cache_sync);
-        return 1; //we ignore it - but it's not a parse error
+        return 0;
     }
-    int registering = !stricmp(argv[0], "Registered");
-    if((registering && (user->flags & USERFLAG_ISBOT))) {
-        DESYNCHRONIZE(cache_sync);
-        return 1; //bot is registering - just ignore it
-    }
-    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) {
-        //check if there are other bots in the users channel - otherwise free them
-        struct ChanUser *chanuser, *next;
-        for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next) {
-            next = getUserChannels(user, chanuser);
-            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->flags &= ~SOCKET_FLAG_READY;
-                bot->user = NULL;
-                break;
-            }
-        }
-    } else if(!registering) {
-        struct ChanUser *chanuser;
-        struct ChanNode *chan;
-        for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
-            chan = chanuser->chan;
-            if((chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING))
-                check_full_rejoin(chan);
+    
+    //check if user is just registering
+    if(!stricmp(argv[0], "Registered"))
+        user->flags |= USERFLAG_WAS_REGISTERING;
+    
+    //decrease visCount counter
+    struct ChanUser *chanuser, *next_chanuser;
+    for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) {
+        next_chanuser = getUserChannels(user, chanuser);
+        chanuser->visCount--;
+        if(chanuser->visCount == 0) {
+            delChanUser(chanuser, 0); //not free, yet!
+            event_part(chanuser, 1, argv[0]);
+            if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING))
+                check_full_rejoin(chanuser->chan);
+            freeChanUser(chanuser);
+        }
+    }
+    
+    if(user->channel == NULL) {
+        if(isBot(user)) {
+            //ASSERT
+            return 0;
         }
+        if((user->flags & USERFLAG_WAS_REGISTERING)) {
+            //TODO: set a timeout or sth like that?
+        } else
+            delUser(user, 1);
     }
-    if(registering && !(user->flags & USERFLAG_ISBOT)) {
-        user->next = registering_users;
-        user->created = time(0);
-        registering_users = user;
-    } else
-        delUser(user, 1); //now we fully free the user
+    
     DESYNCHRONIZE(cache_sync);
     return 1;
 }
 
 void bot_disconnect(struct ClientSocket *client) {
     struct UserNode *user = client->user;
-    struct ChanUser *chanuser, *next;
     if(user) {
-        if(is_onlyBotSeeUser(client, user)) {
-            //ok  the bot-user is not seen by any other bots so we can simply free it.
-            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);
+        //just remove the bot mark from the user and handle a normal quit :)
+        user->flags &= ~USERFLAG_ISBOT;
+        client->user = NULL;
+        client->flags &= ~SOCKET_FLAG_READY;
+        
+        //decrease visCount counter
+        struct ChanUser *chanuser, *next_chanuser;
+        for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) {
+            next_chanuser = getUserChannels(user, chanuser);
+            chanuser->visCount--;
+            if(chanuser->visCount == 0) {
+                delChanUser(chanuser, 0); //not free, yet!
+                event_part(chanuser, 1, "QUIT");
+                if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING))
+                    check_full_rejoin(chanuser->chan);
                 freeChanUser(chanuser);
             }
-            user->channel = NULL;
-            delUser(user, 1); //now we fully free the user
-        } else {
-            //we need to transform the bot-user back to a normal user (BNC FIX)
-            user->flags &= ~USERFLAG_ISBOT;
-            for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next) {
-                next = getUserChannels(user, chanuser);
-                if(chanuser->chan->chanbot == user)
-                    checkChannelVisibility(chanuser->chan);
-            }
         }
-        client->user = NULL;
-        client->flags &= ~SOCKET_FLAG_READY;
+        
+        if(user->channel == NULL)
+            delUser(user, 1);
     }
 }
 
-static IRC_CMD(raw_kick) {
-    if(from == NULL || argc < 3) return 0;
-    SYNCHRONIZE(cache_sync);
-    struct UserNode *user = getUserByMask(from);
-    struct UserNode *target = getUserByNick(argv[1]);
-    struct ChanNode *chan = getChanByName(argv[0]);
-    if(chan == NULL || target == NULL) {
-        DESYNCHRONIZE(cache_sync);
-        return 0;
-    }
-    if(((!isBot(target) && chan->chanbot != client->user) || (isBot(target) && client->user != target))) {
-        DESYNCHRONIZE(cache_sync);
-        return 1; //we ignore it - but it's not a parse error
-    }
-    int keep_channel = 1;
-    if(isUserOnChan(target, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
-        if(user == NULL) {
-            user = createTempUserMask(from);
-                       if(!user) {
-                DESYNCHRONIZE(cache_sync);
-                return 0;
-            }
-            user->flags |= USERFLAG_ISTMPUSER;
-        }
-        struct ChanUser *chanuser = getChanUser(target, chan);
-        delChanUser(chanuser, 0); //we need to free the chanuser manually!
-        event_kick(user, chanuser, argv[1]);
-        if(chanuser->chan->chanbot == user) {
-            //check if theres another bot in the channel - otherwise free it
-            keep_channel = checkChannelVisibility(chan);
-        }
-        freeChanUser(chanuser);
-    }
-    if(target->channel == NULL && !(target->flags & USERFLAG_ISBOT)) {
-        //remove the user
-        delUser(target, 1);
-    }
-    if(keep_channel && (chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chan->flags & CHANFLAG_REJOINING)) {
-        check_full_rejoin(chan);
+static struct ClientSocket *get_first_prefered_bot_in_channel(struct ChanNode *chan) {
+    struct ClientSocket *bot, *chanbot = NULL;
+    for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+        if(!isUserOnChan(bot->user, chan))
+            continue;
+        if(bot->flags & SOCKET_FLAG_PREFERRED)
+            return bot;
+        chanbot = bot;
     }
-    DESYNCHRONIZE(cache_sync);
-    return 1;
+    return chanbot;
 }
 
 static IRC_CMD(raw_topic) {
@@ -480,7 +435,7 @@ static IRC_CMD(raw_topic) {
         DESYNCHRONIZE(cache_sync);
         return 0;
     }
-    if(chan->chanbot != client->user) {
+    if(client != get_first_prefered_bot_in_channel(chan)) {
         DESYNCHRONIZE(cache_sync);
         return 1; //just ignore it to prevent event duplicates
     }
@@ -500,24 +455,6 @@ static IRC_CMD(raw_topic) {
 
 static IRC_CMD(raw_privmsg) {
     if(from == NULL || argc < 2) return 0;
-    if(!stricmplen(from, "*status", 7) || !stricmplen(from, "-sBNC", 5)) {
-        #ifdef HAVE_THREADS
-        unsigned int tid = (unsigned int) pthread_self_tid();
-        while(!clientsocket_parseorder_top(tid)) {
-            usleep(1000); //1ms
-        }
-        #endif
-        if(!match("Disconnected from IRC.*", argv[1])) {
-            //ZNC DISCONNECT
-            bot_disconnect(client);
-            return 1;
-        }
-        if(!match("* disconnected from the server.", argv[1])) {
-            //sBNC DISCONNECT
-            bot_disconnect(client);
-            return 1;
-        }
-    }
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) {
         user = createTempUserMask(from);
@@ -526,7 +463,7 @@ static IRC_CMD(raw_privmsg) {
     }
     if(argv[0][0] == '#') { //Channel message
         struct ChanNode *chan = getChanByName(argv[0]);
-        if(chan && chan->chanbot == client->user) {
+        if(chan && client == get_first_prefered_bot_in_channel(chan)) {
             if(statistics_enabled)
                 statistics_privmsg++;
             if(argv[1][0] == '\001') {
@@ -574,7 +511,7 @@ static IRC_CMD(raw_notice) {
     }
     if(argv[0][0] == '#') { //Channel notice
         struct ChanNode *chan = getChanByName(argv[0]);
-        if(chan && chan->chanbot == client->user)
+        if(chan && client == get_first_prefered_bot_in_channel(chan))
             event_channotice(user, chan, argv[1]);
     } else {
         struct UserNode *target = getUserByNick(argv[0]);
@@ -592,7 +529,7 @@ static IRC_CMD(raw_nick) {
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) {
         DESYNCHRONIZE(cache_sync);
-        return 0;
+        return 1; //maybe already renamed - no parse error
     }
     if(isBot(user)) {
         if(client->user != user) {
@@ -601,9 +538,9 @@ static IRC_CMD(raw_nick) {
         }
         client_renamed(client);
     }
-    else if(!is_firstBotSeeUser(client, user)) {
+    else if(!strcmp(user->nick, argv[0])) {
         DESYNCHRONIZE(cache_sync);
-        return 1; //we ignore it - but it's not a parse error
+        return 1; //user has already this nick (case sensitive)
     }
     event_nick(user, argv[0]);
     renameUser(user, argv[0]);
@@ -667,7 +604,7 @@ static IRC_CMD(raw_mode) {
             DESYNCHRONIZE(cache_sync);
             return 0;
         }
-        if(chan->chanbot != client->user) {
+        if(client != get_first_prefered_bot_in_channel(chan)) {
             DESYNCHRONIZE(cache_sync);
             return 1;
         }
index 07d904fc6117b55104013e034da320e8d8ad0adb..e9cd432ef5c6c34a8dcceb2a69a6c5ce6fbda951 100644 (file)
@@ -22,7 +22,7 @@
 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))
+#define IRC_CMD(NAME) int NAME(struct ClientSocket *client, UNUSED_ARG(char *from), UNUSED_ARG(char **argv), UNUSED_ARG(unsigned int argc))
 typedef IRC_CMD(irc_cmd_t);
 
 struct irc_cmd {
index 992ef0737eddfe9df6ce44407bb8388e774ba4d5..52380d41d6b44cb9d4453ac5f04455c395799f4e 100644 (file)
@@ -30,8 +30,9 @@
 #define USERFLAG_HAS_USERID         0x0200
 #define USERFLAG_IS_ON_WHO_QUEUE    0x0400 /* prevents the user struct from beeing freed too early */
 #define USERFLAG_FREE_AFTER_WHO     0x0800 /* user struct is no more referenced - free it after WHO */
+#define USERFLAG_QUITTING           0x1000 /* user is currently quitting... */
 
-#define USERFLAG_WAS_REGISTRING     0x20000000 /* only set for event_join if the quit reason was Registered */
+#define USERFLAG_WAS_REGISTERING    0x20000000 /* only set for event_join if the quit reason was Registered */
 #define USERFLAG_SCRIPTFLAG1        0x40000000
 #define USERFLAG_SCRIPTFLAG2        0x80000000
 
index db3a291606f51ef8bd5fdc726a93ec21ac04dd4d..4de2468fb237d819ffc5bda26f62a91a301ea30e 100644 (file)
@@ -113,8 +113,8 @@ void *global_functions[] = {
 /* 054 */ (Function) unbind_nick,
 /* 055 */ (Function) bind_part,
 /* 056 */ (Function) unbind_part,
-/* 057 */ (Function) bind_quit,
-/* 058 */ (Function) unbind_quit,
+/* 057 */ (Function) NULL, /* deprecated */
+/* 058 */ (Function) NULL, /* deprecated */
 /* 059 */ (Function) bind_kick,
 /* 060 */ (Function) unbind_kick,
 /* 061 */ (Function) bind_topic,
index 3679234aea712bdeeda7ba8eb8c6aae8fa48fca4..6fad25665145f94df573241197898b68c2eacd10 100644 (file)
@@ -128,16 +128,11 @@ static void start_bots(int type) {
     bind_unbound_required_functions(BOTID);
 }
 
-static void neonfun_parted(struct ChanUser *chanuser, char *reason) {
+static void neonfun_parted(struct ChanUser *chanuser, int quit, char *reason) {
     uno_event_part(chanuser);
     fourwins_event_part(chanuser);
 }
 
-static void neonfun_quitted(struct UserNode *user, char *reason) {
-    uno_event_quit(user);
-    fourwins_event_quit(user);
-}
-
 static int neonfun_freechan(struct ChanNode *chan) {
     uno_event_freechan(chan);
     fourwins_event_freechan(chan);
@@ -183,7 +178,6 @@ void init_NeonFun(int type) {
     //register events
     bind_bot_ready(neonfun_bot_ready, module_id);
     bind_part(neonfun_parted, module_id);
-    bind_quit(neonfun_quitted, module_id);
     bind_freechan(neonfun_freechan, module_id);
     bind_invite(neonfun_event_invite, module_id);
        
index 6698eaea649cef2ef052a14155c63b578b900b09..3b55d146ae024704461bc9d1e16af960ae5ef6d0 100644 (file)
@@ -179,29 +179,6 @@ void fourwins_event_part(struct ChanUser *chanuser) {
     }
 }
 
-void fourwins_event_quit(struct UserNode *user) {
-    struct fourwins_game *game;
-    for(game = fourwins_active_games; game; game = game->next) {
-        if(game->player[0]->user == user || game->player[1]->user == user) {
-            fourwins_reply(game, "NF_4WINS_GAME_CLOSED");
-            fourwins_free_game(game);
-            return;
-        }
-        struct fourwins_guest *guest, *prev_guest = NULL;
-        for(guest = game->guests; guest; guest = guest->next) {
-            if(guest->chanuser->user == user) {
-                if(prev_guest)
-                    prev_guest->next = guest->next;
-                else
-                    game->guests = guest->next;
-                free(guest);
-                break;
-            } else
-                prev_guest = guest;
-        }
-    }
-}
-
 void fourwins_event_freechan(struct ChanNode *chan) {
     struct fourwins_game *game;
     for(game = fourwins_active_games; game; game = game->next) {
index 7e404b6e02c5de4819b16ec7470d34326698d18c..c21fe31f99a9b974be756472d9819e39eac7169e 100644 (file)
@@ -57,7 +57,6 @@ void fourwins_show_matrix(struct fourwins_game *game);
 TIMEQ_CALLBACK(fourwins_timeout);
 void fourwins_free_game(struct fourwins_game *game);
 void fourwins_event_part(struct ChanUser *chanuser);
-void fourwins_event_quit(struct UserNode *user);
 void fourwins_event_freechan(struct ChanNode *chan);
 
 #endif
index 0e2c0280a86131d73c5aea42e661297187395cfa..96f57927f555801b2b19ffbab7efb8669d3be837 100644 (file)
@@ -636,19 +636,6 @@ void uno_event_part(struct ChanUser *chanuser) {
     }
 }
 
-void uno_event_quit(struct UserNode *user) {
-    struct uno_game *game;
-    for(game = uno_active_games; game; game = game->next) {
-        struct uno_player *player;
-        for(player = game->player; player; player = player->next) {
-            if(player->chanuser->user == user) {
-                uno_free_player(player, game->deck);
-                break;
-            }
-        }
-    }
-}
-
 void uno_event_freechan(struct ChanNode *chan) {
     struct uno_game *game;
     for(game = uno_active_games; game; game = game->next) {
index 356fc0054b9aec34bd89bfdee4c67963c276de16..0acbcedadf91ded5e394fe76de439fb623df1469 100644 (file)
@@ -106,7 +106,6 @@ int uno_check_card_valid(struct uno_game *game, struct uno_card *card);
 void uno_play_card(struct uno_game *game, struct uno_player *player, struct uno_card *card);
 
 void uno_event_part(struct ChanUser *chanuser);
-void uno_event_quit(struct UserNode *user);
 void uno_event_freechan(struct ChanNode *chan);
 
 #endif
index 9e3ba72dc3077236b7ab7ef901deee20935cdc99..9d29a50d50bee6a6fd71ef426932d9e123fe0bfc 100644 (file)
@@ -475,7 +475,7 @@ static void neonhelp_event_kick(struct UserNode *user, struct ChanUser *target,
     }
 }
 
-static void neonhelp_event_part(struct ChanUser *target, char *reason) {
+static void neonhelp_event_part(struct ChanUser *target, int quit, char *reason) {
     struct ClientSocket *client;
     MYSQL_RES *res;
     MYSQL_ROW row;
@@ -518,33 +518,6 @@ static void neonhelp_event_part(struct ChanUser *target, char *reason) {
     }
 }
 
-static void neonhelp_event_quit(struct UserNode *target, char *reason) {
-    struct ClientSocket *client;
-    int userHasRequest;
-    for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
-        if(client->botid == BOTID) {
-            userHasRequest = 0;
-            struct NeonHelpNode *helpnode, *prev_helpnode = NULL;
-            if(client->flags & SOCKET_HAVE_HELPNODE) {
-                for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
-                    if(helpnode->user == target) {
-                        userHasRequest = 1;
-                        break;
-                    } else
-                        prev_helpnode = helpnode;
-                }
-            }
-            if(!userHasRequest) continue;
-            //free the user's support request
-            if(prev_helpnode)
-                prev_helpnode->next = helpnode->next;
-            else
-                client->botclass_helpnode = helpnode->next;
-            neonhelp_destroy_support_request(client, helpnode, 0);
-        }
-    }
-}
-
 static void neonhelp_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
        if(client->botid != BOTID)
                return;
@@ -587,7 +560,6 @@ void init_NeonHelp(int type) {
     bind_chanmsg(neonhelp_event_chanmsg, module_id);
     bind_part(neonhelp_event_part, module_id);
     bind_kick(neonhelp_event_kick, module_id);
-    bind_quit(neonhelp_event_quit, module_id);
        bind_invite(neonhelp_event_invite, module_id);
     
     set_trigger_callback(BOTID, module_id, neonhelp_trigger_callback);
index 89f298bdcf8d60fab2465236e314c4d66970e270..0233a059e532c75f79357099d65997ea06349789 100644 (file)
@@ -404,7 +404,6 @@ cmd_neonserv_calc.c
 //EVENTS
 #include "event_neonserv_join.c"
 #include "event_neonserv_part.c"
-#include "event_neonserv_quit.c"
 #include "event_neonserv_kick.c"
 #include "event_neonserv_mode.c"
 #include "event_neonserv_ctcp.c"
@@ -510,7 +509,6 @@ void init_NeonServ(int type) {
     bind_bot_ready(neonserv_bot_ready, module_id);
     bind_join(neonserv_event_join, module_id);
     bind_part(neonserv_event_part, module_id);
-    bind_quit(neonserv_event_quit, module_id);
     bind_chanctcp(neonserv_event_chanctcp, module_id);
     bind_privctcp(general_event_privctcp, module_id);
     bind_channotice(neonserv_event_channotice, module_id);
index 5f8d1440237321d666847a207e310274aa1bd8fe..ea0ce3fc729ce6620f85c6209bdf28a6d8668a75 100644 (file)
 struct neonserv_event_join_cache {
     struct ClientSocket *client;
     struct ChanUser *chanuser;
-    int was_registering;
 };
 
 static USERAUTH_CALLBACK(neonserv_event_join_nick_lookup);
-static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering);
+static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser);
 static TIMEQ_CALLBACK(neonserv_event_join_dynlimit);
 
 static void neonserv_event_join(struct ChanUser *chanuser) {
@@ -59,21 +58,19 @@ static void neonserv_event_join(struct ChanUser *chanuser) {
         }
         cache->client = client;
         cache->chanuser = chanuser;
-        cache->was_registering = (user->flags & USERFLAG_WAS_REGISTRING);
         get_userauth(user, module_id, neonserv_event_join_nick_lookup, cache);
     } else
-        neonserv_event_join_async1(client, chanuser, (user->flags & USERFLAG_WAS_REGISTRING));
+        neonserv_event_join_async1(client, chanuser);
 }
 
 static USERAUTH_CALLBACK(neonserv_event_join_nick_lookup) {
     struct neonserv_event_join_cache *cache = data;
-    if(user) {
-        neonserv_event_join_async1(cache->client, cache->chanuser, cache->was_registering);
-    }
+    if(user)
+        neonserv_event_join_async1(cache->client, cache->chanuser);
     free(cache);
 }
 
-static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering) {
+static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser) {
     struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid));
     struct ChanNode *chan = chanuser->chan;
     struct UserNode *user = chanuser->user;
@@ -140,7 +137,7 @@ static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanU
         if(a)
             b = a+2;
     } while(a);
-    if(greetingPos && (!was_registering || *row[2]))
+    if(greetingPos && *row[2])
         reply(textclient, user, "[%s] %s", chan->name, greeting);
     //USER RIGHTS
     if(!(userflags & DB_CHANUSER_NOAUTOOP)) {
index 7b4846c7b5423710a5f09fc4a3bf62e1281f92c0..b4565c0c0d0a9d1dc6926051cccb480e2589d624 100644 (file)
@@ -15,7 +15,7 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
  */
 
-static void neonserv_event_part(struct ChanUser *chanuser, char *reason) {
+static void neonserv_event_part(struct ChanUser *chanuser, int quit, char *reason) {
     struct ChanNode *chan = chanuser->chan;
     struct UserNode *user = chanuser->user;
     MYSQL_RES *res;
diff --git a/src/modules/NeonServ.mod/event_neonserv_quit.c b/src/modules/NeonServ.mod/event_neonserv_quit.c
deleted file mode 100644 (file)
index 2d1e8ca..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* event_neonserv_quit.c - NeonServ v5.4
- * Copyright (C) 2011-2012  Philipp Kreil (pk910)
- * 
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License 
- * along with this program. If not, see <http://www.gnu.org/licenses/>. 
- */
-
-static void neonserv_event_quit(struct UserNode *user, char *reason) {
-    MYSQL_RES *res;
-    MYSQL_ROW chanuserrow;
-    struct ChanUser *chanuser;
-    if((user->flags & USERFLAG_ISAUTHED)) {
-        for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = getUserChannels(user, chanuser)) {
-            printf_mysql_query("SELECT `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `channel_name` = '%s' AND `user_user` = '%s'", escape_string(chanuser->chan->name), escape_string(user->auth));
-            res = mysql_use();
-            if((chanuserrow = mysql_fetch_row(res)) != NULL)
-                printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", chanuserrow[0]);
-        }
-    }
-}
index 425ad08856ca565f22810fc970d08504f2b04b94..497cc2f0fa5036507da224de38577e71c9909a46 100644 (file)
@@ -27,7 +27,6 @@ struct neonspam_event_join_cache {
 };
 
 static void neonspam_event_join(struct ChanUser *chanuser) {
-    if(chanuser->user->flags & USERFLAG_WAS_REGISTRING) return;
     struct ClientSocket *client = getChannelBot(chanuser->chan, BOTID);
     if(!client) return; //we can't "see" this event
     if(chanuser->user == client->user) {
index bf8958c192ad0be7cbc5b1d98abacb7b38c6204f..7cc075ff0aca2fa47c243adf62034e4c7e801a7b 100644 (file)
@@ -84,8 +84,8 @@ extern int module_id;
 /* 054 */ #define unbind_nick ((void (*)(nick_func_t *))global[54])
 /* 055 */ #define bind_part ((int (*)(part_func_t *, int))global[55])
 /* 056 */ #define unbind_part ((void (*)(part_func_t *))global[56])
-/* 057 */ #define bind_quit ((int (*)(quit_func_t *, int))global[57])
-/* 058 */ #define unbind_quit ((void (*)(quit_func_t *))global[58])
+/* 057 */ /* deprecated */
+/* 058 */ /* deprecated */
 /* 059 */ #define bind_kick ((int (*)(kick_func_t *, int))global[59])
 /* 060 */ #define unbind_kick ((void (*)(kick_func_t *))global[60])
 /* 061 */ #define bind_topic ((int (*)(topic_func_t *, int))global[61])
index 985362d17c2edf8b88835911fdbaee9088f9dc19..093ed80b03618803c579b327e829e9767d32ecce 100644 (file)
@@ -522,7 +522,7 @@ int isFakeHost(char *host) {
     char *p1, *p2 = host;
     
     //find the last dot to identify if the hostmask is a fake host
-    while((p1 = strstr(p2, "."))) {
+    while((p1 = strchr(p2, '.'))) {
         p2 = p1 + 1;
     }
     //TLD database: http://www.iana.org/domains/root/db/
index e4dc9eaef5e3c761cd42fb9ff8fcfea9557bd9e9..38eea8bceca4c5801008a4c9da532f765be4d63b 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "main.h"
 
-#define MODULE_VERSION 4
+#define MODULE_VERSION 5
 
 #ifndef DND_FUNCTIONS
 extern const char *compilation;