X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2FIRCParser.c;h=5d17786d4b2878e5bbc110ee87a2500026b6b583;hb=c575e458c6257e75b97884847143b20965a5dfda;hp=55f3713b15483cd406f15a27bbea7de7d94423b4;hpb=2d9db1adb1946aba00b203f40eff7d5db8163f01;p=NeonServV5.git diff --git a/src/IRCParser.c b/src/IRCParser.c index 55f3713..5d17786 100644 --- a/src/IRCParser.c +++ b/src/IRCParser.c @@ -1,4 +1,4 @@ -/* IRCParser.c - NeonServ v5.1 +/* IRCParser.c - NeonServ v5.2 * Copyright (C) 2011 Philipp Kreil (pk910) * * This program is free software: you can redistribute it and/or modify @@ -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;