From: pk910 Date: Sun, 23 Oct 2011 18:27:16 +0000 (+0200) Subject: found and fixed some very strange code in IRCParser.c and solved the duplicate event... X-Git-Tag: v5.3~258 X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=commitdiff_plain;h=7d31bc7adfcfc4a16e5ace2f383a18cae5cd5618 found and fixed some very strange code in IRCParser.c and solved the duplicate event problem --- diff --git a/src/ChanNode.c b/src/ChanNode.c index 480baed..82198e7 100644 --- a/src/ChanNode.c +++ b/src/ChanNode.c @@ -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); diff --git a/src/ChanUser.c b/src/ChanUser.c index 05dbd88..7638d6f 100644 --- a/src/ChanUser.c +++ b/src/ChanUser.c @@ -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); +} + diff --git a/src/ChanUser.h b/src/ChanUser.h index 65ef133..caf845c 100644 --- a/src/ChanUser.h +++ b/src/ChanUser.h @@ -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 diff --git a/src/IRCParser.c b/src/IRCParser.c index 55f3713..b96acea 100644 --- a/src/IRCParser.c +++ b/src/IRCParser.c @@ -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;