]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanservnetevents.c
32cadf43ab05be824bdc5aff006acbaa1d0e6d0b
3 * Handles the bot reaction to network events (joins, parts, mode changes
9 #include "../channel/channel.h"
10 #include "../nick/nick.h"
11 #include "../localuser/localuser.h"
12 #include "../localuser/localuserchannel.h"
17 * This is for HOOK_NICK_NEWNICK and HOOK_NICK_ACCOUNT.
18 * Associate the nick with it's correct account.
21 void cs_handlenick(int hooknum
, void *arg
) {
27 void cs_handlesethost(int hooknum
, void *arg
) {
33 void cs_handlelostnick(int hooknum
, void *arg
) {
37 if ((rup
=getreguserfromnick(np
))) {
38 /* Clean up if this is the last user. auth->usercount is decremented
39 * AFTER the hook is sent... */
40 if ((rup
->status
& QUSTAT_DEAD
) && (np
->auth
->usercount
==1)) {
45 if (getactiveuserfromnick(np
))
46 freeactiveuser(getactiveuserfromnick(np
));
50 * cs_handlenewchannel:
51 * This is for the HOOK_CHANNEL_NEWCHANNEL message.
52 * A new channel has just been created on the network, associate
53 * with the registered channel (if one exists) unless it's suspended.
56 void cs_handlenewchannel(int hooknum
, void *arg
) {
57 channel
*cp
=(channel
*)arg
;
60 /* Get the registered channel */
61 if ((rcp
=(regchan
*)cp
->index
->exts
[chanservext
])==NULL
|| CIsSuspended(rcp
))
64 /* chanservjoinchan() will deal with joining the channel and/or setting the timestamp */
67 /* Make sure the right modes are set/cleared */
68 cs_checkchanmodes(cp
);
70 /* Start the timer rolling */
71 cs_timerfunc(cp
->index
);
73 /* If topicsave or forcetopic is set, update the topic */
74 if (CIsForceTopic(rcp
) || CIsTopicSave(rcp
)) {
75 localsettopic(chanservnick
, cp
, (rcp
->topic
) ? rcp
->topic
->content
: "");
79 void cs_handlechanlostuser(int hooknum
, void *arg
) {
80 void **args
=(void **)arg
;
84 if (!(rcp
=cp
->index
->exts
[chanservext
]) || CIsSuspended(rcp
) || !chanservnick
||
85 (chanservnick
==args
[1]))
91 if (cp
->users
->totalusers
==2 &&
92 getnumerichandlefromchanhash(cp
->users
, chanservnick
->numeric
)) {
93 /* OK, Q is on the channel and not the one leaving.. */
94 rcp
->lastpart
=time(NULL
);
95 cs_schedupdate(cp
->index
, 1, 5);
101 * cs_handlelostchannel:
102 * This is for the HOOK_CHANNEL_LOSTCHANNEL message.
103 * A channel has just disappeared, clear our association with it.
106 void cs_handlelostchannel(int hooknum
, void *arg
) {
107 /* channel *cp=(channel *)arg; */
109 /* Do we actually need to do anything here? */
114 * A user joined a channel. See if we need to op/etc. them.
115 * Use this for JOIN or CREATE.
118 void cs_handlejoin(int hooknum
, void *arg
) {
119 void **arglist
=(void **)arg
;
120 channel
*cp
=(channel
*)arglist
[0];
121 nick
*np
=(nick
*)arglist
[1];
124 regchanuser
*rcup
=NULL
;
126 int iscreate
, isopped
;
132 /* If not registered or suspended, ignore */
133 if (!(rcp
=cp
->index
->exts
[chanservext
]) || CIsSuspended(rcp
))
140 if (cp
->users
->totalusers
> rcp
->maxusers
)
141 rcp
->maxusers
=cp
->users
->totalusers
;
142 if (cp
->users
->totalusers
> rcp
->tripusers
)
143 rcp
->tripusers
=cp
->users
->totalusers
;
145 /* If their auth is deleted, pretend they don't exist */
146 rup
=getreguserfromnick(np
);
147 if (rup
&& (rup
->status
& QUSTAT_DEAD
))
150 if (rup
&& (rcup
=findreguseronchannel(rcp
,rup
)) && CUKnown(rcup
) && cp
->users
->totalusers
>= 3)
151 rcp
->lastactive
=time(NULL
);
153 /* Update last use time */
155 rcup
->usetime
=getnettime();
157 if (rcp
->lastcountersync
< (time(NULL
) - COUNTERSYNCINTERVAL
)) {
158 csdb_updatechannelcounters(rcp
);
159 rcp
->lastcountersync
=time(NULL
);
162 /* OK, this may be a CREATE but it's possible we have already bursted onto
163 * the channel and deopped them. So let's just check that out now.
165 * There's a distinction between "is it a create?" and "are they opped
166 * already?", since we need to send the generic "This is a Q9 channel"
167 * message on create even if we already deopped them. */
168 if (hooknum
==HOOK_CHANNEL_CREATE
) {
170 if ((lp
=getnumerichandlefromchanhash(cp
->users
, np
->numeric
)) && (*lp
& CUMODE_OP
))
178 /* Check for "Q ban" */
179 if (!IsService(np
) && cs_bancheck(np
,cp
)) {
180 /* They got kicked.. */
184 /* Check for other ban lurking on channel which we are enforcing */
185 if (!IsService(np
) && CIsEnforce(rcp
) && nickbanned_visible(np
,cp
)) {
186 localkickuser(chanservnick
,cp
,np
,"Banned.");
190 /* Check for +b chanlev flag */
191 if (!IsService(np
) && rcup
&& CUIsBanned(rcup
)) {
192 cs_banuser(NULL
, cip
, np
, NULL
);
197 /* Check for +k chan flag */
198 if (!IsService(np
) && CIsKnownOnly(rcp
) && !(rcup
&& CUKnown(rcup
))) {
199 /* Don't ban if they are already "visibly" banned for some reason. */
200 if (IsInviteOnly(cp
) || (IsRegOnly(cp
) && !IsAccount(np
))) {
201 localkickuser(chanservnick
,cp
,np
,"Authorised users only.");
203 cs_banuser(NULL
, cip
, np
, "Authorised users only.");
210 /* They're not a registered user, so deop if it is a create */
211 if (isopped
&& !IsService(np
)) {
214 if (CIsVoiceAll(rcp
)) {
218 if (CIsWelcome(rcp
)) {
219 dowelcome
=1; /* Send welcome message */
220 } else if (!CIsJoined(rcp
) && iscreate
) {
221 dowelcome
=2; /* Send a generic warning */
225 /* DB update removed for efficiency..
226 * csdb_updatelastjoin(rcup); */
228 /* They are registered, let's see what to do with them */
229 if (CUIsOp(rcup
) && (CIsAutoOp(rcp
) || CUIsAutoOp(rcup
) || CUIsProtect(rcup
) || CIsProtect(rcp
)) &&
234 cs_logchanop(rcp
, np
->nick
, rup
);
237 /* Not auto op; deop them if they are opped and are not allowed them */
238 if (isopped
&& !CUHasOpPriv(rcup
) && !IsService(np
)) {
242 if (!CUIsQuiet(rcup
) && /* Not +q */
243 ((CUIsVoice(rcup
) && (CIsAutoVoice(rcp
) || CUIsAutoVoice(rcup
) ||
244 CIsProtect(rcp
) || CUIsProtect(rcup
))) || /* +[gp]v */
245 (CIsVoiceAll(rcp
)))) { /* Or voice-all chan */
250 if (CIsWelcome(rcp
) && !CUIsHideWelcome(rcup
)) {
255 /* Actually do the mode change, if any */
257 localsetmodes(chanservnick
, cp
, np
, modes
);
262 case 1: if (rcp
->welcome
)
263 chanservsendmessage(np
,"[%s] %s",cip
->name
->content
, rcp
->welcome
->content
);
266 case 2: if (chanservnick
) {
267 /* Channel x is protected by y */
268 chanservstdmessage(np
,QM_PROTECTED
,cip
->name
->content
,chanservnick
->nick
);
273 /* Display infoline if... (deep breath) user is registered, known on channel,
274 * user,channel,chanlev all +i and user,channel,chanlev all -s AND Q online */
276 CIsInfo(rcp
) && UIsInfo(rcup
->user
) && CUIsInfo(rcup
) &&
277 !CIsNoInfo(rcp
) && !UIsNoInfo(rcup
->user
) && !CUIsNoInfo(rcup
) && chanservnick
) {
278 if (rcup
->info
&& *(rcup
->info
->content
)) {
279 /* Chan-specific info */
280 sendmessagetochannel(chanservnick
, cp
, "[%s] %s",np
->nick
, rcup
->info
->content
);
281 } else if (rup
->info
&& *(rup
->info
->content
)) {
283 sendmessagetochannel(chanservnick
, cp
, "[%s] %s",np
->nick
, rup
->info
->content
);
288 /* cs_handlemodechange:
289 * Handle mode change on channel
292 void cs_handlemodechange(int hooknum
, void *arg
) {
293 void **arglist
=(void **)arg
;
294 channel
*cp
=(channel
*)arglist
[0];
295 long changeflags
=(long)arglist
[2];
298 if ((rcp
=cp
->index
->exts
[chanservext
])==NULL
|| CIsSuspended(rcp
))
301 if (changeflags
& MODECHANGE_MODES
)
302 rcp
->status
|= QCSTAT_MODECHECK
;
304 if (changeflags
& MODECHANGE_USERS
)
305 rcp
->status
|= QCSTAT_OPCHECK
;
307 if (changeflags
& MODECHANGE_BANS
)
308 rcp
->status
|= QCSTAT_BANCHECK
;
310 cs_timerfunc(rcp
->index
);
313 void cs_handleburst(int hooknum
, void *arg
) {
314 channel
*cp
=(channel
*)arg
;
317 if ((rcp
=cp
->index
->exts
[chanservext
])==NULL
|| CIsSuspended(rcp
))
320 /* Check everything at some future time */
321 /* If autolimit is on, make sure the limit gets reset at that point too */
322 if (CIsAutoLimit(rcp
)) {
325 cs_schedupdate(cp
->index
, 1, 5);
326 rcp
->status
|= (QCSTAT_OPCHECK
| QCSTAT_MODECHECK
| QCSTAT_BANCHECK
);
327 rcp
->lastbancheck
=0; /* Force re-check of all bans on channel */
330 /* cs_handleopchange:
331 * Handle [+-][ov] event
334 void cs_handleopchange(int hooknum
, void *arg
) {
335 void **arglist
=(void **)arg
;
336 channel
*cp
=(channel
*)arglist
[0];
340 nick
*target
=(nick
*)arglist
[2];
343 /* Check that the channel is registered and active */
344 if ((rcp
=cp
->index
->exts
[chanservext
])==NULL
|| CIsSuspended(rcp
))
347 rup
=getreguserfromnick(target
);
350 case HOOK_CHANNEL_OPPED
:
351 if (CIsBitch(rcp
) && !IsService(target
)) {
352 if (!rup
|| (rcup
=findreguseronchannel(rcp
,rup
))==NULL
|| !CUIsOp(rcup
) || CUIsDeny(rcup
))
358 * Should +b prevent extra voices?
359 * If not, should we have a seperate mode that does?
362 case HOOK_CHANNEL_DEOPPED
:
363 if (CIsProtect(rcp
)) {
364 if (rup
&& (rcup
=findreguseronchannel(rcp
,rup
))!=NULL
&& CUIsOp(rcup
) && !CUIsDeny(rcup
))
369 case HOOK_CHANNEL_DEVOICED
:
370 if (CIsProtect(rcp
)) {
371 if (rcp
&& (rcup
=findreguseronchannel(rcp
,rup
))!=NULL
&& CUIsVoice(rcup
) && !CUIsQuiet(rcup
))
378 localsetmodes(chanservnick
, cp
, target
, modes
);
382 * Handle ban being added to channel
385 void cs_handlenewban(int hooknum
, void *arg
) {
386 void **arglist
=(void **)arg
;
388 channel
*cp
=(channel
*)arglist
[0];
393 if ((rcp
=cp
->index
->exts
[chanservext
])==NULL
|| CIsSuspended(rcp
))
396 if ((cbp
=cp
->bans
)==NULL
) {
397 Error("chanserv",ERR_WARNING
,"Told ban added but no bans on channel?");
401 if (CIsEnforce(rcp
)) {
402 for (i
=0;i
<cp
->users
->hashsize
;i
++) {
403 if (cp
->users
->content
[i
]!=nouser
) {
404 if ((np
=getnickbynumeric(cp
->users
->content
[i
]))==NULL
) {
405 Error("chanserv",ERR_WARNING
,"Found user on channel %s who doesn't exist!",cp
->index
->name
->content
);
408 if (!IsService(np
) && nickmatchban_visible(np
,cbp
)) {
409 localkickuser(chanservnick
,cp
,np
,"Banned.");
416 /* cs_handletopicchange:
417 * Handle topic change on channel
420 void cs_handletopicchange(int hooknum
, void *arg
) {
421 void **arglist
=(void **)arg
;
422 channel
*cp
=(channel
*)arglist
[0];
425 if ((rcp
=cp
->index
->exts
[chanservext
])==NULL
|| CIsSuspended(rcp
))
428 if (CIsForceTopic(rcp
)) {
430 /* Forced topic: change it back */
431 localsettopic(chanservnick
, cp
, rcp
->topic
->content
);
433 } else if (CIsTopicSave(rcp
)) {
435 freesstring(rcp
->topic
);
438 rcp
->topic
=getsstring(cp
->topic
->content
,TOPICLEN
);
442 csdb_updatetopic(rcp
);