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