added new multi log system
[NeonServV5.git] / src / modules / NeonServ.mod / event_neonserv_kick.c
1 /* event_neonserv_kick.c - NeonServ v5.6
2  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17
18 struct neonserv_event_kick_cache {
19     struct ClientSocket *client;
20     struct UserNode *user;
21     struct UserNode *target;
22     struct ChanNode *chan;
23     int userauth_pending;
24 };
25
26 static USERAUTH_CALLBACK(neonserv_event_kick_nick_lookup);
27 static void neonserv_event_kick_async1(struct neonserv_event_kick_cache *cache);
28 static void neonserv_event_kick_async2(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, struct ChanNode *chan);
29
30 static void neonserv_event_kick(struct UserNode *user, struct ChanUser *target, char *reason) {
31     struct ChanNode *chan = target->chan;
32     struct ClientSocket *client;
33     if(isBot(target->user)) {
34         client = getChannelBot(chan, 0);
35         struct ClientSocket *bot = client;
36         for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
37             if(client->user == target->user) {
38                 break;
39             }
40         }
41         if(!client) return;
42         if(bot && bot != client && (isModeSet(chan->modes, 'i') || isModeSet(chan->modes, 'a') || isModeSet(chan->modes, 'l'))) {
43             struct ChanUser *chanuser = getChanUser(bot->user, chan);
44             if(chanuser && chanuser->flags & CHANUSERFLAG_OPPED)
45                 putsock(bot, "INVITE %s %s", target->user->nick, chan->name);
46         }
47         char *key = "";
48         if(isModeSet(chan->modes, 'k')) {
49             key = getModeValue(chan->modes, 'k');
50         }
51         putsock(client, "JOIN %s %s", chan->name, key);
52         return;
53     }
54     client = getBotForChannel(chan);
55     if(!client) return; //we can't "see" this event
56     if(isNetworkService(user)) return; 
57     loadChannelSettings(chan);
58     if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
59     struct neonserv_event_kick_cache *cache = malloc(sizeof(*cache));
60     if (!cache) {
61         printf_log("neonserv", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
62         return;
63     }
64     cache->client = client;
65     cache->user = user;
66     cache->target = target->user;
67     cache->chan = target->chan;
68     cache->userauth_pending = 0;
69     if(!(user->flags & USERFLAG_ISAUTHED)) {
70         get_userauth(user, module_id, neonserv_event_kick_nick_lookup, cache);
71         cache->userauth_pending++;
72     }
73     if(!(target->user->flags & USERFLAG_ISAUTHED)) {
74         get_userauth(target->user, module_id, neonserv_event_kick_nick_lookup, cache);
75         cache->userauth_pending++;
76     }
77     neonserv_event_kick_async1(cache);
78 }
79
80 static USERAUTH_CALLBACK(neonserv_event_kick_nick_lookup) {
81     struct neonserv_event_kick_cache *cache = data;
82     cache->userauth_pending--;
83     neonserv_event_kick_async1(cache);
84 }
85
86 static void neonserv_event_kick_async1(struct neonserv_event_kick_cache *cache) {
87     if(cache->userauth_pending == 0) {
88         neonserv_event_kick_async2(cache->client, cache->user, cache->target, cache->chan);
89         free(cache);
90     }
91 }
92
93 static void neonserv_event_kick_async2(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, struct ChanNode *chan) {
94     if(isUserProtected(chan, target, user)) {
95         char buf[MAXLEN];
96         putsock(client, "KICK %s %s :%s", chan->name, user->nick, build_language_string(user, buf, "NS_USER_PROTECTED", target->nick));
97         putsock(client, "INVITE %s %s", target->nick, chan->name);
98     }
99 }