]>
jfr.im git - irc/quakenet/newserv.git/blob - qabot/qabot_chancommands.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 int qabot_dochananswer ( void * np
, int cargc
, char ** cargv
) {
16 nick
* sender
= ( nick
*) np
;
17 qab_bot
* bot
= qabot_getcurrentbot ();
23 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !answer <id> <answer>" );
27 id
= strtol ( cargv
[ 0 ], NULL
, 10 );
30 if (( id
< 1 ) || ( id
> bot
-> lastquestionID
)) {
31 sendnoticetouser ( bot
-> np
, sender
, "Invalid question ID %d ." , id
);
35 for ( q
= bot
-> questions
[ id
% QUESTIONHASHSIZE
]; q
; q
= q
-> next
)
40 sendnoticetouser ( bot
-> np
, sender
, "Can't find question %d ." , id
);
44 switch ( q
-> flags
& QAQ_QSTATE
) {
46 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been answered." , id
);
50 sendnoticetouser ( bot
-> np
, sender
, "Question %d has been marked as off-topic." , id
);
54 sendnoticetouser ( bot
-> np
, sender
, "Question %d has been marked as spam." , id
);
61 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_ANSWERED
;
62 q
-> answer
= strdup ( ch
);
66 if (! bot
-> nextspam
&& ! bot
-> micnumeric
) {
67 sendmessagetochannel ( bot
-> np
, bot
-> public_chan
-> channel
, " %s asked: %s " , q
-> nick
, q
-> question
);
68 sendmessagetochannel ( bot
-> np
, bot
-> public_chan
-> channel
, " %s answers: %s " , sender
-> nick
, ch
);
73 a
= ( qab_answer
*) malloc ( sizeof ( qab_answer
));
75 strncpy ( a
-> nick
, sender
-> nick
, NICKLEN
);
76 a
-> nick
[ NICKLEN
] = '\0' ;
77 a
-> next
= bot
-> answers
;
80 sendnoticetouser ( bot
-> np
, sender
, "Can't send your answer right now. Answer was stored and will be sent later on." );
84 sendnoticetouser ( bot
-> np
, sender
, "Answer to question %d has been sent and stored." , id
);
89 int qabot_dochanblock ( void * np
, int cargc
, char ** cargv
) {
90 nick
* sender
= ( nick
*) np
;
91 qab_bot
* bot
= qabot_getcurrentbot ();
95 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !block [-q|-t] <account|mask>" );
100 if (! ircd_strncmp ( cargv
[ 0 ], "-q" , 2 )) {
102 char * target
= cargv
[ 1 ];
104 if (* target
== '#' ) {
107 if ( strchr ( target
, '*' ) || strchr ( target
, '?' )) {
108 sendnoticetouser ( bot
-> np
, sender
, "Wildcard account blocks are not supported." );
115 if (!( tnick
= getnickbynick ( target
))) {
116 sendnoticetouser ( bot
-> np
, sender
, "Couldn't find user %s ." , target
);
120 if (! IsAccount ( tnick
)) {
121 sendnoticetouser ( bot
-> np
, sender
, " %s is not authed." , tnick
-> nick
);
125 target
= tnick
-> authname
;
128 b
= ( qab_block
*) malloc ( sizeof ( qab_block
));
129 b
-> type
= QABBLOCK_ACCOUNT
;
130 b
-> created
= time ( 0 );
131 strncpy ( b
-> creator
, IsAccount ( sender
) ? sender
-> authname
: "UNKNOWN" , ACCOUNTLEN
);
132 b
-> creator
[ ACCOUNTLEN
] = '\0' ;
133 b
-> blockstr
= strdup ( target
);
135 b
-> next
= bot
-> blocks
;
137 bot
-> blocks
-> prev
= b
;
141 sendnoticetouser ( bot
-> np
, sender
, "Now blocking all messages from users with accountname %s ." , target
);
143 if ( bot
-> flags
& QAB_BLOCKMARK
) {
145 int i
, spamqcount
= 0 ;
148 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
149 for ( q
= bot
-> questions
[ i
]; q
; q
= q
-> next
) {
150 if (( q
-> flags
& QAQ_QSTATE
) != QAQ_NEW
)
153 if (!( qnick
= getnickbynumeric ( q
-> numeric
)))
156 if (! IsAccount ( qnick
))
159 if ( ircd_strcmp ( qnick
-> authname
, b
-> blockstr
))
162 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_SPAM
;
167 sendnoticetouser ( bot
-> np
, sender
, "Block caused %d message %s to be marked as spam." , spamqcount
, ( spamqcount
== 1 ) ? "" : "s" );
170 else if (! ircd_strncmp ( cargv
[ 0 ], "-t" , 2 )) {
172 char * mask
= cargv
[ 1 ];
174 b
= ( qab_block
*) malloc ( sizeof ( qab_block
));
175 b
-> type
= QABBLOCK_TEXT
;
176 b
-> created
= time ( 0 );
177 strncpy ( b
-> creator
, sender
-> authname
, ACCOUNTLEN
);
178 b
-> creator
[ ACCOUNTLEN
] = '\0' ;
179 b
-> blockstr
= strdup ( mask
);
181 b
-> next
= bot
-> blocks
;
183 bot
-> blocks
-> prev
= b
;
187 sendnoticetouser ( bot
-> np
, sender
, "Now blocking all questions which match %s ." , mask
);
189 if ( bot
-> flags
& QAB_BLOCKMARK
) {
191 int i
, spamqcount
= 0 ;
193 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
194 for ( q
= bot
-> questions
[ i
]; q
; q
= q
-> next
) {
195 if (( q
-> flags
& QAQ_QSTATE
) != QAQ_NEW
)
198 if ( match ( b
-> blockstr
, q
-> question
))
201 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_SPAM
;
206 sendnoticetouser ( bot
-> np
, sender
, "Block caused %d message %s to be marked as spam." , spamqcount
, ( spamqcount
== 1 ) ? "" : "s" );
210 sendnoticetouser ( bot
-> np
, sender
, "Invalid flag." );
216 char * mask
= cargv
[ 0 ];
218 if (! strchr ( mask
, '@' ) || ! strchr ( mask
, '!' )) {
219 sendnoticetouser ( bot
-> np
, sender
, " %s is not a valid hostmask." , mask
);
223 b
= ( qab_block
*) malloc ( sizeof ( qab_block
));
224 b
-> type
= QABBLOCK_HOST
;
225 b
-> created
= time ( 0 );
226 strncpy ( b
-> creator
, sender
-> authname
, ACCOUNTLEN
);
227 b
-> creator
[ ACCOUNTLEN
] = '\0' ;
228 b
-> blockstr
= strdup ( mask
);
230 b
-> next
= bot
-> blocks
;
232 bot
-> blocks
-> prev
= b
;
236 sendnoticetouser ( bot
-> np
, sender
, "Now blocking all messages from users with a hostmask matching %s ." , mask
);
238 if ( bot
-> flags
& QAB_BLOCKMARK
) {
240 int i
, spamqcount
= 0 ;
242 char hostbuf
[ NICKLEN
+ USERLEN
+ HOSTLEN
+ 3 ];
244 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
245 for ( q
= bot
-> questions
[ i
]; q
; q
= q
-> next
) {
246 if (( q
-> flags
& QAQ_QSTATE
) != QAQ_NEW
)
249 if (!( qnick
= getnickbynumeric ( q
-> numeric
)))
252 sprintf ( hostbuf
, " %s ! %s @ %s " , qnick
-> nick
, qnick
-> ident
, qnick
-> host
-> name
-> content
);
254 if ( match ( b
-> blockstr
, hostbuf
))
257 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_SPAM
;
262 sendnoticetouser ( bot
-> np
, sender
, "Block caused %d message %s to be marked as spam." , spamqcount
, ( spamqcount
== 1 ) ? "" : "s" );
269 int qabot_dochanclear ( void * np
, int cargc
, char ** cargv
) {
270 qab_bot
* bot
= qabot_getcurrentbot ();
271 channel
* cp
= qabot_getcurrentchannel ();
275 for ( s
= bot
-> nextspam
; s
; s
= ns
) {
281 bot
-> nextspam
= bot
-> lastspam
= 0 ;
283 sendmessagetochannel ( bot
-> np
, cp
, "Cleared message buffer." );
284 if ( bot
-> micnumeric
) {
286 sendmessagetochannel ( bot
-> np
, cp
, "Mic deactivated." );
292 int qabot_dochanclosechan ( void * np
, int cargc
, char ** cargv
) {
293 nick
* sender
= ( nick
*) np
;
294 qab_bot
* bot
= qabot_getcurrentbot ();
297 localsetmodeinit (& changes
, bot
-> public_chan
-> channel
, bot
-> np
);
298 localdosetmode_simple (& changes
, CHANMODE_INVITEONLY
, 0 );
299 localsetmodeflush (& changes
, 1 );
300 sendnoticetouser ( bot
-> np
, sender
, "Public channel has been closed." );
305 int qabot_dochanconfig ( void * np
, int cargc
, char ** cargv
) {
306 nick
* sender
= ( nick
*) np
;
307 qab_bot
* bot
= qabot_getcurrentbot ();
312 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !config <option> [<value>]" );
313 sendnoticetouser ( bot
-> np
, sender
, "Displays or sets configuration option. Valid options are:" );
314 sendnoticetouser ( bot
-> np
, sender
, "blockcontrol - Block questions containing control chars." );
315 sendnoticetouser ( bot
-> np
, sender
, "blockcolour - Block questions containing colour." );
316 sendnoticetouser ( bot
-> np
, sender
, "blockmark - Mark questions affected by blocks as spam." );
317 sendnoticetouser ( bot
-> np
, sender
, "authedonly - Accept questions from authed users only." );
318 sendnoticetouser ( bot
-> np
, sender
, "linebreak - Separate questions with line breaks." );
319 sendnoticetouser ( bot
-> np
, sender
, "flooddetect - Attempt to detect floodclone spam." );
320 sendnoticetouser ( bot
-> np
, sender
, "floodblock - Automatically block floodclone spam." );
321 sendnoticetouser ( bot
-> np
, sender
, "spamint - Text spam interval." );
322 sendnoticetouser ( bot
-> np
, sender
, "nickblockint - Time to wait before sending another question." );
323 sendnoticetouser ( bot
-> np
, sender
, "queuedqint - Queued answer spam interval." );
324 sendnoticetouser ( bot
-> np
, sender
, "mictimeout - Idle time before mic is automatically disabled." );
334 if (! ircd_strcmp ( opt
, "blockcontrol" )) {
336 if (! ircd_strcmp ( value
, "on" )) {
337 bot
-> flags
|= QAB_CONTROLCHAR
;
338 sendnoticetouser ( bot
-> np
, sender
, "Questions containing control characters will now be blocked." );
340 else if (! ircd_strcmp ( value
, "off" )) {
341 bot
-> flags
&= (~ QAB_CONTROLCHAR
);
342 sendnoticetouser ( bot
-> np
, sender
, "Questions containing control characters will no longer be blocked." );
345 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
348 sendnoticetouser ( bot
-> np
, sender
, "Control characters are currently %s blocked." , ( bot
-> flags
& QAB_CONTROLCHAR
) ? "being" : "not being" );
350 else if (! ircd_strcmp ( opt
, "blockcolour" )) {
352 if (! ircd_strcmp ( value
, "on" )) {
353 bot
-> flags
|= QAB_COLOUR
;
354 sendnoticetouser ( bot
-> np
, sender
, "Questions containing colour will now be blocked." );
356 else if (! ircd_strcmp ( value
, "off" )) {
357 bot
-> flags
&= (~ QAB_COLOUR
);
358 sendnoticetouser ( bot
-> np
, sender
, "Questions containing colour will no longer be blocked." );
361 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
364 sendnoticetouser ( bot
-> np
, sender
, "Colours are currently %s blocked." , ( bot
-> flags
& QAB_COLOUR
) ? "being" : "not being" );
366 else if (! ircd_strcmp ( opt
, "blockmark" )) {
368 if (! ircd_strcmp ( value
, "on" )) {
369 bot
-> flags
|= QAB_BLOCKMARK
;
370 sendnoticetouser ( bot
-> np
, sender
, "New blocks will automatically mark affected questions as spam." );
372 else if (! ircd_strcmp ( value
, "off" )) {
373 bot
-> flags
&= (~ QAB_BLOCKMARK
);
374 sendnoticetouser ( bot
-> np
, sender
, "New blocks will no longer automatically mark affected questions as spam." );
377 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
380 sendnoticetouser ( bot
-> np
, sender
, "Blocks are currently %s marking affected questions as spam." , ( bot
-> flags
& QAB_BLOCKMARK
) ? "" : "not " );
382 else if (! ircd_strcmp ( opt
, "authedonly" )) {
384 if (! ircd_strcmp ( value
, "on" )) {
385 bot
-> flags
|= QAB_AUTHEDONLY
;
386 sendnoticetouser ( bot
-> np
, sender
, "Questions from unauthed users will now be blocked." );
388 else if (! ircd_strcmp ( value
, "off" )) {
389 bot
-> flags
&= (~ QAB_AUTHEDONLY
);
390 sendnoticetouser ( bot
-> np
, sender
, "Questions from unauthed users will no longer be blocked." );
393 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
396 sendnoticetouser ( bot
-> np
, sender
, "Unauthed users may currently %s send questions." , ( bot
-> flags
& QAB_AUTHEDONLY
) ? "NOT " : "" );
398 else if (! ircd_strcmp ( opt
, "linebreak" )) {
400 if (! ircd_strcmp ( value
, "on" )) {
401 bot
-> flags
|= QAB_LINEBREAK
;
402 sendnoticetouser ( bot
-> np
, sender
, "Line breaks are now enabled." );
404 else if (! ircd_strcmp ( value
, "off" )) {
405 bot
-> flags
&= (~ QAB_LINEBREAK
);
406 sendnoticetouser ( bot
-> np
, sender
, "Line breaks are now disabled." );
409 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
412 sendnoticetouser ( bot
-> np
, sender
, "Line breaks are currently %s ." , ( bot
-> flags
& QAB_LINEBREAK
) ? "enabled" : "disabled" );
414 else if (! ircd_strcmp ( opt
, "flooddetect" )) {
416 if (! ircd_strcmp ( value
, "on" )) {
417 bot
-> flags
|= QAB_FLOODDETECT
;
418 sendnoticetouser ( bot
-> np
, sender
, "Flood detection is now enabled." );
420 else if (! ircd_strcmp ( value
, "off" )) {
421 bot
-> flags
&= (~ QAB_FLOODDETECT
);
422 sendnoticetouser ( bot
-> np
, sender
, "Flood detection is now disabled." );
425 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
428 sendnoticetouser ( bot
-> np
, sender
, "Flood detection is currently %s ." , ( bot
-> flags
& QAB_FLOODDETECT
) ? "enabled" : "disabled" );
430 else if (! ircd_strcmp ( opt
, "floodblock" )) {
432 if (! ircd_strcmp ( value
, "on" )) {
433 bot
-> flags
|= QAB_FLOODSTOP
;
434 sendnoticetouser ( bot
-> np
, sender
, "Flood blocking is now enabled." );
436 else if (! ircd_strcmp ( value
, "off" )) {
437 bot
-> flags
&= (~ QAB_FLOODSTOP
);
438 sendnoticetouser ( bot
-> np
, sender
, "Flood blocking is now disabled." );
441 sendnoticetouser ( bot
-> np
, sender
, "Invalid option. Valid options are 'on' or 'off'." );
444 sendnoticetouser ( bot
-> np
, sender
, "Flood blocking is currently %s ." , ( bot
-> flags
& QAB_FLOODSTOP
) ? "enabled" : "disabled" );
446 else if (! ircd_strcmp ( opt
, "mictimeout" )) {
448 int v
= ( int ) strtol ( value
, NULL
, 10 );
450 if (( v
< 0 ) || ( v
> 300 )) {
451 sendnoticetouser ( bot
-> np
, sender
, "Value must be between 0 (off) and 300." );
455 bot
-> mic_timeout
= v
;
456 sendnoticetouser ( bot
-> np
, sender
, "Value set." );
459 if ( bot
-> mic_timeout
)
460 sendnoticetouser ( bot
-> np
, sender
, "Mic timeout is currently %d second %s ." , bot
-> mic_timeout
, ( bot
-> mic_timeout
== 1 ) ? "" : "s" );
462 sendnoticetouser ( bot
-> np
, sender
, "Mic timeout is currently disabled." );
465 else if (! ircd_strcmp ( opt
, "spamint" )) {
467 int v
= ( int ) strtol ( value
, NULL
, 10 );
469 if (( v
< 1 ) || ( v
> 30 )) {
470 sendnoticetouser ( bot
-> np
, sender
, "Value must be between 1 and 30." );
474 bot
-> spam_interval
= v
;
475 sendnoticetouser ( bot
-> np
, sender
, "Value set." );
478 sendnoticetouser ( bot
-> np
, sender
, "Spam interval is currently %d second %s ." , bot
-> spam_interval
, ( bot
-> spam_interval
== 1 ) ? "" : "s" );
480 else if (! ircd_strcmp ( opt
, "nickblockint" )) {
482 int v
= ( int ) strtol ( value
, NULL
, 10 );
484 if (( v
< 1 ) || ( v
> 300 )) {
485 sendnoticetouser ( bot
-> np
, sender
, "Value must be between 1 and 300." );
490 sendnoticetouser ( bot
-> np
, sender
, "Value set." );
493 sendnoticetouser ( bot
-> np
, sender
, "Nick block interval is currently %d second %s ." , bot
-> ask_wait
, ( bot
-> ask_wait
== 1 ) ? "" : "s" );
495 else if (! ircd_strcmp ( opt
, "queuedqint" )) {
497 int v
= ( int ) strtol ( value
, NULL
, 10 );
499 if (( v
< 1 ) || ( v
> 20 )) {
500 sendnoticetouser ( bot
-> np
, sender
, "Value must be between 1 and 20." );
504 bot
-> queued_question_interval
= v
;
505 sendnoticetouser ( bot
-> np
, sender
, "Value set." );
508 sendnoticetouser ( bot
-> np
, sender
, "Queued question interval is currently %d second %s ." , bot
-> queued_question_interval
, ( bot
-> queued_question_interval
== 1 ) ? "" : "s" );
511 sendnoticetouser ( bot
-> np
, sender
, "Invalid configuration option." );
516 int qabot_dochanhelp ( void * np
, int cargc
, char ** cargv
) {
517 nick
* sender
= ( nick
*) np
;
518 qab_bot
* bot
= qabot_getcurrentbot ();
527 if (! ircd_strcmp ( ch
, "mic" )) {
528 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !mic" );
529 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
);
531 else if (! ircd_strcmp ( ch
, "clear" )) {
532 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !clear" );
533 sendnoticetouser ( bot
-> np
, sender
, "Clear currently queued text to relay, and turn off the microphone." );
535 else if (! ircd_strcmp ( ch
, "ping" )) {
536 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !ping" );
537 sendnoticetouser ( bot
-> np
, sender
, "Pings the bot." );
539 else if (! ircd_strcmp ( ch
, "config" )) {
540 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !config <option|help> [<value>]" );
541 sendnoticetouser ( bot
-> np
, sender
, "Display or set bot configuration options." );
543 else if (! ircd_strcmp ( ch
, "answer" )) {
544 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !answer <id> <answer>" );
545 sendnoticetouser ( bot
-> np
, sender
, "Answer a question." );
547 else if (! ircd_strcmp ( ch
, "block" )) {
548 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !block [<-q|-t>] <mask>" );
549 sendnoticetouser ( bot
-> np
, sender
, "Add a block, where:" );
550 sendnoticetouser ( bot
-> np
, sender
, "-q: blocks a Q account." );
551 sendnoticetouser ( bot
-> np
, sender
, "-t: blocks question text." );
552 sendnoticetouser ( bot
-> np
, sender
, "No flag results in a hostmask block." );
554 else if (! ircd_strcmp ( ch
, "listblocks" )) {
555 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !listblocks" );
556 sendnoticetouser ( bot
-> np
, sender
, "View the currently added blocks." );
558 else if (! ircd_strcmp ( ch
, "spam" )) {
559 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !spam <id>" );
560 sendnoticetouser ( bot
-> np
, sender
, "Mark a question as spam. This stops it being answered." );
562 else if (! ircd_strcmp ( ch
, "offtopic" )) {
563 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !offtopic <id>" );
564 sendnoticetouser ( bot
-> np
, sender
, "Mark a question as off-topic. This stops it being answered." );
566 else if (! ircd_strcmp ( ch
, "unblock" )) {
567 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !unblock [<-q|-t>] <mask>" );
568 sendnoticetouser ( bot
-> np
, sender
, "Removes a block. See \" !help block \" for a description of the flags." );
570 else if (! ircd_strcmp ( ch
, "reset" )) {
571 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !reset <all|questions|blocks|stats>" );
572 sendnoticetouser ( bot
-> np
, sender
, "Reset the questions, blocks or both; or the stats." );
574 else if (! ircd_strcmp ( ch
, "closechan" )) {
575 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !closechan" );
576 sendnoticetouser ( bot
-> np
, sender
, "Closes the public channel." );
578 else if (! ircd_strcmp ( ch
, "openchan" )) {
579 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !openchan" );
580 sendnoticetouser ( bot
-> np
, sender
, "Opens the public channel." );
582 else if (! ircd_strcmp ( ch
, "status" )) {
583 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !status" );
584 sendnoticetouser ( bot
-> np
, sender
, "Displays some status information and statistics." );
586 else if (! ircd_strcmp ( ch
, "help" )) {
587 sendnoticetouser ( bot
-> np
, sender
, "Syntax !help [<command>]" );
588 sendnoticetouser ( bot
-> np
, sender
, "List available commands or view help for a particular command." );
591 sendnoticetouser ( bot
-> np
, sender
, "No help available for ' %s '." , ch
);
595 sendnoticetouser ( bot
-> np
, sender
, "The following channel commands are recognised:" );
596 sendnoticetouser ( bot
-> np
, sender
, "!answer - Answer a question." );
597 sendnoticetouser ( bot
-> np
, sender
, "!block - Block a hostmask, account or string." );
598 sendnoticetouser ( bot
-> np
, sender
, "!clear - Clear currently queued text to spam." );
599 sendnoticetouser ( bot
-> np
, sender
, "!closechan - Close the public channel." );
600 sendnoticetouser ( bot
-> np
, sender
, "!config - Display or set bot configuration options." );
601 sendnoticetouser ( bot
-> np
, sender
, "!help - List commands or view the help for a command" );
602 sendnoticetouser ( bot
-> np
, sender
, "!listblocks - List currently added blocks." );
603 sendnoticetouser ( bot
-> np
, sender
, "!mic - Turn the microphone on or off." );
604 sendnoticetouser ( bot
-> np
, sender
, "!offtopic - Mark a question or questions as off-topic." );
605 sendnoticetouser ( bot
-> np
, sender
, "!openchan - Open the public channel." );
606 sendnoticetouser ( bot
-> np
, sender
, "!ping - Ping the bot." );
607 sendnoticetouser ( bot
-> np
, sender
, "!reset - Clear all blocks, questions or both." );
608 sendnoticetouser ( bot
-> np
, sender
, "!spam - Mark a question or questions as spam." );
609 sendnoticetouser ( bot
-> np
, sender
, "!status - Display some status statistics." );
610 sendnoticetouser ( bot
-> np
, sender
, "!unblock - Remove a block." );
611 sendnoticetouser ( bot
-> np
, sender
, "End of list." );
617 int qabot_dochanlistblocks ( void * np
, int cargc
, char ** cargv
) {
618 nick
* sender
= ( nick
*) np
;
619 qab_bot
* bot
= qabot_getcurrentbot ();
622 if (!( b
= bot
-> blocks
)) {
623 sendnoticetouser ( bot
-> np
, sender
, "There are no blocks currently added." );
627 sendnoticetouser ( bot
-> np
, sender
, "Type: Hostmask/Account/Textmask:" );
629 for (; b
; b
= b
-> next
) {
630 if ( b
-> type
== QABBLOCK_ACCOUNT
)
631 sendnoticetouser ( bot
-> np
, sender
, "A %s " , b
-> blockstr
);
632 else if ( b
-> type
== QABBLOCK_HOST
)
633 sendnoticetouser ( bot
-> np
, sender
, "H %s " , b
-> blockstr
);
635 sendnoticetouser ( bot
-> np
, sender
, "T %s " , b
-> blockstr
);
638 sendnoticetouser ( bot
-> np
, sender
, "End of list." );
643 int qabot_dochanmic ( void * np
, int cargc
, char ** cargv
) {
644 nick
* sender
= ( nick
*) np
;
645 qab_bot
* bot
= qabot_getcurrentbot ();
646 channel
* cp
= qabot_getcurrentchannel ();
648 if ( bot
-> micnumeric
) {
649 if ( bot
-> micnumeric
== sender
-> numeric
) {
651 sendmessagetochannel ( bot
-> np
, cp
, "Mic deactivated." );
653 qabot_spamstored (( void *) bot
);
656 bot
-> lastmic
= time ( NULL
);
657 bot
-> micnumeric
= sender
-> numeric
;
658 sendmessagetochannel ( bot
-> np
, cp
, " %s now has the mic. Anything said by %s will be relayed in %s ." ,
659 sender
-> nick
, sender
-> nick
, bot
-> public_chan
-> name
-> content
);
660 deleteschedule ( 0 , qabot_spamstored
, ( void *) bot
);
664 bot
-> lastmic
= time ( NULL
);
665 bot
-> micnumeric
= sender
-> numeric
;
666 sendmessagetochannel ( bot
-> np
, cp
, "Mic activated. Anything said by %s will be relayed in %s ." ,
667 sender
-> nick
, bot
-> public_chan
-> name
-> content
);
668 deleteschedule ( 0 , qabot_spamstored
, ( void *) bot
);
674 int qabot_dochanmoo ( void * np
, int cargc
, char ** cargv
) {
675 qab_bot
* bot
= qabot_getcurrentbot ();
677 int i
, moocount
= 5 + ( rand () % 40 );
678 channel
* cp
= qabot_getcurrentchannel ();
681 for ( i
= 1 ; i
< moocount
; i
++)
682 moostr
[ i
] = (( rand () % 100 ) > 50 ) ? 'o' : '0' ;
685 sendmessagetochannel ( bot
-> np
, cp
, " %s " , moostr
);
690 int qabot_dochanofftopic ( void * np
, int cargc
, char ** cargv
) {
691 nick
* sender
= ( nick
*) np
;
692 qab_bot
* bot
= qabot_getcurrentbot ();
698 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !spam <id> [<id> ... <id>]" );
702 for ( i
= 0 ; i
< cargc
; i
++) {
703 id
= strtol ( cargv
[ i
], NULL
, 10 );
705 if (( id
< 1 ) || ( id
> bot
-> lastquestionID
)) {
706 sendnoticetouser ( bot
-> np
, sender
, "Invalid question ID %d ." , id
);
710 for ( q
= bot
-> questions
[ id
% QUESTIONHASHSIZE
]; q
; q
= q
-> next
)
715 sendnoticetouser ( bot
-> np
, sender
, "Can't find question %d ." , id
);
719 switch ( q
-> flags
& QAQ_QSTATE
) {
721 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been answered." , id
);
725 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been marked as off-topic." , id
);
729 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been marked as spam." , id
);
736 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_OFFTOPIC
;
737 sendnoticetouser ( bot
-> np
, sender
, "Question %d has been marked as off-topic." , id
);
743 int qabot_dochanopenchan ( void * np
, int cargc
, char ** cargv
) {
744 nick
* sender
= ( nick
*) np
;
745 qab_bot
* bot
= qabot_getcurrentbot ();
748 localsetmodeinit (& changes
, bot
-> public_chan
-> channel
, bot
-> np
);
749 localdosetmode_simple (& changes
, CHANMODE_MODERATE
| CHANMODE_DELJOINS
, CHANMODE_INVITEONLY
);
750 localsetmodeflush (& changes
, 1 );
751 sendnoticetouser ( bot
-> np
, sender
, "Public channel has been opened." );
756 int qabot_dochanping ( void * np
, int cargc
, char ** cargv
) {
757 qab_bot
* bot
= qabot_getcurrentbot ();
758 channel
* cp
= qabot_getcurrentchannel ();
760 sendmessagetochannel ( bot
-> np
, cp
, "pong!" );
765 int qabot_dochanreset ( void * np
, int cargc
, char ** cargv
) {
766 nick
* sender
= ( nick
*) np
;
767 qab_bot
* bot
= qabot_getcurrentbot ();
771 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !reset <blocks|questions|stats|all>" );
775 if (! ircd_strcmp ( cargv
[ 0 ], "blocks" ))
777 else if (! ircd_strcmp ( cargv
[ 0 ], "questions" ))
779 else if (! ircd_strcmp ( cargv
[ 0 ], "stats" ))
781 else if (! ircd_strcmp ( cargv
[ 0 ], "all" ))
784 sendnoticetouser ( bot
-> np
, sender
, "Unknown parameter: %s ." , cargv
[ 0 ]);
791 while ( bot
-> blocks
) {
793 bot
-> blocks
= bot
-> blocks
-> next
;
799 bot
-> block_count
= 0 ;
801 sendnoticetouser ( bot
-> np
, sender
, "Reset (blocks): Done." );
808 for ( i
= 0 ; i
< QUESTIONHASHSIZE
; i
++) {
809 while ( bot
-> questions
[ i
]) {
810 q
= bot
-> questions
[ i
];
811 bot
-> questions
[ i
] = bot
-> questions
[ i
]-> next
;
820 bot
-> lastquestionID
= 0 ;
823 sendnoticetouser ( bot
-> np
, sender
, "Reset (questions): Done." );
829 sendnoticetouser ( bot
-> np
, sender
, "Reset (stats): Done." );
835 int qabot_dochanspam ( void * np
, int cargc
, char ** cargv
) {
836 nick
* sender
= ( nick
*) np
;
837 qab_bot
* bot
= qabot_getcurrentbot ();
843 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !spam <id> [<id> ... <id>]" );
847 for ( i
= 0 ; i
< cargc
; i
++) {
848 id
= strtol ( cargv
[ i
], NULL
, 10 );
850 if (( id
< 1 ) || ( id
> bot
-> lastquestionID
)) {
851 sendnoticetouser ( bot
-> np
, sender
, "Invalid question ID %d ." , id
);
855 for ( q
= bot
-> questions
[ id
% QUESTIONHASHSIZE
]; q
; q
= q
-> next
)
860 sendnoticetouser ( bot
-> np
, sender
, "Can't find question %d ." , id
);
864 switch ( q
-> flags
& QAQ_QSTATE
) {
866 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been answered." , id
);
870 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been marked as off-topic." , id
);
874 sendnoticetouser ( bot
-> np
, sender
, "Question %d has already been marked as spam." , id
);
881 q
-> flags
= (( q
-> flags
) & ~ QAQ_QSTATE
) | QAQ_SPAM
;
882 sendnoticetouser ( bot
-> np
, sender
, "Question %d has been marked as spam." , id
);
888 int qabot_dochanstatus ( void * np
, int cargc
, char ** cargv
) {
889 nick
* sender
= ( nick
*) np
;
890 qab_bot
* bot
= qabot_getcurrentbot ();
892 sendnoticetouser ( bot
-> np
, sender
, "Lines spammed: %d " , bot
-> spammed
);
893 sendnoticetouser ( bot
-> np
, sender
, "Questions asked: %d " , bot
-> lastquestionID
);
894 sendnoticetouser ( bot
-> np
, sender
, "Questions answered: %d " , bot
-> answered
);
895 sendnoticetouser ( bot
-> np
, sender
, "Blocks: %d " , bot
-> block_count
);
896 /*sendnoticetouser(bot->np, sender, "Question interval: %d seconds", bot->question_interval);*/
897 sendnoticetouser ( bot
-> np
, sender
, "Spam interval: %d seconds" , bot
-> spam_interval
);
898 sendnoticetouser ( bot
-> np
, sender
, "Nick block interval: %d seconds" , bot
-> ask_wait
);
899 sendnoticetouser ( bot
-> np
, sender
, "Queued question interval: %d seconds" , bot
-> queued_question_interval
);
900 sendnoticetouser ( bot
-> np
, sender
, "Block control chars: %s " , ( bot
-> flags
& QAB_CONTROLCHAR
) ? "Yes" : "No" );
901 sendnoticetouser ( bot
-> np
, sender
, "Block colour: %s " , ( bot
-> flags
& QAB_COLOUR
) ? "Yes" : "No" );
902 sendnoticetouser ( bot
-> np
, sender
, "Authed users only: %s " , ( bot
-> flags
& QAB_AUTHEDONLY
) ? "Yes" : "No" );
903 sendnoticetouser ( bot
-> np
, sender
, "Line break: %s " , ( bot
-> flags
& QAB_LINEBREAK
) ? "Yes" : "No" );
904 sendnoticetouser ( bot
-> np
, sender
, "Question flood detection: %s " , ( bot
-> flags
& QAB_FLOODDETECT
) ? "Yes" : "No" );
905 sendnoticetouser ( bot
-> np
, sender
, "Question flood blocking: %s " , ( bot
-> flags
& QAB_FLOODSTOP
) ? "Yes" : "No" );
906 sendnoticetouser ( bot
-> np
, sender
, "Blocks mark as spam: %s " , ( bot
-> flags
& QAB_BLOCKMARK
) ? "Yes" : "No" );
907 if ( bot
-> micnumeric
) {
908 nick
* mnick
= getnickbynumeric ( bot
-> micnumeric
);
910 sendnoticetouser ( bot
-> np
, np
, "Mic: Enabled ( %s )" , mnick
? mnick
-> nick
: "UNKNOWN" );
913 sendnoticetouser ( bot
-> np
, np
, "Mic: Disabled" );
914 sendnoticetouser ( bot
-> np
, sender
, "Mic timeout: %d " , bot
-> mic_timeout
);
915 /*sendnoticetouser(bot->np, sender, "");*/
920 int qabot_dochanunblock ( void * np
, int cargc
, char ** cargv
) {
921 nick
* sender
= ( nick
*) np
;
922 qab_bot
* bot
= qabot_getcurrentbot ();
928 sendnoticetouser ( bot
-> np
, sender
, "Syntax: !unblock [-q|-t] <account|mask>" );
933 if (! ircd_strncmp ( cargv
[ 0 ], "-q" , 2 )) {
934 type
= QABBLOCK_ACCOUNT
;
940 else if (! ircd_strncmp ( cargv
[ 0 ], "-t" , 2 )) {
941 type
= QABBLOCK_TEXT
;
945 sendnoticetouser ( bot
-> np
, sender
, "Invalid flag." );
950 type
= QABBLOCK_HOST
;
954 for ( b
= bot
-> blocks
; b
; b
= b
-> next
) {
958 if (! ircd_strcmp ( b
-> blockstr
, ch
)) {
960 b
-> next
-> prev
= b
-> prev
;
962 b
-> prev
-> next
= b
-> next
;
964 bot
-> blocks
= b
-> next
;
971 sendnoticetouser ( bot
-> np
, sender
, "Block removed." );
976 sendnoticetouser ( bot
-> np
, sender
, "No such block." );