]> jfr.im git - irc/quakenet/newserv.git/blob - helpmod2/hhooks.c
helpmod2 version 2.02
[irc/quakenet/newserv.git] / helpmod2 / hhooks.c
1 #include <string.h>
2 #include <assert.h>
3
4 #include "../core/hooks.h"
5 #include "../localuser/localuser.h"
6
7 #include "helpmod.h"
8 #include "hchannel.h"
9 #include "haccount.h"
10 #include "huser.h"
11 #include "hban.h"
12 #include "hqueue.h"
13 #include "hgen.h"
14 #include "hstat.h"
15
16 void helpmod_hook_quit(int unused, void *args)
17 {
18 nick *nck = ((nick**)args)[0];
19 huser *husr = huser_get(nck);
20 /* it was someone we didn't even know */
21 if (husr == NULL)
22 return;
23 }
24 /*
25 void helpmod_hook_part(int unused, void *args)
26 {
27 channel *chan = ((channel**)args)[0];
28 hchannel *hchan = hchannel_get_by_channel(chan);
29 nick *nck = ((nick**)args)[1];
30 huser *husr;
31
32
33 }
34 */
35 void helpmod_hook_join(int unused, void *args)
36 {
37 channel *chan = ((channel**)args)[0];
38 hchannel *hchan = hchannel_get_by_channel(chan);
39 nick *nck = ((nick**)args)[1];
40 huser *husr;
41
42 /* if we're not on this channel, the event is of no interest */
43 if (hchan == NULL || hchan->flags & H_PASSIVE)
44 return;
45
46 husr = huser_get(nck);
47
48 assert(husr != NULL); /* hook_channel_newnick should fix this */
49
50 if (hchan->flags & H_JOINFLOOD_PROTECTION)
51 {
52 if (hchan->jf_control < time(NULL))
53 hchan->jf_control = time(NULL);
54 else
55 hchan->jf_control++;
56
57 if (hchan->jf_control - time(NULL) > 25 && !IsRegOnly(hchan))
58 {
59 if (hchan->flags & H_REPORT && hchannel_is_valid(hchan->report_to))
60 helpmod_message_channel(hchan->report_to, "Warning: Possible join flood on %s, setting +r", hchannel_get_name(hchan));
61 hchannel_activate_join_flood(hchan);
62 }
63 }
64
65 if (hchan->flags & H_DO_STATS)
66 hstat_add_join(hchan);
67
68 if (hchan->flags & H_TROJAN_REMOVAL && huser_is_trojan(husr))
69 {
70 hban_huser(husr, "Trojan client", time(NULL) + 4 * HDEF_d, 1);
71 return;
72 }
73
74 if (huser_get_level(husr) > H_PEON && (huser_get_account_flags(husr) & H_AUTO_OP) && hchannel_authority(hchan, husr))
75 helpmod_channick_modes(husr, hchan ,MC_OP,HNOW);
76
77 if (huser_get_level(husr) > H_PEON && (huser_get_account_flags(husr) & H_AUTO_VOICE) && hchannel_authority(hchan, husr))
78 helpmod_channick_modes(husr, hchan, MC_VOICE,HNOW);
79
80 if (hchan->flags & H_WELCOME && *hchan->real_channel->index->name->content)
81 helpmod_reply(husr, chan, "[%s] %s", hchan->real_channel->index->name->content, hchan->welcome);
82
83
84 if (hchan->flags & H_QUEUE && hchan->flags & H_QUEUE_SPAMMY)
85 {
86 if (huser_get_level(husr) < H_STAFF)
87 helpmod_reply(husr, NULL, "Channel %s is using a queue system. This means you will have to wait for support. Your queue position is #%d and currently the average time in queue is %s. Please wait for your turn and do not attempt to contact channel operators directly", hchannel_get_name(hchan), hqueue_get_position(hchan, husr), helpmod_strtime(hqueue_average_time(hchan)));
88 }
89 if (IsModerated(hchan->real_channel) && !(hchan->flags & H_QUEUE) && (hchan->flags & H_ANTI_IDLE))
90 { /* being nice to users */
91 if (huser_get_level(husr) < H_STAFF)
92 helpmod_reply(husr, NULL, "Channel %s is currently moderated and there are anti-idle measures in place. This usually means that there is no one to handle your problem at this time. Please try again later and don't forget to read the FAQ at www.quakenet.org", hchannel_get_name(hchan));
93 }
94 }
95
96 void helpmod_hook_channel_newnick(int unused, void *args)
97 {
98 channel *chan = ((channel**)args)[0];
99 hchannel *hchan = hchannel_get_by_channel(chan);
100 nick *nck = ((nick**)args)[1];
101 huser *husr;
102
103 /* if we're not on this channel, the event is of no interest */
104 if (hchan == NULL)
105 return;
106
107 if ((husr = huser_get(nck)) == NULL)
108 husr = huser_add(nck);
109 /*
110 fprintf(hdebug_file, "%d ADD %s to %s\n", time(NULL), husr->real_user->nick, hchannel_get_name(hchan));
111 fflush(hdebug_file);
112 */
113 assert(huser_on_channel(husr, hchan) == NULL);
114 assert(hchannel_on_channel(hchan, husr) == NULL);
115
116 hchannel_add_user(hchan, husr);
117 huser_add_channel(husr, hchan);
118
119 if (huser_get_level(husr) == H_LAMER || (huser_get_level(husr) == H_PEON && hban_check(nck)))
120 {
121 hban *hb = hban_check(nck);
122 if (hb)
123 {
124 const char *banmask = hban_ban_string(nck, HBAN_HOST);
125
126 helpmod_setban(hchan, banmask, time(NULL) + 1 * HDEF_d, MCB_ADD, HNOW);
127
128 helpmod_kick(hchan, husr,hban_get_reason(hb));
129 }
130 return;
131 }
132 if (hchan->flags & H_QUEUE)
133 hqueue_handle_queue(hchan, NULL);
134 }
135
136 void helpmod_hook_channel_lostnick(int unused, void *args)
137 {
138 channel *chan = ((channel**)args)[0];
139 hchannel *hchan = hchannel_get_by_channel(chan);
140 huser_channel *huserchan;
141 nick *nck = ((nick**)args)[1];
142 huser *husr;
143
144 /* hackery, can't think of a better way to do this */
145 huser *oper = NULL;
146 int handle_queue = 0;
147
148 /* if we're not on this channel, the event is of no interest */
149 if (hchan == NULL)
150 return;
151
152 husr = huser_get(nck);
153
154 assert(husr != NULL);
155
156 huserchan = huser_on_channel(husr, hchan);
157 /*
158 fprintf(hdebug_file, "%d DEL %s from %s\n", time(NULL), husr->real_user->nick, hchannel_get_name(hchan));
159 fflush(hdebug_file);
160 */
161 assert(hchannel_on_channel(hchan, husr) != NULL);
162 assert(huserchan != NULL);
163
164 if ((hchan->flags & H_QUEUE) && (hchan->flags & H_QUEUE_MAINTAIN)) /* && (huser_get_level(husr) == H_PEON) && (huserchan->flags & HCUMODE_VOICE) && (hchannel_count_queue(hchan)))*/
165 if (serverlist[homeserver(husr->real_user->numeric)].linkstate != LS_SQUIT)
166 /* if it was a netsplit, we do not trigger autoqueue */
167 {
168 oper = huserchan->responsible_oper;
169 handle_queue = !0;
170 }
171
172 hchannel_del_user(hchan, husr);
173 huser_del_channel(husr, hchan);
174
175 if (nck == helpmodnick)
176 { /* if H left the channel, we remove all the users from the channel */
177 while (hchan->channel_users)
178 {
179 /*
180 fprintf(hdebug_file, "%d DEL %s from %s\n", time(NULL), hchan->channel_users->husr->real_user->nick, hchannel_get_name(hchan));
181 fflush(hdebug_file);
182 */
183 huser_del_channel(hchan->channel_users->husr, hchan);
184 hchannel_del_user(hchan, hchan->channel_users->husr);
185 }
186 }
187
188 else if (handle_queue)
189 hqueue_handle_queue(hchan, oper);
190 }
191
192 void helpmod_hook_nick_lostnick(int unused, void *args)
193 {
194 nick *nck = ((nick**)args)[0];
195 huser *husr = huser_get(nck);
196
197 /* it was someone we didn't even know */
198 if (husr == NULL)
199 return;
200
201 huser_del(husr);
202 }
203
204 void helpmod_hook_channel_opped(int unused, void *args)
205 {
206 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
207 huser_channel *huserchan;
208 huser *husr, *husr2;
209
210 if (hchan == NULL)
211 return;
212
213 husr = huser_get(((nick**)args)[2]);
214 husr2 = huser_get(((nick**)args)[1]);
215
216 assert(husr != NULL);
217
218 huserchan = huser_on_channel(husr, hchan);
219
220 assert(huserchan != NULL);
221
222 huserchan->flags |= HCUMODE_OP;
223
224 /* if the +o was given by a network service, G will not interfere */
225 if (husr2 == NULL || strlen(husr2->real_user->nick) == 1)
226 return;
227
228 if (huser_get_level(husr) < H_STAFF)
229 helpmod_channick_modes(husr, hchan, MC_DEOP ,HNOW);
230 }
231
232 void helpmod_hook_channel_deopped(int unused, void *args)
233 {
234 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
235 huser_channel *huserchan;
236 huser *husr;
237
238 if (hchan == NULL)
239 return;
240
241 husr = huser_get(((nick**)args)[2]);
242
243 assert(husr != NULL);
244
245 huserchan = huser_on_channel(husr, hchan);
246
247 assert(huserchan != NULL);
248
249 huserchan->flags &= ~HCUMODE_OP;
250
251 }
252
253 void helpmod_hook_channel_voiced(int unused, void *args)
254 {
255 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
256 huser_channel *huserchan;
257 huser *husr;
258
259 if (hchan == NULL)
260 return;
261 husr = huser_get(((nick**)args)[2]);
262
263 assert(husr != NULL);
264
265 huserchan = huser_on_channel(husr, hchan);
266
267 assert(huserchan != NULL);
268
269 huserchan->flags |= HCUMODE_VOICE;
270
271 if (hchan->flags & H_QUEUE)
272 {
273 huserchan->flags |= HQUEUE_DONE;
274 huserchan->last_activity = time(NULL);
275 }
276 }
277
278 void helpmod_hook_channel_devoiced(int unused, void *args)
279 {
280 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
281 huser_channel *huserchan;
282 huser *husr;
283
284 if (hchan == NULL)
285 return;
286
287 husr = huser_get(((nick**)args)[2]);
288
289 assert(husr != NULL);
290
291 huserchan = huser_on_channel(husr, hchan);
292
293 assert(huserchan != NULL);
294
295 huserchan->flags &= ~HCUMODE_VOICE;
296
297 if ((hchan->flags & H_QUEUE) && (hchan->flags & H_QUEUE_MAINTAIN) && (huser_get_level(husr) == H_PEON) && (huserchan->flags & HCUMODE_VOICE) && (hchannel_count_queue(hchan)))
298 {
299 if (serverlist[homeserver(husr->real_user->numeric)].linkstate != LS_SQUIT)
300 { /* if it was a netsplit, we do not trigger autoqueue */
301 hqueue_handle_queue(hchan, huserchan->responsible_oper);
302 /*if (huser_valid(huserchan->responsible_oper) && huser_on_channel(huserchan->responsible_oper, hchan))
303 hqueue_advance(hchan, huserchan->responsible_oper, 1);
304 else
305 hqueue_advance(hchan, huserchan->responsible_oper, 1);
306 */
307 }
308 }
309 }
310
311 void helpmod_hook_channel_topic(int unused, void *args)
312 {
313 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
314 huser *husr;
315
316 if (hchan == NULL)
317 return;
318
319 husr = huser_get(((nick**)args)[2]);
320
321 if (hchan->flags & H_HANDLE_TOPIC)
322 {
323 if (husr != NULL && huser_get_level(husr) >= H_OPER)
324 {
325 htopic_del_all(&hchan->topic);
326 htopic_add(&hchan->topic, hchan->real_channel->topic->content, 0);
327 }
328 else
329 {
330 hchannel_set_topic(hchan);
331 }
332 }
333 }
334
335 void helpmod_hook_nick_account(int unused, void *args)
336 {
337 nick *nck = (nick*)args;
338 huser *husr = huser_get(nck);
339 if (husr == NULL)
340 return;
341 else
342 husr->account = haccount_get_by_name(nck->authname);
343 }
344
345 void helpmod_registerhooks(void)
346 {
347 if (registerhook(HOOK_NICK_QUIT, &helpmod_hook_quit));
348 /*if (registerhook(HOOK_CHANNEL_PART, &helpmod_hook_part));*/
349 if (registerhook(HOOK_CHANNEL_JOIN, &helpmod_hook_join));
350 if (registerhook(HOOK_NICK_LOSTNICK, &helpmod_hook_nick_lostnick));
351 if (registerhook(HOOK_CHANNEL_NEWNICK, &helpmod_hook_channel_newnick));
352 if (registerhook(HOOK_CHANNEL_LOSTNICK, &helpmod_hook_channel_lostnick));
353 if (registerhook(HOOK_CHANNEL_OPPED, &helpmod_hook_channel_opped));
354 if (registerhook(HOOK_CHANNEL_DEOPPED, &helpmod_hook_channel_deopped));
355 if (registerhook(HOOK_CHANNEL_VOICED, &helpmod_hook_channel_voiced));
356 if (registerhook(HOOK_CHANNEL_DEVOICED, &helpmod_hook_channel_devoiced));
357 if (registerhook(HOOK_CHANNEL_TOPIC, &helpmod_hook_channel_topic));
358 if (registerhook(HOOK_NICK_ACCOUNT, &helpmod_hook_nick_account));
359 }
360
361 void helpmod_deregisterhooks(void)
362 {
363 if (deregisterhook(HOOK_NICK_QUIT, &helpmod_hook_quit));
364 /*if (deregisterhook(HOOK_CHANNEL_PART, &helpmod_hook_part));*/
365 if (deregisterhook(HOOK_CHANNEL_JOIN, &helpmod_hook_join));
366 if (deregisterhook(HOOK_NICK_LOSTNICK, &helpmod_hook_nick_lostnick));
367 if (deregisterhook(HOOK_CHANNEL_NEWNICK, &helpmod_hook_channel_newnick));
368 if (deregisterhook(HOOK_CHANNEL_LOSTNICK, &helpmod_hook_channel_lostnick));
369 if (deregisterhook(HOOK_CHANNEL_OPPED, &helpmod_hook_channel_opped));
370 if (deregisterhook(HOOK_CHANNEL_DEOPPED, &helpmod_hook_channel_deopped));
371 if (deregisterhook(HOOK_CHANNEL_VOICED, &helpmod_hook_channel_voiced));
372 if (deregisterhook(HOOK_CHANNEL_DEVOICED, &helpmod_hook_channel_devoiced));
373 if (deregisterhook(HOOK_CHANNEL_TOPIC, &helpmod_hook_channel_topic));
374 if (deregisterhook(HOOK_NICK_ACCOUNT, &helpmod_hook_nick_account));
375 }