X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2FIRCParser.c;h=2d9fbbf5b815cea2dc3c164a56ef5c2aba04cbb6;hb=c49eed20311de32444533a519fa6fbacab481688;hp=3d410a471824b392016cbd8bb08b74b8208a8480;hpb=c8e7ce1c57afaebf3996a6712c45f4c89c34ba44;p=NeonServV5.git diff --git a/src/IRCParser.c b/src/IRCParser.c index 3d410a4..2d9fbbf 100644 --- a/src/IRCParser.c +++ b/src/IRCParser.c @@ -1,4 +1,4 @@ -/* IRCParser.c - NeonServ v5.4 +/* IRCParser.c - NeonServ v5.5 * Copyright (C) 2011-2012 Philipp Kreil (pk910) * * This program is free software: you can redistribute it and/or modify @@ -35,27 +35,10 @@ int statistics_privmsg = 0; int statistics_network_users = 0; int statistics_network_channels = 0; -static void parse_line(struct ClientSocket *client, char *line); static void register_irc_function(char *command, irc_cmd_t *func); static void parse_raw(struct ClientSocket *client, char *from, char *cmd, char **argv, int argc); -int parse_lines(struct ClientSocket *client, char *lines, int len) { - int i, used = 0; - char *line = lines; - for(i = 0; i < len; i++) { - if(lines[i] == '\r') //just zero it out :D - lines[i] = 0; - if(lines[i] == '\n') { - lines[i] = 0; - parse_line(client, line); - line = lines+(i+1); - used = i+1; - } - } - return used; -} - -static void parse_line(struct ClientSocket *client, char *line) { +void parse_line(struct ClientSocket *client, char *line) { int argc = 0; char *argv[MAXNUMPARAMS]; #ifdef HAVE_THREADS @@ -116,8 +99,34 @@ static void parse_raw(struct ClientSocket *client, char *from, char *cmd, char * } } +static void increase_viscount_butone(struct ChanNode *chan, struct ChanUser *ignore) { + struct ChanUser *chanuser; + + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { + if(chanuser == ignore) + continue; + chanuser->visCount++; + } +} + +static void decrease_viscount_butone(struct ChanNode *chan, struct ChanUser *ignore) { + struct ChanUser *chanuser, *next_chanuser; + + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next_chanuser) { + next_chanuser = getChannelUsers(chan, chanuser); + if(chanuser == ignore) + continue; + chanuser->visCount--; + if(chanuser->visCount <= 0) + delChanUser(chanuser, 1); + } +} + static USERLIST_CALLBACK(got_channel_userlist) { struct ChanUser *chanuser = data; + + increase_viscount_butone(chanuser->chan, chanuser); + event_join(chanuser); } @@ -161,12 +170,28 @@ static IRC_CMD(raw_join) { event_registered(user, from); user->flags &= ~USERFLAG_WAS_REGISTERING; + } else if(!(chan->flags & CHANFLAG_RECEIVED_USERLIST)) { + if(client->user != user) { //bots are allowed to add themselves + DESYNCHRONIZE(cache_sync); + return 1; //ignore join + } + + chanuser = addChanUser(chan, user); + chanuser->visCount = 1; + + if(isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible + chanuser->flags |= CHANUSERFLAG_INVISIBLE; + + get_userlist_with_invisible(chan, 0, got_channel_userlist, chanuser); } 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(isBot(user)) { + if(isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible + chanuser->flags |= CHANUSERFLAG_INVISIBLE; + increase_viscount_butone(chan, chanuser); + } event_join(chanuser); @@ -184,6 +209,10 @@ static IRC_CMD(raw_join) { //user is already in the channel chanuser = getChanUser(user, chan); chanuser->visCount++; + + if(isBot(user) && !(chanuser->flags & CHANUSERFLAG_INVISIBLE)) + increase_viscount_butone(chan, chanuser); + //if multiple bots see the user, it can't be invisible chanuser->flags &= ~CHANUSERFLAG_INVISIBLE; } @@ -239,6 +268,8 @@ static IRC_CMD(raw_part) { DESYNCHRONIZE(cache_sync); return 0; } + if(isBot(user) && user == client->user) + decrease_viscount_butone(chan, chanuser); chanuser->visCount--; if(chanuser->visCount == 0) { delChanUser(chanuser, 0); //not free, yet! @@ -295,6 +326,8 @@ static IRC_CMD(raw_kick) { DESYNCHRONIZE(cache_sync); return 0; } + if(isBot(target) && target == client->user) + decrease_viscount_butone(chan, chanuser); chanuser->visCount--; if(chanuser->visCount == 0) { delChanUser(chanuser, 0); //not free, yet! @@ -363,7 +396,7 @@ static IRC_CMD(raw_quit) { for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) { next_chanuser = getUserChannels(user, chanuser); chanuser->visCount--; - if(chanuser->visCount == 0) { + if(chanuser->visCount <= 0 && !(user->flags & USERFLAG_WAS_REGISTERING)) { delChanUser(chanuser, 0); //not free, yet! event_part(chanuser, 1, argv[0]); if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING)) @@ -399,12 +432,13 @@ void bot_disconnect(struct ClientSocket *client) { struct ChanUser *chanuser, *next_chanuser; for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) { next_chanuser = getUserChannels(user, chanuser); + decrease_viscount_butone(chanuser->chan, chanuser); chanuser->visCount--; - if(chanuser->visCount == 0) { + 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); + if(chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) + checkChannelVisibility(chanuser->chan); freeChanUser(chanuser); } }