]>
jfr.im git - irc/quakenet/newserv.git/blob - qabot/qabot_bot.c
4 #include "../nick/nick.h"
5 #include "../localuser/localuserchannel.h"
6 #include "../core/hooks.h"
7 #include "../core/schedule.h"
8 #include "../lib/array.h"
9 #include "../lib/base64.h"
10 #include "../lib/irc_string.h"
11 #include "../lib/splitline.h"
15 qab_bot
* qabot_getbot () {
19 bot
= ( qab_bot
*) malloc ( sizeof ( qab_bot
));
25 bot
-> question_chan
= 0 ;
32 bot
-> flags
= DEFAULTBOTFLAGS
;
34 /*bot->question_interval = QUESTIONINTERVAL;*/
35 bot
-> spam_interval
= SPAMINTERVAL
;
36 bot
-> ask_wait
= ASKWAIT
;
37 bot
-> queued_question_interval
= QUEUEDQUESTIONINTERVAL
;
39 bot
-> lastquestionID
= 0 ;
42 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++)
43 bot
-> questions
[ i
] = 0 ;
61 int qabot_addbot ( char * nickname
, char * user
, char * host
, char * pub_chan
, char * qu_chan
, char * stff_chan
, flag_t flags
, int spam_interval
,
62 int ask_wait
, int queued_question_interval
, nick
* sender
) {
66 if (* pub_chan
!= '#' ) {
68 sendnoticetouser ( qabot_nick
, sender
, "Invalid public channel." );
72 if (* qu_chan
!= '#' ) {
74 sendnoticetouser ( qabot_nick
, sender
, "Invalid question channel." );
78 if (* stff_chan
!= '#' ) {
80 sendnoticetouser ( qabot_nick
, sender
, "Invalid staff channel." );
84 for ( bot
= qab_bots
; bot
; bot
= bot
-> next
) {
85 if (! ircd_strcmp ( bot
-> nick
, nickname
)) {
87 sendnoticetouser ( qabot_nick
, sender
, "That QABot already exists." );
91 if (! ircd_strcmp ( bot
-> public_chan
-> name
-> content
, pub_chan
)) {
93 sendnoticetouser ( qabot_nick
, sender
, "That public channel is already in use by %s ." , bot
-> nick
);
97 if (! ircd_strcmp ( bot
-> question_chan
-> name
-> content
, qu_chan
)) {
99 sendnoticetouser ( qabot_nick
, sender
, "That question channel is already in use by %s ." , bot
-> nick
);
103 if (! ircd_strcmp ( bot
-> staff_chan
-> name
-> content
, stff_chan
)) {
105 sendnoticetouser ( qabot_nick
, sender
, "That staff channel is already in use by %s ." , bot
-> nick
);
110 bot
= qabot_getbot ();
111 strncpy ( bot
-> nick
, nickname
, NICKLEN
);
112 bot
-> nick
[ NICKLEN
] = '\0' ;
113 strncpy ( bot
-> user
, user
, USERLEN
);
114 bot
-> user
[ USERLEN
] = '\0' ;
115 bot
-> host
= strdup ( host
);
116 if (! ircd_strcmp ( nickname
, "Tutor" ))
117 bot
-> np
= registerlocaluser ( nickname
, user
, host
, TUTOR_NAME
, TUTOR_ACCOUNT
, QABOT_CHILD_UMODE
| UMODE_ACCOUNT
, & qabot_child_handler
);
119 bot
-> np
= registerlocaluser ( nickname
, user
, host
, QABOT_NAME
, NULL
, QABOT_CHILD_UMODE
, & qabot_child_handler
);
122 bot
-> spam_interval
= spam_interval
;
123 bot
-> ask_wait
= ask_wait
;
124 bot
-> queued_question_interval
= queued_question_interval
;
126 bot
-> mic_timeout
= QABOT_MICTIMEOUT
;
130 if (( cp
= findchannel ( pub_chan
))) {
131 localjoinchannel ( bot
-> np
, cp
);
132 localgetops ( bot
-> np
, cp
);
133 bot
-> public_chan
= cp
-> index
;
136 localcreatechannel ( bot
-> np
, pub_chan
);
137 cp
= findchannel ( pub_chan
);
138 bot
-> public_chan
= cp
-> index
;
141 if (( cp
= findchannel ( qu_chan
))) {
142 localjoinchannel ( bot
-> np
, cp
);
143 bot
-> question_chan
= cp
-> index
;
146 localcreatechannel ( bot
-> np
, qu_chan
);
147 cp
= findchannel ( qu_chan
);
148 bot
-> question_chan
= cp
-> index
;
151 if (! IsModerated ( cp
)) {
152 irc_send ( " %s M %s +m \r\n " , mynumeric
-> content
, cp
-> index
-> name
-> content
);
156 if (( cp
= findchannel ( stff_chan
))) {
157 localjoinchannel ( bot
-> np
, cp
);
158 localgetops ( bot
-> np
, cp
);
159 bot
-> staff_chan
= cp
-> index
;
162 localcreatechannel ( bot
-> np
, stff_chan
);
163 cp
= findchannel ( stff_chan
);
164 bot
-> staff_chan
= cp
-> index
;
167 bot
-> next
= qab_bots
;
169 qab_bots
-> prev
= bot
;
172 bot
-> np
-> exts
[ qabot_nickext
] = ( void *) bot
;
174 scheduleoneshot ( time ( NULL
) + 10 , & qabot_timer
, ( void *) bot
);
179 void qabot_delbot ( qab_bot
* bot
) {
188 deleteschedule ( 0 , qabot_spam
, ( void *) bot
);
189 deleteschedule ( 0 , qabot_spamstored
, ( void *) bot
);
190 deleteschedule ( 0 , qabot_createbotfakeuser
, ( void *) bot
);
191 deleteschedule ( 0 , qabot_timer
, ( void *) bot
);
194 fclose ( bot
-> recfile
);
199 fclose ( bot
-> playfile
);
200 bot
-> playfile
= NULL
;
203 while ( bot
-> blocks
) {
205 bot
-> blocks
= bot
-> blocks
-> next
;
211 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
212 while ( bot
-> questions
[ i
]) {
213 q
= bot
-> questions
[ i
];
214 bot
-> questions
[ i
] = bot
-> questions
[ i
]-> next
;
223 for ( s
= bot
-> nextspam
; s
; s
= ns
) {
229 for ( a
= bot
-> answers
; a
; a
= na
) {
236 deregisterlocaluser ( bot
-> np
, "Bot deleted." );
239 bot
-> next
-> prev
= bot
-> prev
;
241 bot
-> prev
-> next
= bot
-> next
;
243 qab_bots
= bot
-> next
;
248 void qabot_playback ( qab_bot
* bot
) {
252 if (!( bot
-> playfile
)) {
258 while (! feof ( bot
-> playfile
)) {
259 fscanf ( bot
-> playfile
, "%[^ \n ] \n " , buf
);
261 if (! ircd_strcmp ( "--PAUSE--" , buf
)) {
262 if ( bot
-> staff_chan
&& bot
-> staff_chan
-> channel
) {
263 sendmessagetochannel ( bot
-> np
, bot
-> staff_chan
-> channel
, "Pause found in playback, use !continue when ready to continue playback." );
264 sendmessagetochannel ( bot
-> np
, bot
-> staff_chan
-> channel
, " %l u lines ready to send to channel. This will take approx. %s to send." , lines
, longtoduration (( lines
* SPAMINTERVAL
), 1 ));
272 /* Copied from microphone code */
276 s
= ( qab_spam
*) malloc ( sizeof ( qab_spam
));
277 s
-> message
= strdup ( buf
);
279 bot
-> lastspam
-> next
= s
;
283 if (( bot
-> spamtime
+ bot
-> spam_interval
) < time ( 0 )) {
284 sendmessagetochannel ( bot
-> np
, bot
-> public_chan
-> channel
, " %s " , buf
);
286 bot
-> spamtime
= time ( 0 );
291 s
= ( qab_spam
*) malloc ( sizeof ( qab_spam
));
292 s
-> message
= strdup ( buf
);
294 bot
-> nextspam
= bot
-> lastspam
= s
;
295 scheduleoneshot ( bot
-> spamtime
+ bot
-> spam_interval
, qabot_spam
, ( void *) bot
);
300 fclose ( bot
-> playfile
);
301 bot
-> playfile
= NULL
;
303 if ( bot
-> staff_chan
&& bot
-> staff_chan
-> channel
) {
304 sendmessagetochannel ( bot
-> np
, bot
-> staff_chan
-> channel
, "End of playback." );
305 sendmessagetochannel ( bot
-> np
, bot
-> staff_chan
-> channel
, " %l u lines ready to send to channel. This will take approx. %s to send." , lines
, longtoduration (( lines
* SPAMINTERVAL
), 1 ));
309 void qabot_spam ( void * arg
) {
310 qab_bot
* bot
= ( qab_bot
*) arg
;
317 sendmessagetochannel ( bot
-> np
, bot
-> public_chan
-> channel
, " %s " , bot
-> nextspam
-> message
);
322 bot
-> nextspam
= s
-> next
;
327 bot
-> spamtime
= time ( 0 );
330 scheduleoneshot ( bot
-> spamtime
+ bot
-> spam_interval
, qabot_spam
, ( void *) bot
);
333 if (! bot
-> micnumeric
)
334 qabot_spamstored (( void *) bot
);
338 void qabot_spamstored ( void * arg
) {
339 qab_bot
* bot
= ( qab_bot
*) arg
;
346 sendmessagetochannel ( bot
-> np
, bot
-> public_chan
-> channel
, " %s asked: %s " , bot
-> answers
-> question
-> nick
,
347 bot
-> answers
-> question
-> question
);
348 sendmessagetochannel ( bot
-> np
, bot
-> public_chan
-> channel
, " %s answered: %s " , bot
-> answers
-> nick
,
349 bot
-> answers
-> question
-> answer
);
353 bot
-> answers
= a
-> next
;
358 scheduleoneshot ( time ( 0 ) + bot
-> queued_question_interval
, qabot_spamstored
, ( void *) bot
);
361 void qabot_createbotfakeuser ( void * arg
) {
362 qab_bot
* bot
= ( qab_bot
*) arg
;
367 bot
-> np
= registerlocaluser ( bot
-> nick
, bot
-> user
, bot
-> host
, QABOT_NAME
, NULL
, QABOT_CHILD_UMODE
, & qabot_child_handler
);
369 bot
-> np
-> exts
[ qabot_nickext
] = ( void *) bot
;
371 if ( bot
-> public_chan
-> channel
) {
372 localjoinchannel ( bot
-> np
, bot
-> public_chan
-> channel
);
373 localgetops ( bot
-> np
, bot
-> public_chan
-> channel
);
376 localcreatechannel ( bot
-> np
, bot
-> public_chan
-> name
-> content
);
378 if ( bot
-> question_chan
-> channel
) {
379 localjoinchannel ( bot
-> np
, bot
-> question_chan
-> channel
);
380 localgetops ( bot
-> np
, bot
-> question_chan
-> channel
);
383 localcreatechannel ( bot
-> np
, bot
-> question_chan
-> name
-> content
);
385 if ( bot
-> staff_chan
-> channel
) {
386 localjoinchannel ( bot
-> np
, bot
-> staff_chan
-> channel
);
387 localgetops ( bot
-> np
, bot
-> staff_chan
-> channel
);
390 localcreatechannel ( bot
-> np
, bot
-> staff_chan
-> name
-> content
);
393 void qabot_timer ( void * arg
) {
394 qab_bot
* bot
= ( qab_bot
*) arg
;
399 if ( bot
-> micnumeric
&& ( bot
-> mic_timeout
> 0 ) && ( time ( NULL
) >= ( bot
-> lastmic
+ bot
-> mic_timeout
))) {
402 sendmessagetochannel ( bot
-> np
, bot
-> staff_chan
-> channel
, "Mic deactivated (idle timeout)." );
404 qabot_spamstored (( void *) bot
);
407 scheduleoneshot ( time ( NULL
) + 10 , & qabot_timer
, ( void *) bot
);