X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=blobdiff_plain;f=src%2Fevent_neonserv_join.c;h=77d5de7519a200df297dbe939b3b691b405e8c03;hp=a117c18b0c7afa4145ea63a05c42c46a83864d6a;hb=b013fcf166b6b84f7b946412dacfe84ba5cfe6b6;hpb=0f1dc61921eef1db8e404a5a82372e2d1cd55daa diff --git a/src/event_neonserv_join.c b/src/event_neonserv_join.c index a117c18..77d5de7 100644 --- a/src/event_neonserv_join.c +++ b/src/event_neonserv_join.c @@ -1,21 +1,39 @@ +/* event_neonserv_join.c - NeonServ v5.3 + * 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 . + */ 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); +static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering); static TIMEQ_CALLBACK(neonserv_event_join_dynlimit); static void neonserv_event_join(struct ChanUser *chanuser) { struct UserNode *user = chanuser->user; struct ClientSocket *client = getBotForChannel(chanuser->chan); if(!client) return; //we can't "see" this event - if(user->flags & USERFLAG_ISBOT) { - putsock(client, "MODE %s +o %s", chanuser->chan->name, chanuser->user->nick); + if(chanuser->user == client->user) { + requestOp(client->user, chanuser->chan); return; } + if(chanuser->user->flags & USERFLAG_ISBOT) return; loadChannelSettings(chanuser->chan); if(!(chanuser->chan->flags & CHANFLAG_CHAN_REGISTERED)) return; char *ban; @@ -40,31 +58,33 @@ 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, neonserv_event_join_nick_lookup, cache); } else - neonserv_event_join_async1(client, chanuser); + neonserv_event_join_async1(client, chanuser, (user->flags & USERFLAG_WAS_REGISTRING)); } 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); + neonserv_event_join_async1(cache->client, cache->chanuser, cache->was_registering); } free(cache); } -static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser) { +static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering) { struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid)); struct ChanNode *chan = chanuser->chan; struct UserNode *user = chanuser->user; struct ModeBuffer *modeBuf; + int with_halfops = get_int_field("General.have_halfop"); MYSQL_RES *res; MYSQL_ROW row, chanuserrow, defaultrow = NULL; - printf_mysql_query("SELECT `channel_maxusers`, `channel_greeting`, `channel_usergreeting`, `channel_getop`, `channel_getvoice`, `channel_userinfo`, `channel_dynlimit` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); + printf_mysql_query("SELECT `channel_maxusers`, `channel_greeting`, `channel_usergreeting`, `channel_getop`, `channel_getvoice`, `channel_userinfo`, `channel_dynlimit`, `channel_gethalfop` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); res = mysql_use(); if ((row = mysql_fetch_row(res)) == NULL) return; - if(!row[3] || !row[4]) { - printf_mysql_query("SELECT `channel_getop`, `channel_getvoice`, `channel_userinfo` FROM `channels` WHERE `channel_name` = 'defaults'"); + if(!row[3] || !row[4] || !row[5] || (!row[7] && with_halfops)) { + printf_mysql_query("SELECT `channel_getop`, `channel_getvoice`, `channel_userinfo`, `channel_gethalfop` FROM `channels` WHERE `channel_name` = 'defaults'"); res = mysql_use(); defaultrow = mysql_fetch_row(res); } @@ -78,6 +98,8 @@ static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanU chanuserrow = mysql_fetch_row(res); } else chanuserrow = NULL; + if(!chanuserrow) + printf_mysql_query("UPDATE `channels` SET `channel_lastvisit` = UNIX_TIMESTAMP() WHERE `channel_id` = '%d'", chan->channel_id); int userflags = (chanuserrow ? atoi(chanuserrow[1]) : 0); int uaccess = ((chanuserrow && !(userflags & DB_CHANUSER_SUSPENDED)) ? atoi(chanuserrow[0]) : 0); //GREETING @@ -117,15 +139,18 @@ static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanU if(a) b = a+2; } while(a); - if(greetingPos) + if(greetingPos && (!was_registering || *row[2])) reply(textclient, user, "[%s] %s", chan->name, greeting); //USER RIGHTS if(!(userflags & DB_CHANUSER_NOAUTOOP)) { int getop = atoi((row[3] ? row[3] : defaultrow[0])); + int gethalfop = (with_halfops ? atoi((row[7] ? row[7] : defaultrow[3])) : 0); int getvoice = atoi((row[4] ? row[4] : defaultrow[1])); modeBuf = initModeBuffer(client, chan); if(uaccess >= getop && uaccess != 0) { //we disallow auto op for all users modeBufferOp(modeBuf, user->nick); + } else if(with_halfops && uaccess >= gethalfop) { + modeBufferHalfop(modeBuf, user->nick); } else if(uaccess >= getvoice) { modeBufferVoice(modeBuf, user->nick); } @@ -152,8 +177,59 @@ static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanU } } //AUTOINVITE - if(chanuserrow && !strcmp(chanuserrow[3], "0") && time(0) - atol(chanuserrow[3]) >= 30) { - //TODO: autoinvite + if((user->flags & USERFLAG_ISAUTHED) && (!chanuserrow || !strcmp(chanuserrow[3], "0") || time(0) - atol(chanuserrow[3]) >= 30)) { + //check if it's the first channel, the user is seen by the bot (IMPORTANT: ignore other bot's channel!) + char first_chan = 1; + char bot_in_chan; + struct ChanUser *cchanuser, *bchanuser; + struct ClientSocket *bot; + for(cchanuser = getUserChannels(user, NULL); cchanuser; cchanuser = getUserChannels(user, cchanuser)) { + if(chanuser == cchanuser) continue; //ignore this one ;) + //check if this bot is in the specific channel + bot_in_chan = 0; + for(bchanuser = getChannelUsers(cchanuser->chan, NULL); bchanuser; bchanuser = getChannelUsers(cchanuser->chan, bchanuser)) { + if(bchanuser->user->flags & USERFLAG_ISBOT) { + //get the botid + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(bot->user == bchanuser->user) { + if(bot->botid == client->botid) + bot_in_chan = 1; + break; + } + } + if(bot_in_chan) break; + } + } + if(!bot_in_chan) continue; + first_chan = 0; + break; + } + if(first_chan) { + //autoinvite :) + defaultrow = NULL; + printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `channel_name`, `channel_getinvite` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `user_user` = '%s' AND `chanuser_flags` >= '%d'", escape_string(user->auth), DB_CHANUSER_AUTOINVITE); + res = mysql_use(); + int getinvite; + while((chanuserrow = mysql_fetch_row(res)) != NULL) { + userflags = atoi(chanuserrow[1]); + if(!(userflags & DB_CHANUSER_AUTOINVITE)) continue; + if(!(chan = getChanByName(chanuserrow[2]))) continue; //no bot is in the channel + if((bchanuser = getChanUser(client->user, chan)) && (bchanuser->flags & CHANUSERFLAG_OPPED)) + bot = client; + else { + bot = getBotForChannel(chan); + } + if(chanuserrow[3] == NULL && defaultrow == NULL) { + printf_mysql_query("SELECT `channel_getinvite` FROM `channels` WHERE `channel_name` = 'defaults'"); + res = mysql_use(); + defaultrow = mysql_fetch_row(res); + } + getinvite = atoi((chanuserrow[3] ? chanuserrow[3] : defaultrow[0])); + if(atoi(chanuserrow[0]) >= getinvite) { + putsock(bot, "INVITE %s %s", user->nick, chan->name); + } + } + } } }