]>
jfr.im git - irc/quakenet/newserv.git/blob - qabot/qabot_chancommands.c
5 #include "../nick/nick.h"
6 #include "../localuser/localuserchannel.h"
7 #include "../core/hooks.h"
8 #include "../core/schedule.h"
9 #include "../lib/array.h"
10 #include "../lib/base64.h"
11 #include "../lib/irc_string.h"
12 #include "../lib/splitline.h"
16 int qabot_dochananswer ( void * np
, int cargc
, char ** cargv
) {
17 nick
* sender
= ( nick
*) np
;
18 qab_bot
* bot
= qabot_getcurrentbot ();
19 channel
* cp
= qabot_getcurrentchannel ();
25 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !answer <id> <answer>" );
29 id
= strtol ( cargv
[ 0 ], NULL
, 10 );
32 if (( id
< 1 ) || ( id
> bot
-> lastquestionID
)) {
33 sendnoticetouser ( bot
-> np
, sender
, "Invalid question ID %d ." , id
);
37 for ( q
= bot
-> questions
[ id
% QUESTIONHASHSIZE
]; q
; q
= q
-> next
)
42 sendnoticetouser ( bot
-> np
, sender
, "Can't find question %d ." , id
);
46 switch ( q
-> flags
& QAQ_QSTATE
) {
48 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been answered." , id
);
52 sendnoticetouser ( bot
-> np
, sender
, "Question %d has been marked as off-topic." , id
);
56 sendnoticetouser ( bot
-> np
, sender
, "Question %d has been marked as spam." , id
);
63 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_ANSWERED
;
64 q
-> answer
= strdup ( ch
);
68 if (! bot
-> nextspam
&& ! bot
-> micnumeric
) {
69 sendmessagetochannel ( bot
-> np
, bot
-> public_chan
-> channel
, " %s asked: %s " , q
-> nick
, q
-> question
);
70 sendmessagetochannel ( bot
-> np
, bot
-> public_chan
-> channel
, " %s answers: %s " , sender
-> nick
, ch
);
75 a
= ( qab_answer
*) malloc ( sizeof ( qab_answer
));
77 strncpy ( a
-> nick
, sender
-> nick
, NICKLEN
);
78 a
-> nick
[ NICKLEN
] = '\0' ;
79 a
-> next
= bot
-> answers
;
82 sendnoticetouser ( bot
-> np
, sender
, "Can't send your answer right now. Answer was stored and will be sent later on." );
86 sendnoticetouser ( bot
-> np
, sender
, "Answer to question %d has been sent and stored." , id
);
91 int qabot_dochanblock ( void * np
, int cargc
, char ** cargv
) {
92 nick
* sender
= ( nick
*) np
;
93 qab_bot
* bot
= qabot_getcurrentbot ();
94 channel
* cp
= qabot_getcurrentchannel ();
98 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !block [-q|-t] <account|mask>" );
103 if (! ircd_strncmp ( cargv
[ 0 ], "-q" , 2 )) {
105 char * target
= cargv
[ 1 ];
107 if (* target
== '#' ) {
110 if ( strchr ( target
, '*' ) || strchr ( target
, '?' )) {
111 sendnoticetouser ( bot
-> np
, sender
, "Wildcard account blocks are not supported." );
118 if (!( tnick
= getnickbynick ( target
))) {
119 sendnoticetouser ( bot
-> np
, sender
, "Couldn't find user %s ." , target
);
123 if (! IsAccount ( tnick
)) {
124 sendnoticetouser ( bot
-> np
, sender
, " %s is not authed." , tnick
-> nick
);
128 target
= tnick
-> authname
;
131 b
= ( qab_block
*) malloc ( sizeof ( qab_block
));
132 b
-> type
= QABBLOCK_ACCOUNT
;
133 b
-> created
= time ( 0 );
134 strncpy ( b
-> creator
, IsAccount ( sender
) ? sender
-> authname
: "UNKNOWN" , ACCOUNTLEN
);
135 b
-> creator
[ ACCOUNTLEN
] = '\0' ;
136 b
-> blockstr
= strdup ( target
);
138 b
-> next
= bot
-> blocks
;
140 bot
-> blocks
-> prev
= b
;
144 sendnoticetouser ( bot
-> np
, sender
, "Now blocking all messages from users with accountname %s ." , target
);
146 if ( bot
-> flags
& QAB_BLOCKMARK
) {
148 int i
, spamqcount
= 0 ;
151 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
152 for ( q
= bot
-> questions
[ i
]; q
; q
= q
-> next
) {
153 if (( q
-> flags
& QAQ_QSTATE
) != QAQ_NEW
)
156 if (!( qnick
= getnickbynumeric ( q
-> numeric
)))
159 if (! IsAccount ( qnick
))
162 if ( ircd_strcmp ( qnick
-> authname
, b
-> blockstr
))
165 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_SPAM
;
170 sendnoticetouser ( bot
-> np
, sender
, "Block caused %d message %s to be marked as spam." , spamqcount
, ( spamqcount
== 1 ) ? "" : "s" );
173 else if (! ircd_strncmp ( cargv
[ 0 ], "-t" , 2 )) {
175 char * mask
= cargv
[ 1 ];
177 b
= ( qab_block
*) malloc ( sizeof ( qab_block
));
178 b
-> type
= QABBLOCK_TEXT
;
179 b
-> created
= time ( 0 );
180 strncpy ( b
-> creator
, sender
-> authname
, ACCOUNTLEN
);
181 b
-> creator
[ ACCOUNTLEN
] = '\0' ;
182 b
-> blockstr
= strdup ( mask
);
184 b
-> next
= bot
-> blocks
;
186 bot
-> blocks
-> prev
= b
;
190 sendnoticetouser ( bot
-> np
, sender
, "Now blocking all questions which match %s ." , mask
);
192 if ( bot
-> flags
& QAB_BLOCKMARK
) {
194 int i
, spamqcount
= 0 ;
196 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
197 for ( q
= bot
-> questions
[ i
]; q
; q
= q
-> next
) {
198 if (( q
-> flags
& QAQ_QSTATE
) != QAQ_NEW
)
201 if ( match ( b
-> blockstr
, q
-> question
))
204 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_SPAM
;
209 sendnoticetouser ( bot
-> np
, sender
, "Block caused %d message %s to be marked as spam." , spamqcount
, ( spamqcount
== 1 ) ? "" : "s" );
213 sendnoticetouser ( bot
-> np
, sender
, "Invalid flag." );
219 char * mask
= cargv
[ 0 ];
221 if (! strchr ( mask
, '@' ) || ! strchr ( mask
, '!' )) {
222 sendnoticetouser ( bot
-> np
, sender
, " %s is not a valid hostmask." , mask
);
226 b
= ( qab_block
*) malloc ( sizeof ( qab_block
));
227 b
-> type
= QABBLOCK_HOST
;
228 b
-> created
= time ( 0 );
229 strncpy ( b
-> creator
, sender
-> authname
, ACCOUNTLEN
);
230 b
-> creator
[ ACCOUNTLEN
] = '\0' ;
231 b
-> blockstr
= strdup ( mask
);
233 b
-> next
= bot
-> blocks
;
235 bot
-> blocks
-> prev
= b
;
239 sendnoticetouser ( bot
-> np
, sender
, "Now blocking all messages from users with a hostmask matching %s ." , mask
);
241 if ( bot
-> flags
& QAB_BLOCKMARK
) {
243 int i
, spamqcount
= 0 ;
245 char hostbuf
[ NICKLEN
+ USERLEN
+ HOSTLEN
+ 3 ];
247 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
248 for ( q
= bot
-> questions
[ i
]; q
; q
= q
-> next
) {
249 if (( q
-> flags
& QAQ_QSTATE
) != QAQ_NEW
)
252 if (!( qnick
= getnickbynumeric ( q
-> numeric
)))
255 sprintf ( hostbuf
, " %s ! %s @ %s " , qnick
-> nick
, qnick
-> ident
, qnick
-> host
-> name
-> content
);
257 if ( match ( b
-> blockstr
, hostbuf
))
260 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_SPAM
;
265 sendnoticetouser ( bot
-> np
, sender
, "Block caused %d message %s to be marked as spam." , spamqcount
, ( spamqcount
== 1 ) ? "" : "s" );
272 int qabot_dochanclear ( void * np
, int cargc
, char ** cargv
) {
273 nick
* sender
= ( nick
*) np
;
274 qab_bot
* bot
= qabot_getcurrentbot ();
275 channel
* cp
= qabot_getcurrentchannel ();
281 if ( bot
-> recording_section
) {
282 sendmessagetochannel ( bot
-> np
, cp
, "Deactivate recorder before using clear." );
286 for ( s
= bot
-> nextspam
; s
; s
= ns
) {
292 bot
-> nextspam
= bot
-> lastspam
= 0 ;
294 sendmessagetochannel ( bot
-> np
, cp
, "Cleared message buffer." );
295 if ( bot
-> micnumeric
) {
297 sendmessagetochannel ( bot
-> np
, cp
, "Mic deactivated." );
303 int qabot_dochanclosechan ( void * np
, int cargc
, char ** cargv
) {
304 nick
* sender
= ( nick
*) np
;
305 qab_bot
* bot
= qabot_getcurrentbot ();
306 channel
* cp
= qabot_getcurrentchannel ();
309 localsetmodeinit (& changes
, bot
-> public_chan
-> channel
, bot
-> np
);
310 localdosetmode_simple (& changes
, CHANMODE_INVITEONLY
, 0 );
311 localsetmodeflush (& changes
, 1 );
312 sendnoticetouser ( bot
-> np
, sender
, "Public channel has been closed." );
317 int qabot_dochanconfig ( void * np
, int cargc
, char ** cargv
) {
318 nick
* sender
= ( nick
*) np
;
319 qab_bot
* bot
= qabot_getcurrentbot ();
320 channel
* cp
= qabot_getcurrentchannel ();
325 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !config <option> [<value>]" );
326 sendnoticetouser ( bot
-> np
, sender
, "Displays or sets configuration option. Valid options are:" );
327 sendnoticetouser ( bot
-> np
, sender
, "blockcontrol - Block questions containing control chars." );
328 sendnoticetouser ( bot
-> np
, sender
, "blockcolour - Block questions containing colour." );
329 sendnoticetouser ( bot
-> np
, sender
, "blockmark - Mark questions affected by blocks as spam." );
330 sendnoticetouser ( bot
-> np
, sender
, "authedonly - Accept questions from authed users only." );
331 sendnoticetouser ( bot
-> np
, sender
, "linebreak - Separate questions with line breaks." );
332 sendnoticetouser ( bot
-> np
, sender
, "flooddetect - Attempt to detect floodclone spam." );
333 sendnoticetouser ( bot
-> np
, sender
, "floodblock - Automatically block floodclone spam." );
334 sendnoticetouser ( bot
-> np
, sender
, "spamint - Text spam interval." );
335 sendnoticetouser ( bot
-> np
, sender
, "nickblockint - Time to wait before sending another question." );
336 sendnoticetouser ( bot
-> np
, sender
, "queuedqint - Queued answer spam interval." );
337 sendnoticetouser ( bot
-> np
, sender
, "mictimeout - Idle time before mic is automatically disabled." );
347 if (! ircd_strcmp ( opt
, "blockcontrol" )) {
349 if (! ircd_strcmp ( value
, "on" )) {
350 bot
-> flags
|= QAB_CONTROLCHAR
;
351 sendnoticetouser ( bot
-> np
, sender
, "Questions containing control characters will now be blocked." );
353 else if (! ircd_strcmp ( value
, "off" )) {
354 bot
-> flags
&= (~ QAB_CONTROLCHAR
);
355 sendnoticetouser ( bot
-> np
, sender
, "Questions containing control characters will no longer be blocked." );
358 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
361 sendnoticetouser ( bot
-> np
, sender
, "Control characters are currently %s blocked." , ( bot
-> flags
& QAB_CONTROLCHAR
) ? "being" : "not being" );
363 else if (! ircd_strcmp ( opt
, "blockcolour" )) {
365 if (! ircd_strcmp ( value
, "on" )) {
366 bot
-> flags
|= QAB_COLOUR
;
367 sendnoticetouser ( bot
-> np
, sender
, "Questions containing colour will now be blocked." );
369 else if (! ircd_strcmp ( value
, "off" )) {
370 bot
-> flags
&= (~ QAB_COLOUR
);
371 sendnoticetouser ( bot
-> np
, sender
, "Questions containing colour will no longer be blocked." );
374 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
377 sendnoticetouser ( bot
-> np
, sender
, "Colours are currently %s blocked." , ( bot
-> flags
& QAB_COLOUR
) ? "being" : "not being" );
379 else if (! ircd_strcmp ( opt
, "blockmark" )) {
381 if (! ircd_strcmp ( value
, "on" )) {
382 bot
-> flags
|= QAB_BLOCKMARK
;
383 sendnoticetouser ( bot
-> np
, sender
, "New blocks will automatically mark affected questions as spam." );
385 else if (! ircd_strcmp ( value
, "off" )) {
386 bot
-> flags
&= (~ QAB_BLOCKMARK
);
387 sendnoticetouser ( bot
-> np
, sender
, "New blocks will no longer automatically mark affected questions as spam." );
390 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
393 sendnoticetouser ( bot
-> np
, sender
, "Blocks are currently %s marking affected questions as spam." , ( bot
-> flags
& QAB_BLOCKMARK
) ? "" : "not " );
395 else if (! ircd_strcmp ( opt
, "authedonly" )) {
397 if (! ircd_strcmp ( value
, "on" )) {
398 bot
-> flags
|= QAB_AUTHEDONLY
;
399 sendnoticetouser ( bot
-> np
, sender
, "Questions from unauthed users will now be blocked." );
401 else if (! ircd_strcmp ( value
, "off" )) {
402 bot
-> flags
&= (~ QAB_AUTHEDONLY
);
403 sendnoticetouser ( bot
-> np
, sender
, "Questions from unauthed users will no longer be blocked." );
406 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
409 sendnoticetouser ( bot
-> np
, sender
, "Unauthed users may currently %s send questions." , ( bot
-> flags
& QAB_AUTHEDONLY
) ? "NOT " : "" );
411 else if (! ircd_strcmp ( opt
, "linebreak" )) {
413 if (! ircd_strcmp ( value
, "on" )) {
414 bot
-> flags
|= QAB_LINEBREAK
;
415 sendnoticetouser ( bot
-> np
, sender
, "Line breaks are now enabled." );
417 else if (! ircd_strcmp ( value
, "off" )) {
418 bot
-> flags
&= (~ QAB_LINEBREAK
);
419 sendnoticetouser ( bot
-> np
, sender
, "Line breaks are now disabled." );
422 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
425 sendnoticetouser ( bot
-> np
, sender
, "Line breaks are currently %s ." , ( bot
-> flags
& QAB_LINEBREAK
) ? "enabled" : "disabled" );
427 else if (! ircd_strcmp ( opt
, "flooddetect" )) {
429 if (! ircd_strcmp ( value
, "on" )) {
430 bot
-> flags
|= QAB_FLOODDETECT
;
431 sendnoticetouser ( bot
-> np
, sender
, "Flood detection is now enabled." );
433 else if (! ircd_strcmp ( value
, "off" )) {
434 bot
-> flags
&= (~ QAB_FLOODDETECT
);
435 sendnoticetouser ( bot
-> np
, sender
, "Flood detection is now disabled." );
438 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
441 sendnoticetouser ( bot
-> np
, sender
, "Flood detection is currently %s ." , ( bot
-> flags
& QAB_FLOODDETECT
) ? "enabled" : "disabled" );
443 else if (! ircd_strcmp ( opt
, "floodblock" )) {
445 if (! ircd_strcmp ( value
, "on" )) {
446 bot
-> flags
|= QAB_FLOODSTOP
;
447 sendnoticetouser ( bot
-> np
, sender
, "Flood blocking is now enabled." );
449 else if (! ircd_strcmp ( value
, "off" )) {
450 bot
-> flags
&= (~ QAB_FLOODSTOP
);
451 sendnoticetouser ( bot
-> np
, sender
, "Flood blocking is now disabled." );
454 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
457 sendnoticetouser ( bot
-> np
, sender
, "Flood blocking is currently %s ." , ( bot
-> flags
& QAB_FLOODSTOP
) ? "enabled" : "disabled" );
459 else if (! ircd_strcmp ( opt
, "mictimeout" )) {
461 int v
= ( int ) strtol ( value
, NULL
, 10 );
463 if (( v
< 0 ) || ( v
> 300 )) {
464 sendnoticetouser ( bot
-> np
, sender
, "Value must be between 0 (off) and 300." );
468 bot
-> mic_timeout
= v
;
469 sendnoticetouser ( bot
-> np
, sender
, "Value set." );
472 if ( bot
-> mic_timeout
)
473 sendnoticetouser ( bot
-> np
, sender
, "Mic timeout is currently %d second %s ." , bot
-> mic_timeout
, ( bot
-> mic_timeout
== 1 ) ? "" : "s" );
475 sendnoticetouser ( bot
-> np
, sender
, "Mic timeout is currently disabled." );
478 else if (! ircd_strcmp ( opt
, "spamint" )) {
480 int v
= ( int ) strtol ( value
, NULL
, 10 );
482 if (( v
< 1 ) || ( v
> 30 )) {
483 sendnoticetouser ( bot
-> np
, sender
, "Value must be between 1 and 30." );
487 bot
-> spam_interval
= v
;
488 sendnoticetouser ( bot
-> np
, sender
, "Value set." );
491 sendnoticetouser ( bot
-> np
, sender
, "Spam interval is currently %d second %s ." , bot
-> spam_interval
, ( bot
-> spam_interval
== 1 ) ? "" : "s" );
493 else if (! ircd_strcmp ( opt
, "nickblockint" )) {
495 int v
= ( int ) strtol ( value
, NULL
, 10 );
497 if (( v
< 1 ) || ( v
> 300 )) {
498 sendnoticetouser ( bot
-> np
, sender
, "Value must be between 1 and 300." );
503 sendnoticetouser ( bot
-> np
, sender
, "Value set." );
506 sendnoticetouser ( bot
-> np
, sender
, "Nick block interval is currently %d second %s ." , bot
-> ask_wait
, ( bot
-> ask_wait
== 1 ) ? "" : "s" );
508 else if (! ircd_strcmp ( opt
, "queuedqint" )) {
510 int v
= ( int ) strtol ( value
, NULL
, 10 );
512 if (( v
< 1 ) || ( v
> 20 )) {
513 sendnoticetouser ( bot
-> np
, sender
, "Value must be between 1 and 20." );
517 bot
-> queued_question_interval
= v
;
518 sendnoticetouser ( bot
-> np
, sender
, "Value set." );
521 sendnoticetouser ( bot
-> np
, sender
, "Queued question interval is currently %d second %s ." , bot
-> queued_question_interval
, ( bot
-> queued_question_interval
== 1 ) ? "" : "s" );
524 sendnoticetouser ( bot
-> np
, sender
, "Invalid configuration option." );
529 int qabot_dochanhelp ( void * np
, int cargc
, char ** cargv
) {
530 nick
* sender
= ( nick
*) np
;
531 qab_bot
* bot
= qabot_getcurrentbot ();
532 channel
* cp
= qabot_getcurrentchannel ();
541 if (! ircd_strcmp ( ch
, "mic" )) {
542 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !mic" );
543 sendnoticetouser ( bot
-> np
, sender
, "Turn the microphone on or off. When turned on, anything said by the microphone holder is relayed to %s ." , bot
-> public_chan
-> name
-> content
);
545 else if (! ircd_strcmp ( ch
, "clear" )) {
546 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !clear" );
547 sendnoticetouser ( bot
-> np
, sender
, "Clear currently queued text to relay, and turn off the microphone." );
549 else if (! ircd_strcmp ( ch
, "ping" )) {
550 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !ping" );
551 sendnoticetouser ( bot
-> np
, sender
, "Pings the bot." );
553 else if (! ircd_strcmp ( ch
, "config" )) {
554 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !config <option|help> [<value>]" );
555 sendnoticetouser ( bot
-> np
, sender
, "Display or set bot configuration options." );
557 else if (! ircd_strcmp ( ch
, "answer" )) {
558 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !answer <id> <answer>" );
559 sendnoticetouser ( bot
-> np
, sender
, "Answer a question." );
561 else if (! ircd_strcmp ( ch
, "block" )) {
562 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !block [<-q|-t>] <mask>" );
563 sendnoticetouser ( bot
-> np
, sender
, "Add a block, where:" );
564 sendnoticetouser ( bot
-> np
, sender
, "-q: blocks a Q account." );
565 sendnoticetouser ( bot
-> np
, sender
, "-t: blocks question text." );
566 sendnoticetouser ( bot
-> np
, sender
, "No flag results in a hostmask block." );
568 else if (! ircd_strcmp ( ch
, "listblocks" )) {
569 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !listblocks" );
570 sendnoticetouser ( bot
-> np
, sender
, "View the currently added blocks." );
572 else if (! ircd_strcmp ( ch
, "spam" )) {
573 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !spam <id>" );
574 sendnoticetouser ( bot
-> np
, sender
, "Mark a question as spam. This stops it being answered." );
576 else if (! ircd_strcmp ( ch
, "offtopic" )) {
577 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !offtopic <id>" );
578 sendnoticetouser ( bot
-> np
, sender
, "Mark a question as off-topic. This stops it being answered." );
580 else if (! ircd_strcmp ( ch
, "unblock" )) {
581 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !unblock [<-q|-t>] <mask>" );
582 sendnoticetouser ( bot
-> np
, sender
, "Removes a block. See \" !help block \" for a description of the flags." );
584 else if (! ircd_strcmp ( ch
, "reset" )) {
585 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !reset <all|questions|blocks|stats>" );
586 sendnoticetouser ( bot
-> np
, sender
, "Reset the questions, blocks or both; or the stats." );
588 else if (! ircd_strcmp ( ch
, "closechan" )) {
589 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !closechan" );
590 sendnoticetouser ( bot
-> np
, sender
, "Closes the public channel." );
592 else if (! ircd_strcmp ( ch
, "openchan" )) {
593 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !openchan" );
594 sendnoticetouser ( bot
-> np
, sender
, "Opens the public channel." );
596 else if (! ircd_strcmp ( ch
, "status" )) {
597 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !status" );
598 sendnoticetouser ( bot
-> np
, sender
, "Displays some status information and statistics." );
600 else if (! ircd_strcmp ( ch
, "help" )) {
601 sendnoticetouser ( bot
-> np
, sender
, "Syntax !help [<command>]" );
602 sendnoticetouser ( bot
-> np
, sender
, "List available commands or view help for a particular command." );
605 sendnoticetouser ( bot
-> np
, sender
, "No help available for ' %s '." , ch
);
609 sendnoticetouser ( bot
-> np
, sender
, "The following channel commands are recognised:" );
610 sendnoticetouser ( bot
-> np
, sender
, "!answer - Answer a question." );
611 sendnoticetouser ( bot
-> np
, sender
, "!block - Block a hostmask, account or string." );
612 sendnoticetouser ( bot
-> np
, sender
, "!clear - Clear currently queued text to spam." );
613 sendnoticetouser ( bot
-> np
, sender
, "!closechan - Close the public channel." );
614 sendnoticetouser ( bot
-> np
, sender
, "!config - Display or set bot configuration options." );
615 sendnoticetouser ( bot
-> np
, sender
, "!help - List commands or view the help for a command" );
616 sendnoticetouser ( bot
-> np
, sender
, "!listblocks - List currently added blocks." );
617 sendnoticetouser ( bot
-> np
, sender
, "!mic - Turn the microphone on or off." );
618 sendnoticetouser ( bot
-> np
, sender
, "!offtopic - Mark a question or questions as off-topic." );
619 sendnoticetouser ( bot
-> np
, sender
, "!openchan - Open the public channel." );
620 sendnoticetouser ( bot
-> np
, sender
, "!ping - Ping the bot." );
621 sendnoticetouser ( bot
-> np
, sender
, "!reset - Clear all blocks, questions or both." );
622 sendnoticetouser ( bot
-> np
, sender
, "!spam - Mark a question or questions as spam." );
623 sendnoticetouser ( bot
-> np
, sender
, "!status - Display some status statistics." );
624 sendnoticetouser ( bot
-> np
, sender
, "!unblock - Remove a block." );
625 sendnoticetouser ( bot
-> np
, sender
, "End of list." );
631 int qabot_dochanlistblocks ( void * np
, int cargc
, char ** cargv
) {
632 nick
* sender
= ( nick
*) np
;
633 qab_bot
* bot
= qabot_getcurrentbot ();
634 channel
* cp
= qabot_getcurrentchannel ();
637 if (!( b
= bot
-> blocks
)) {
638 sendnoticetouser ( bot
-> np
, sender
, "There are no blocks currently added." );
642 sendnoticetouser ( bot
-> np
, sender
, "Type: Hostmask/Account/Textmask:" );
644 for (; b
; b
= b
-> next
) {
645 if ( b
-> type
== QABBLOCK_ACCOUNT
)
646 sendnoticetouser ( bot
-> np
, sender
, "A %s " , b
-> blockstr
);
647 else if ( b
-> type
== QABBLOCK_HOST
)
648 sendnoticetouser ( bot
-> np
, sender
, "H %s " , b
-> blockstr
);
650 sendnoticetouser ( bot
-> np
, sender
, "T %s " , b
-> blockstr
);
653 sendnoticetouser ( bot
-> np
, sender
, "End of list." );
658 int qabot_dochanmic ( void * np
, int cargc
, char ** cargv
) {
659 nick
* sender
= ( nick
*) np
;
660 qab_bot
* bot
= qabot_getcurrentbot ();
661 channel
* cp
= qabot_getcurrentchannel ();
663 if ( bot
-> recording_section
)
664 sendmessagetochannel ( bot
-> np
, cp
, "Deactivate recorder before attempting to use mic." );
665 else if ( bot
-> micnumeric
) {
666 if ( bot
-> micnumeric
== sender
-> numeric
) {
668 sendmessagetochannel ( bot
-> np
, cp
, "Mic deactivated." );
670 qabot_spamstored (( void *) bot
);
673 bot
-> lastmic
= time ( NULL
);
674 bot
-> micnumeric
= sender
-> numeric
;
675 sendmessagetochannel ( bot
-> np
, cp
, " %s now has the mic. Anything said by %s will be relayed in %s ." ,
676 sender
-> nick
, sender
-> nick
, bot
-> public_chan
-> name
-> content
);
677 deleteschedule ( 0 , qabot_spamstored
, ( void *) bot
);
681 bot
-> lastmic
= time ( NULL
);
682 bot
-> micnumeric
= sender
-> numeric
;
683 sendmessagetochannel ( bot
-> np
, cp
, "Mic activated. Anything said by %s will be relayed in %s ." ,
684 sender
-> nick
, bot
-> public_chan
-> name
-> content
);
685 deleteschedule ( 0 , qabot_spamstored
, ( void *) bot
);
691 int qabot_dochanmoo ( void * np
, int cargc
, char ** cargv
) {
692 nick
* sender
= ( nick
*) np
;
693 qab_bot
* bot
= qabot_getcurrentbot ();
694 channel
* cp
= qabot_getcurrentchannel ();
696 int i
, moocount
= 5 + ( rand () % 40 );
699 for ( i
= 1 ; i
< moocount
; i
++)
700 moostr
[ i
] = (( rand () % 100 ) > 50 ) ? 'o' : '0' ;
703 sendmessagetochannel ( bot
-> np
, cp
, " %s " , moostr
);
708 int qabot_dochanofftopic ( void * np
, int cargc
, char ** cargv
) {
709 nick
* sender
= ( nick
*) np
;
710 qab_bot
* bot
= qabot_getcurrentbot ();
711 channel
* cp
= qabot_getcurrentchannel ();
717 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !spam <id> [<id> ... <id>]" );
721 for ( i
= 0 ; i
< cargc
; i
++) {
722 id
= strtol ( cargv
[ i
], NULL
, 10 );
724 if (( id
< 1 ) || ( id
> bot
-> lastquestionID
)) {
725 sendnoticetouser ( bot
-> np
, sender
, "Invalid question ID %d ." , id
);
729 for ( q
= bot
-> questions
[ id
% QUESTIONHASHSIZE
]; q
; q
= q
-> next
)
734 sendnoticetouser ( bot
-> np
, sender
, "Can't find question %d ." , id
);
738 switch ( q
-> flags
& QAQ_QSTATE
) {
740 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been answered." , id
);
744 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been marked as off-topic." , id
);
748 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been marked as spam." , id
);
755 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_OFFTOPIC
;
756 sendnoticetouser ( bot
-> np
, sender
, "Question %d has been marked as off-topic." , id
);
762 int qabot_dochanopenchan ( void * np
, int cargc
, char ** cargv
) {
763 nick
* sender
= ( nick
*) np
;
764 qab_bot
* bot
= qabot_getcurrentbot ();
765 channel
* cp
= qabot_getcurrentchannel ();
768 localsetmodeinit (& changes
, bot
-> public_chan
-> channel
, bot
-> np
);
769 localdosetmode_simple (& changes
, CHANMODE_MODERATE
| CHANMODE_DELJOINS
, CHANMODE_INVITEONLY
);
770 localsetmodeflush (& changes
, 1 );
771 sendnoticetouser ( bot
-> np
, sender
, "Public channel has been opened." );
776 int qabot_dochanping ( void * np
, int cargc
, char ** cargv
) {
777 nick
* sender
= ( nick
*) np
;
778 qab_bot
* bot
= qabot_getcurrentbot ();
779 channel
* cp
= qabot_getcurrentchannel ();
781 sendmessagetochannel ( bot
-> np
, cp
, "pong!" );
786 int qabot_dochanreset ( void * np
, int cargc
, char ** cargv
) {
787 nick
* sender
= ( nick
*) np
;
788 qab_bot
* bot
= qabot_getcurrentbot ();
789 channel
* cp
= qabot_getcurrentchannel ();
793 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !reset <blocks|questions|stats|all>" );
797 if (! ircd_strcmp ( cargv
[ 0 ], "blocks" ))
799 else if (! ircd_strcmp ( cargv
[ 0 ], "questions" ))
801 else if (! ircd_strcmp ( cargv
[ 0 ], "stats" ))
803 else if (! ircd_strcmp ( cargv
[ 0 ], "all" ))
806 sendnoticetouser ( bot
-> np
, sender
, "Unknown parameter: %s ." , cargv
[ 0 ]);
813 while ( bot
-> blocks
) {
815 bot
-> blocks
= bot
-> blocks
-> next
;
821 bot
-> block_count
= 0 ;
823 sendnoticetouser ( bot
-> np
, sender
, "Reset (blocks): Done." );
830 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
831 while ( bot
-> questions
[ i
]) {
832 q
= bot
-> questions
[ i
];
833 bot
-> questions
[ i
] = bot
-> questions
[ i
]-> next
;
842 bot
-> lastquestionID
= 0 ;
845 sendnoticetouser ( bot
-> np
, sender
, "Reset (questions): Done." );
851 sendnoticetouser ( bot
-> np
, sender
, "Reset (stats): Done." );
857 int qabot_dochanspam ( void * np
, int cargc
, char ** cargv
) {
858 nick
* sender
= ( nick
*) np
;
859 qab_bot
* bot
= qabot_getcurrentbot ();
860 channel
* cp
= qabot_getcurrentchannel ();
866 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !spam <id> [<id> ... <id>]" );
870 for ( i
= 0 ; i
< cargc
; i
++) {
871 id
= strtol ( cargv
[ i
], NULL
, 10 );
873 if (( id
< 1 ) || ( id
> bot
-> lastquestionID
)) {
874 sendnoticetouser ( bot
-> np
, sender
, "Invalid question ID %d ." , id
);
878 for ( q
= bot
-> questions
[ id
% QUESTIONHASHSIZE
]; q
; q
= q
-> next
)
883 sendnoticetouser ( bot
-> np
, sender
, "Can't find question %d ." , id
);
887 switch ( q
-> flags
& QAQ_QSTATE
) {
889 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been answered." , id
);
893 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been marked as off-topic." , id
);
897 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been marked as spam." , id
);
904 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_SPAM
;
905 sendnoticetouser ( bot
-> np
, sender
, "Question %d has been marked as spam." , id
);
911 int qabot_dochanstatus ( void * np
, int cargc
, char ** cargv
) {
912 nick
* sender
= ( nick
*) np
;
913 qab_bot
* bot
= qabot_getcurrentbot ();
914 channel
* cp
= qabot_getcurrentchannel ();
916 sendnoticetouser ( bot
-> np
, sender
, "Lines spammed: %d " , bot
-> spammed
);
917 sendnoticetouser ( bot
-> np
, sender
, "Questions asked: %d " , bot
-> lastquestionID
);
918 sendnoticetouser ( bot
-> np
, sender
, "Questions answered: %d " , bot
-> answered
);
919 sendnoticetouser ( bot
-> np
, sender
, "Blocks: %d " , bot
-> block_count
);
920 /*sendnoticetouser(bot->np, sender, "Question interval: %d seconds", bot->question_interval);*/
921 sendnoticetouser ( bot
-> np
, sender
, "Spam interval: %d seconds" , bot
-> spam_interval
);
922 sendnoticetouser ( bot
-> np
, sender
, "Nick block interval: %d seconds" , bot
-> ask_wait
);
923 sendnoticetouser ( bot
-> np
, sender
, "Queued question interval: %d seconds" , bot
-> queued_question_interval
);
924 sendnoticetouser ( bot
-> np
, sender
, "Block control chars: %s " , ( bot
-> flags
& QAB_CONTROLCHAR
) ? "Yes" : "No" );
925 sendnoticetouser ( bot
-> np
, sender
, "Block colour: %s " , ( bot
-> flags
& QAB_COLOUR
) ? "Yes" : "No" );
926 sendnoticetouser ( bot
-> np
, sender
, "Authed users only: %s " , ( bot
-> flags
& QAB_AUTHEDONLY
) ? "Yes" : "No" );
927 sendnoticetouser ( bot
-> np
, sender
, "Line break: %s " , ( bot
-> flags
& QAB_LINEBREAK
) ? "Yes" : "No" );
928 sendnoticetouser ( bot
-> np
, sender
, "Question flood detection: %s " , ( bot
-> flags
& QAB_FLOODDETECT
) ? "Yes" : "No" );
929 sendnoticetouser ( bot
-> np
, sender
, "Question flood blocking: %s " , ( bot
-> flags
& QAB_FLOODSTOP
) ? "Yes" : "No" );
930 sendnoticetouser ( bot
-> np
, sender
, "Blocks mark as spam: %s " , ( bot
-> flags
& QAB_BLOCKMARK
) ? "Yes" : "No" );
931 if ( bot
-> micnumeric
) {
932 nick
* mnick
= getnickbynumeric ( bot
-> micnumeric
);
934 sendnoticetouser ( bot
-> np
, np
, "Mic: Enabled ( %s )" , mnick
? mnick
-> nick
: "UNKNOWN" );
937 sendnoticetouser ( bot
-> np
, np
, "Mic: Disabled" );
938 sendnoticetouser ( bot
-> np
, sender
, "Mic timeout: %d " , bot
-> mic_timeout
);
939 /*sendnoticetouser(bot->np, sender, "");*/
944 int qabot_dochanunblock ( void * np
, int cargc
, char ** cargv
) {
945 nick
* sender
= ( nick
*) np
;
946 qab_bot
* bot
= qabot_getcurrentbot ();
947 channel
* cp
= qabot_getcurrentchannel ();
953 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !unblock [-q|-t] <account|mask>" );
958 if (! ircd_strncmp ( cargv
[ 0 ], "-q" , 2 )) {
959 type
= QABBLOCK_ACCOUNT
;
965 else if (! ircd_strncmp ( cargv
[ 0 ], "-t" , 2 )) {
966 type
= QABBLOCK_TEXT
;
970 sendnoticetouser ( bot
-> np
, sender
, "Invalid flag." );
975 type
= QABBLOCK_HOST
;
979 for ( b
= bot
-> blocks
; b
; b
= b
-> next
) {
983 if (! ircd_strcmp ( b
-> blockstr
, ch
)) {
985 b
-> next
-> prev
= b
-> prev
;
987 b
-> prev
-> next
= b
-> next
;
989 bot
-> blocks
= b
-> next
;
996 sendnoticetouser ( bot
-> np
, sender
, "Block removed." );
1001 sendnoticetouser ( bot
-> np
, sender
, "No such block." );
1006 int qabot_dochanlisttexts ( void * np
, int cargc
, char ** cargv
) {
1007 nick
* sender
= ( nick
*) np
;
1008 qab_bot
* bot
= qabot_getcurrentbot ();
1009 qab_text
* texts
= bot
-> texts
;
1012 sendnoticetouser ( bot
-> np
, sender
, "There are no texts added." );
1016 sendnoticetouser ( bot
-> np
, sender
, "Name: Sections:" );
1017 for (; texts
; texts
= texts
-> next
) {
1018 sendnoticetouser ( bot
-> np
, sender
, "%-15s %d " , texts
-> name
, texts
-> section_count
);
1021 sendnoticetouser ( bot
-> np
, sender
, "End of list." );
1026 int qabot_dochanshowsection ( void * np
, int cargc
, char ** cargv
) {
1027 nick
* sender
= ( nick
*) np
;
1028 qab_bot
* bot
= qabot_getcurrentbot ();
1029 qab_text
* texts
= bot
-> texts
;
1030 qab_textsection
* section
;
1034 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !showsection <text name> <section number>" );
1039 sendnoticetouser ( bot
-> np
, sender
, "There are no texts added." );
1043 id
= ( int ) strtol ( cargv
[ 1 ]);
1045 for (; texts
; texts
= texts
-> next
) {
1046 if (! ircd_strcmp ( texts
-> name
, cargv
[ 0 ])) {
1047 for ( section
= texts
-> sections
; section
&& ( count
<= section
-> section_count
); section
= section
-> next
) {
1048 if (++ count
== id
) {
1052 sendnoticetouser ( bot
-> np
, sender
, "Section %d (of text %s ) contents:" , count
, texts
-> name
);
1053 for ( lines
= section
-> lines
; lines
; lines
= lines
-> next
)
1054 sendnoticetouser ( bot
-> np
, sender
, "%-2d> %s " , ++ lineno
, lines
-> message
);
1055 sendnoticetouser ( bot
-> np
, sender
, "End of section." );
1060 sendnoticetouser ( bot
-> np
, sender
, "No such section." );
1065 sendnoticetouser ( bot
-> np
, sender
, "No such text." );
1070 int qabot_dochanaddtext ( void * np
, int cargc
, char ** cargv
) {
1071 nick
* sender
= ( nick
*) np
;
1072 qab_bot
* bot
= qabot_getcurrentbot ();
1073 qab_text
* texts
= bot
-> texts
;
1076 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !addtext <text name>" );
1080 for (; texts
; texts
= texts
-> next
) {
1081 if (! ircd_strcmp ( texts
-> name
, cargv
[ 0 ])) {
1082 sendnoticetouser ( bot
-> np
, sender
, "A text with this name already exists." );
1087 texts
= ( qab_text
*) malloc ( sizeof ( qab_text
));
1088 strncpy ( texts
-> name
, cargc
[ 0 ], NICKLEN
);
1089 texts
-> name
[ NICKLEN
] = '\0' ;
1090 texts
-> sections
= 0 ;
1091 texts
-> sections_tail
= 0 ;
1092 texts
-> section_count
= 0 ;
1093 texts
-> next
= bot
-> texts
;
1096 bot
-> texts
-> prev
= texts
;
1099 sendnoticetouser ( bot
-> np
, sender
, "Added text ' %s '." , texts
-> name
);
1104 int qabot_dochandeltext ( void * np
, int cargc
, char ** cargv
) {
1105 nick
* sender
= ( nick
*) np
;
1106 qab_bot
* bot
= qabot_getcurrentbot ();
1107 qab_text
* texts
= bot
-> texts
;
1110 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !deltext <text name>" );
1114 for (; texts
; texts
= texts
-> next
) {
1115 if (! ircd_strcmp ( texts
-> name
, cargv
[ 0 ])) {
1116 sendnoticetouser ( bot
-> np
, sender
, "Text ' %s ' deleted." , texts
-> name
);
1117 qabot_freetext ( bot
, texts
);
1122 sendnoticetouser ( bot
-> np
, sender
, "No such text." );
1127 int qabot_dochanaddsection ( void * np
, int cargc
, char ** cargv
) {
1128 nick
* sender
= ( nick
*) np
;
1129 qab_bot
* bot
= qabot_getcurrentbot ();
1130 qab_text
* texts
= bot
-> texts
;
1131 qab_textsection
* section
;
1134 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !addsection <text name> [<section number>]" );
1138 for (; texts
; texts
= texts
-> next
) {
1139 if (! ircd_strcmp ( texts
-> name
, cargv
[ 0 ])) {
1141 if ( cargc
== 1 || ! texts
-> sections_tail
) {
1142 section
= ( qab_textsection
*) malloc ( sizeof ( qab_textsection
));
1144 section
-> lines_tail
= 0 ;
1145 section
-> line_count
= 0 ;
1148 texts
-> sections
= section
;
1149 texts
-> sections_tail
= section
;
1150 texts
-> section_count
++;
1156 sendnoticetouser ( bot
-> np
, sender
, "Section %d added." , num
);
1161 sendnoticetouser ( bot
-> np
, sender
, "No such text." );
1166 int qabot_dochandelsection ( void * np
, int cargc
, char ** cargv
) {
1167 nick
* sender
= ( nick
*) np
;
1168 qab_bot
* bot
= qabot_getcurrentbot ();
1169 qab_text
* texts
= bot
-> texts
;
1170 qab_textsection
* section
;
1173 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !delsection <text name> <section number>" );
1177 for (; texts
; texts
= texts
-> next
) {
1178 if (! ircd_strcmp ( texts
-> name
, cargv
[ 0 ])) {
1179 for ( section
= texts
-> sections
; section
&& ( count
<= section
-> section_count
); section
= section
-> next
) {
1180 if (++ count
== id
) {
1181 qabot_freesection ( texts
, section
);
1182 sendnoticetouser ( bot
-> np
, sender
, "Section deleted." );
1186 sendnoticetouser ( bot
-> np
, sender
, "No such section." );
1191 sendnoticetouser ( bot
-> np
, sender
, "No such text." );
1196 int qabot_dochanrecord ( void * np
, int cargc
, char ** cargv
) {
1197 nick
* sender
= ( nick
*) np
;
1198 qab_bot
* bot
= qabot_getcurrentbot ();
1199 channel
* cp
= qabot_getcurrentchannel ();
1201 if ( bot
-> recording_section
) {
1202 if ( bot
-> micnumeric
== sender
-> numeric
) {
1203 bot
-> micnumeric
= 0 ;
1204 bot
-> recording_section
= 0 ;
1205 sendmessagetochannel ( bot
-> np
, cp
, "Recorder deactivated." );
1208 sendmessagetochannel ( bot
-> np
, cp
, "The recorder is already in use." );
1211 else if ( bot
-> micnumeric
)
1212 sendmessagetochannel ( bot
-> np
, cp
, "Deactivate mic before attempting to use recorder." );
1213 else if ( cargc
>= 2 ) {
1214 qab_text
* texts
= bot
-> texts
;
1215 qab_textsection
* section
;
1216 int id
= ( int ) strtol ( cargv
[ 1 ]);
1218 for (; texts
; texts
= texts
-> next
) {
1219 if (! ircd_strcmp ( texts
-> name
, cargv
[ 0 ])) {
1220 for ( section
= texts
-> sections
; section
&& ( count
<= section
-> section_count
); section
= section
-> next
) {
1221 if (++ count
== id
) {
1222 bot
-> lastmic
= time ( NULL
);
1223 bot
-> micnumeric
= sender
-> numeric
;
1224 bot
-> recording_section
= count
;
1225 sendmessagetochannel ( bot
-> np
, cp
, "Recorder activated. Anything said by %s will be relayed in %s ." ,
1226 sender
-> nick
, bot
-> public_chan
-> name
-> content
);
1227 deleteschedule ( 0 , qabot_spamstored
, ( void *) bot
);
1231 sendnoticetouser ( bot
-> np
, sender
, "No such section." );
1236 sendnoticetouser ( bot
-> np
, sender
, "No such text." );
1240 sendmessagetochannel ( bot
-> np
, cp
, "syntax: !record [<text name> <section number>]" );