Merge branch 'development'
[NeonServV5.git] / src / IRCEvents.c
1 /* IRCEvents.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 #include "IRCEvents.h"
19 #include "UserNode.h"
20 #include "ChanNode.h"
21 #include "ChanUser.h"
22 #include "ClientSocket.h"
23 #include "mysqlConn.h"
24 #include "log.h"
25
26 struct binding {
27     void *func;
28     int module_id;
29     struct binding *next;
30 };
31
32 static void **binds = NULL;
33 #define BIND_TYPE_JOIN       0
34 #define BIND_TYPE_NICK       1
35 #define BIND_TYPE_PART       2
36 #define BIND_TYPE_QUIT       3
37 #define BIND_TYPE_KICK       4
38 #define BIND_TYPE_TOPIC      5
39 #define BIND_TYPE_MODE       6
40 #define BIND_TYPE_CHANMSG    7
41 #define BIND_TYPE_PRIVMSG    8
42 #define BIND_TYPE_CHANNOTICE 9
43 #define BIND_TYPE_PRIVNOTICE 10
44 #define BIND_TYPE_CHANCTCP   11
45 #define BIND_TYPE_PRIVCTCP   12
46 #define BIND_TYPE_INVITE     13
47 #define BIND_TYPE_RAW        14
48 #define BIND_TYPE_BOT_READY  15
49 #define BIND_TYPE_REGISTERED 16
50 #define BIND_TYPE_FREEUSER   17
51 #define BIND_TYPE_FREECHAN   18
52 #define BIND_TYPE_RELOAD     19
53 #define BIND_TYPE_FREECLIENT 20
54
55 #define TOTAL_BIND_TYPES     21
56
57 void init_bind() {
58     if(binds)
59         return;
60     binds = calloc(TOTAL_BIND_TYPES, sizeof(*binds));
61 }
62
63 void free_bind() {
64     struct binding *cbind, *next;
65     int i;
66     for(i = 0; i < TOTAL_BIND_TYPES; i++) {
67         for(cbind = binds[i]; cbind; cbind = next) {
68             next = cbind->next;
69             free(cbind);
70         }
71     }
72     free(binds);
73     binds = NULL;
74 }
75
76 void unregister_module_events(int module_id) {
77     struct binding *cbind, *next, *prev;
78     int i;
79     for(i = 0; i < TOTAL_BIND_TYPES; i++) {
80         prev = NULL;
81         for(cbind = binds[i]; cbind; cbind = next) {
82             next = cbind->next;
83             if(cbind->module_id == module_id) {
84                 if(prev)
85                     prev->next = next;
86                 else
87                     binds[i] = next;
88                 free(cbind);
89             } else
90                 prev = cbind;
91         }
92     }
93 }
94
95 static int is_bound(unsigned char type, void *func) {
96     struct binding *cbind;
97     for(cbind = binds[type]; cbind; cbind = cbind->next) {
98         if(cbind->func == func) 
99             return 1;
100     }
101     return 0;
102 }
103
104 #define FUNC_BIND(NAME,FUNCTYPE,TYPE) \
105 int bind_##NAME(FUNCTYPE *func, int module_id) { \
106     if(!is_bound(TYPE, func)) { \
107         struct binding *cbind = malloc(sizeof(*cbind)); \
108         if (!cbind) { \
109             printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__); \
110             return 0; \
111         } \
112         cbind->func = func; \
113         cbind->module_id = module_id; \
114         cbind->next = binds[TYPE]; \
115         binds[TYPE] = cbind; \
116         return 1; \
117     } \
118     return 0; \
119 }
120
121 #define FUNC_UNBIND(NAME,FUNCTYPE,TYPE) \
122 void unbind_##NAME(FUNCTYPE *func) { \
123     struct binding *cbind, *last = NULL, *next; \
124     for(cbind = binds[TYPE]; cbind; cbind = next) { \
125         next = cbind->next; \
126         if(cbind->func == func) { \
127             if(last) \
128                 last->next = cbind->next; \
129             else \
130                 binds[TYPE] = cbind->next; \
131             free(cbind); \
132         } else \
133             last = cbind; \
134     } \
135 }
136
137 #define FUNC_EVENT(NAME,FUNCTYPE,TYPE,PDECLARATION,PLIST) \
138 int event_##NAME PDECLARATION { \
139     struct binding *cbind; \
140     pre_event(TYPE); \
141     for(cbind = binds[TYPE]; cbind; cbind = cbind->next) { \
142         FUNCTYPE *func = cbind->func; \
143         func PLIST; \
144     } \
145     post_event(TYPE); \
146     return 1; \
147 }
148
149 void pre_event(UNUSED_ARG(int type)) {
150
151 }
152
153 void post_event(UNUSED_ARG(int type)) {
154
155 }
156
157 //EVENTS
158
159 FUNC_BIND(join, join_func_t, BIND_TYPE_JOIN)
160 FUNC_UNBIND(join, join_func_t, BIND_TYPE_JOIN)
161 FUNC_EVENT(join, join_func_t, BIND_TYPE_JOIN, (struct ChanUser *chanuser), (chanuser))
162
163 FUNC_BIND(nick, nick_func_t, BIND_TYPE_NICK)
164 FUNC_UNBIND(nick, nick_func_t, BIND_TYPE_NICK)
165 FUNC_EVENT(nick, nick_func_t, BIND_TYPE_NICK, (struct UserNode *user, char *new_nick), (user, new_nick))
166
167 FUNC_BIND(part, part_func_t, BIND_TYPE_PART)
168 FUNC_UNBIND(part, part_func_t, BIND_TYPE_PART)
169 FUNC_EVENT(part, part_func_t, BIND_TYPE_PART, (struct ChanUser *chanuser, int quit, char *reason), (chanuser, quit, reason))
170
171 FUNC_BIND(kick, kick_func_t, BIND_TYPE_KICK)
172 FUNC_UNBIND(kick, kick_func_t, BIND_TYPE_KICK)
173 FUNC_EVENT(kick, kick_func_t, BIND_TYPE_KICK, (struct UserNode *user, struct ChanUser *target, char *reason), (user, target, reason))
174
175 FUNC_BIND(topic, topic_func_t, BIND_TYPE_TOPIC)
176 FUNC_UNBIND(topic, topic_func_t, BIND_TYPE_TOPIC)
177 FUNC_EVENT(topic, topic_func_t, BIND_TYPE_TOPIC, (struct UserNode *user, struct ChanNode *chan, const char *new_topic), (user, chan, new_topic))
178
179 FUNC_BIND(mode, mode_func_t, BIND_TYPE_MODE)
180 FUNC_UNBIND(mode, mode_func_t, BIND_TYPE_MODE)
181 FUNC_EVENT(mode, mode_func_t, BIND_TYPE_MODE, (struct UserNode *user, struct ChanNode *chan, char *modes, char **args, int argc), (user, chan, modes, args, argc))
182
183 FUNC_BIND(chanmsg, chanmsg_func_t, BIND_TYPE_CHANMSG)
184 FUNC_UNBIND(chanmsg, chanmsg_func_t, BIND_TYPE_CHANMSG)
185 FUNC_EVENT(chanmsg, chanmsg_func_t, BIND_TYPE_CHANMSG, (struct UserNode *user, struct ChanNode *chan, char *message), (user, chan, message))
186
187 FUNC_BIND(privmsg, privmsg_func_t, BIND_TYPE_PRIVMSG)
188 FUNC_UNBIND(privmsg, privmsg_func_t, BIND_TYPE_PRIVMSG)
189 FUNC_EVENT(privmsg, privmsg_func_t, BIND_TYPE_PRIVMSG, (struct UserNode *user, struct UserNode *target, char *message), (user, target, message))
190
191 FUNC_BIND(channotice, channotice_func_t, BIND_TYPE_CHANNOTICE)
192 FUNC_UNBIND(channotice, channotice_func_t, BIND_TYPE_CHANNOTICE)
193 FUNC_EVENT(channotice, channotice_func_t, BIND_TYPE_CHANNOTICE, (struct UserNode *user, struct ChanNode *chan, char *message), (user, chan, message))
194
195 FUNC_BIND(privnotice, privnotice_func_t, BIND_TYPE_PRIVNOTICE)
196 FUNC_UNBIND(privnotice, privnotice_func_t, BIND_TYPE_PRIVNOTICE)
197 FUNC_EVENT(privnotice, privnotice_func_t, BIND_TYPE_PRIVNOTICE, (struct UserNode *user, struct UserNode *target, char *message), (user, target, message))
198
199 FUNC_BIND(chanctcp, chanctcp_func_t, BIND_TYPE_CHANCTCP)
200 FUNC_UNBIND(chanctcp, chanctcp_func_t, BIND_TYPE_CHANCTCP)
201 FUNC_EVENT(chanctcp, chanctcp_func_t, BIND_TYPE_CHANCTCP, (struct UserNode *user, struct ChanNode *chan, char *command, char *text), (user, chan, command, text))
202
203 FUNC_BIND(privctcp, privctcp_func_t, BIND_TYPE_PRIVCTCP)
204 FUNC_UNBIND(privctcp, privctcp_func_t, BIND_TYPE_PRIVCTCP)
205 FUNC_EVENT(privctcp, privctcp_func_t, BIND_TYPE_PRIVCTCP, (struct UserNode *user, struct UserNode *target, char *command, char *text), (user, target, command, text))
206
207 FUNC_BIND(invite, invite_func_t, BIND_TYPE_INVITE)
208 FUNC_UNBIND(invite, invite_func_t, BIND_TYPE_INVITE)
209 FUNC_EVENT(invite, invite_func_t, BIND_TYPE_INVITE, (struct ClientSocket *client, struct UserNode *user, char *channel), (client, user, channel))
210
211 FUNC_BIND(raw, raw_func_t, BIND_TYPE_RAW)
212 FUNC_UNBIND(raw, raw_func_t, BIND_TYPE_RAW)
213 FUNC_EVENT(raw, raw_func_t, BIND_TYPE_RAW, (struct ClientSocket *client, char *from, char *cmd, char **argv, int argc), (client, from, cmd, argv, argc))
214
215 FUNC_BIND(bot_ready, bot_ready_func_t, BIND_TYPE_BOT_READY)
216 FUNC_UNBIND(bot_ready, bot_ready_func_t, BIND_TYPE_BOT_READY)
217 FUNC_EVENT(bot_ready, bot_ready_func_t, BIND_TYPE_BOT_READY, (struct ClientSocket *client), (client))
218
219 FUNC_BIND(registered, registered_func_t, BIND_TYPE_REGISTERED)
220 FUNC_UNBIND(registered, registered_func_t, BIND_TYPE_REGISTERED)
221 FUNC_EVENT(registered, registered_func_t, BIND_TYPE_REGISTERED, (struct UserNode *user, char *new_mask), (user, new_mask))
222
223 FUNC_BIND(freeuser, freeuser_func_t, BIND_TYPE_FREEUSER)
224 FUNC_UNBIND(freeuser, freeuser_func_t, BIND_TYPE_FREEUSER)
225 FUNC_EVENT(freeuser, freeuser_func_t, BIND_TYPE_FREEUSER, (struct UserNode *user), (user))
226
227 FUNC_BIND(freechan, freechan_func_t, BIND_TYPE_FREECHAN)
228 FUNC_UNBIND(freechan, freechan_func_t, BIND_TYPE_FREECHAN)
229 FUNC_EVENT(freechan, freechan_func_t, BIND_TYPE_FREECHAN, (struct ChanNode *chan), (chan))
230
231 FUNC_BIND(reload, reload_func_t, BIND_TYPE_RELOAD)
232 FUNC_UNBIND(reload, reload_func_t, BIND_TYPE_RELOAD)
233 FUNC_EVENT(reload, reload_func_t, BIND_TYPE_RELOAD, (int initialization), (initialization))
234
235 FUNC_BIND(freeclient, freeclient_func_t, BIND_TYPE_FREECLIENT)
236 FUNC_UNBIND(freeclient, freeclient_func_t, BIND_TYPE_FREECLIENT)
237 FUNC_EVENT(freeclient, freeclient_func_t, BIND_TYPE_FREECLIENT, (struct ClientSocket *client), (client))