/var/www/www.irssi.org-old/scripts/html/dau.pl


   1 ################################################################################
   2 # $Id: dau.pl 273 2008-02-03 15:27:25Z heidinger $
   3 ################################################################################
   4 #
   5 # dau.pl - write like an idiot
   6 #
   7 ################################################################################
   8 # Author
   9 ################################################################################
  10 #
  11 # Clemens Heidinger <heidinger@dau.pl>
  12 #
  13 ################################################################################
  14 # Changelog
  15 ################################################################################
  16 #
  17 # dau.pl has a built-in changelog (--changelog switch)
  18 #
  19 ################################################################################
  20 # Credits
  21 ################################################################################
  22 #
  23 # - Robert Hennig: For the original dau shell script. Out of this script,
  24 #   merged with some other small Perl and shell scripts and aliases arised the
  25 #   first version of dau.pl for irssi.
  26 #
  27 ################################################################################
  28 # Documentation
  29 ################################################################################
  30 #
  31 # dau.pl has a built-in documentation (--help switch)
  32 #
  33 ################################################################################
  34 # License
  35 ################################################################################
  36 #
  37 # Licensed under the BSD license
  38 #
  39 ################################################################################
  40 # Website
  41 ################################################################################
  42 #
  43 # http://dau.pl/
  44 #
  45 # Additional information, DAU.pm, the dauomat and the dauproxy
  46 #
  47 ################################################################################
  48 
  49 use 5.6.0;
  50 use File::Basename;
  51 use File::Path;
  52 use IPC::Open3;
  53 use Irssi 20021107.0841;
  54 use Irssi::TextUI;
  55 use locale;
  56 use POSIX;
  57 use re 'eval';
  58 use strict;
  59 use Tie::File;
  60 use vars qw($VERSION %IRSSI);
  61 
  62 $VERSION = '2.4.3';
  63 #$VERSION = '2.4.3 SVN ($LastChangedRevision: 273 $)';
  64 %IRSSI = (
  65           authors     => 'Clemens Heidinger',
  66           changed     => '$LastChangedDate: 2008-02-03 16:27:25 +0100 (Sun, 03 Feb 2008) $',
  67           commands    => 'dau',
  68           contact     => 'heidinger@dau.pl',
  69           description => 'write like an idiot',
  70           license     => 'BSD',
  71           modules     => 'File::Basename File::Path IPC::Open3 POSIX Tie::File',
  72           name        => 'DAU',
  73           sbitems     => 'daumode',
  74           url         => 'http://dau.pl/',
  75 );
  76 
  77 ################################################################################
  78 # Register commands
  79 ################################################################################
  80 
  81 Irssi::command_bind('dau', \&command_dau);
  82 
  83 ################################################################################
  84 # Register settings
  85 # setting changed/added => change/add it here
  86 ################################################################################
  87 
  88 # boolean
  89 Irssi::settings_add_bool('misc', 'dau_away_quote_reason', 1);
  90 Irssi::settings_add_bool('misc', 'dau_away_reminder', 0);
  91 Irssi::settings_add_bool('misc', 'dau_babble_verbose', 1);
  92 Irssi::settings_add_bool('misc', 'dau_color_choose_colors_randomly', 1);
  93 Irssi::settings_add_bool('misc', 'dau_cowsay_print_cow', 0);
  94 Irssi::settings_add_bool('misc', 'dau_figlet_print_font', 0);
  95 Irssi::settings_add_bool('misc', 'dau_silence', 0);
  96 Irssi::settings_add_bool('misc', 'dau_statusbar_daumode_hide_when_off', 0);
  97 Irssi::settings_add_bool('misc', 'dau_tab_completion', 1);
  98 
  99 # Integer
 100 Irssi::settings_add_int('misc', 'dau_babble_history_size', 10);
 101 Irssi::settings_add_int('misc', 'dau_babble_verbose_minimum_lines', 2);
 102 Irssi::settings_add_int('misc', 'dau_cool_maximum_line', 2);
 103 Irssi::settings_add_int('misc', 'dau_cool_probability_eol', 20);
 104 Irssi::settings_add_int('misc', 'dau_cool_probability_word', 20);
 105 Irssi::settings_add_int('misc', 'dau_remote_babble_interval_accuracy', 90);
 106 
 107 # String
 108 Irssi::settings_add_str('misc', 'dau_away_away_text', '$N is away now: [ $reason ]. Away since: $Z. I am currently not available at $T @ $chatnet (sry 4 amsg)!');
 109 Irssi::settings_add_str('misc', 'dau_away_back_text', '$N is back: [ $reason ]. Away time: [ $time ]. I am available again at $T @ $chatnet (sry 4 amsg)!');
 110 Irssi::settings_add_str('misc', 'dau_away_options',
 111                                                    "--parse_special --bracket -left '!---?[' -right ']?---!' --color -split capitals -random off -codes 'light red; yellow',"  .
 112                                                    "--parse_special --bracket -left '--==||{{' -right '}}||==--' --color -split capitals -random off -codes 'light red; light cyan'," .
 113                                                    "--parse_special --bracket -left '--==||[[' -right ']]||==--' --color -split capitals -random off -codes 'yellow; light green'"
 114 );
 115 Irssi::settings_add_str('misc', 'dau_away_reminder_interval', '1 hour');
 116 Irssi::settings_add_str('misc', 'dau_away_reminder_text', '$N is still away: [ $reason ]. Away time: [ $time ] (sry 4 amsg)');
 117 Irssi::settings_add_str('misc', 'dau_babble_options_line_by_line', '--nothing');
 118 Irssi::settings_add_str('misc', 'dau_babble_options_preprocessing', '');
 119 Irssi::settings_add_str('misc', 'dau_color_codes', 'blue; green; red; magenta; yellow; cyan');
 120 Irssi::settings_add_str('misc', 'dau_cool_eol_style', 'random');
 121 Irssi::settings_add_str('misc', 'dau_cowsay_cowlist', '');
 122 Irssi::settings_add_str('misc', 'dau_cowsay_cowpath', &def_dau_cowsay_cowpath);
 123 Irssi::settings_add_str('misc', 'dau_cowsay_cowpolicy', 'allow');
 124 Irssi::settings_add_str('misc', 'dau_cowsay_cowsay_path', &def_dau_cowsay_cowsay_path);
 125 Irssi::settings_add_str('misc', 'dau_cowsay_cowthink_path', &def_dau_cowsay_cowthink_path);
 126 Irssi::settings_add_str('misc', 'dau_daumode_channels', '');
 127 Irssi::settings_add_str('misc', 'dau_delimiter_string', ' ');
 128 Irssi::settings_add_str('misc', 'dau_figlet_fontlist', 'mnemonic,term,ivrit');
 129 Irssi::settings_add_str('misc', 'dau_figlet_fontpath', &def_dau_figlet_fontpath);
 130 Irssi::settings_add_str('misc', 'dau_figlet_fontpolicy', 'allow');
 131 Irssi::settings_add_str('misc', 'dau_figlet_path', &def_dau_figlet_path);
 132 Irssi::settings_add_str('misc', 'dau_files_away', '.away');
 133 Irssi::settings_add_str('misc', 'dau_files_babble_messages', 'babble_messages');
 134 Irssi::settings_add_str('misc', 'dau_files_cool_suffixes', 'cool_suffixes');
 135 Irssi::settings_add_str('misc', 'dau_files_root_directory', "$ENV{HOME}/.dau");
 136 Irssi::settings_add_str('misc', 'dau_files_substitute', 'substitute.pl');
 137 Irssi::settings_add_str('misc', 'dau_language', 'en');
 138 Irssi::settings_add_str('misc', 'dau_moron_eol_style', 'random');
 139 Irssi::settings_add_str('misc', 'dau_parse_special_list_delimiter', ' ');
 140 Irssi::settings_add_str('misc', 'dau_random_options',
 141                                                       '--substitute --boxes --uppercase,' .
 142                                                       "--substitute --color -split capitals -random off -codes 'light red; yellow'," .
 143                                                       "--substitute --color -split capitals -random off -codes 'light red; light cyan'," .
 144                                                       "--substitute --color -split capitals -random off -codes 'yellow; light green'," .
 145                                                       '--substitute --color --uppercase,' .
 146                                                       '--substitute --cool,' .
 147                                                       '--substitute --delimiter,' .
 148                                                       '--substitute --dots --moron,' .
 149                                                       '--substitute --leet,' .
 150                                                       '--substitute --mix,' .
 151                                                       '--substitute --mixedcase --bracket,' .
 152                                                       '--substitute --moron --stutter --uppercase,' .
 153                                                       '--substitute --moron -omega on,' .
 154                                                       '--substitute --moron,' .
 155                                                       '--substitute --uppercase --underline,' .
 156                                                       '--substitute --words --mixedcase'
 157 );
 158 Irssi::settings_add_str('misc', 'dau_remote_babble_channellist', '');
 159 Irssi::settings_add_str('misc', 'dau_remote_babble_channelpolicy', 'deny');
 160 Irssi::settings_add_str('misc', 'dau_remote_babble_interval', '1 hour');
 161 Irssi::settings_add_str('misc', 'dau_remote_channellist', '');
 162 Irssi::settings_add_str('misc', 'dau_remote_channelpolicy', 'deny');
 163 Irssi::settings_add_str('misc', 'dau_remote_deop_reply', 'you are on my shitlist now @ $nick');
 164 Irssi::settings_add_str('misc', 'dau_remote_devoice_reply', 'you are on my shitlist now @ $nick');
 165 Irssi::settings_add_str('misc', 'dau_remote_op_reply', 'thx 4 op @ $nick');
 166 Irssi::settings_add_str('misc', 'dau_remote_permissions', '000000');
 167 Irssi::settings_add_str('misc', 'dau_remote_question_regexp', '%%%DISABLED%%%');
 168 Irssi::settings_add_str('misc', 'dau_remote_question_reply', 'EDIT_THIS_ONE');
 169 Irssi::settings_add_str('misc', 'dau_remote_voice_reply', 'thx 4 voice @ $nick');
 170 Irssi::settings_add_str('misc', 'dau_standard_messages', 'hi @ all');
 171 Irssi::settings_add_str('misc', 'dau_standard_options', '--random');
 172 Irssi::settings_add_str('misc', 'dau_words_range', '1-4');
 173 
 174 ################################################################################
 175 # Register signals
 176 # (Note that most signals are set dynamical in the subroutine signal_handling)
 177 ################################################################################
 178 
 179 Irssi::signal_add_last('setup changed', \&signal_setup_changed);
 180 Irssi::signal_add_last('window changed' => sub { Irssi::statusbar_items_redraw('daumode') });
 181 Irssi::signal_add_last('window item changed' => sub { Irssi::statusbar_items_redraw('daumode') });
 182 
 183 ################################################################################
 184 # Register statusbar items
 185 ################################################################################
 186 
 187 Irssi::statusbar_item_register('daumode', '', 'statusbar_daumode');
 188 
 189 ################################################################################
 190 # Global variables
 191 ################################################################################
 192 
 193 # Timer used by --away
 194 
 195 our %away_timer;
 196 
 197 # babble
 198 
 199 our %babble;
 200 
 201 # --command -in
 202 
 203 our $command_in;
 204 
 205 # The command to use for the output (MSG f.e.)
 206 
 207 our $command_out;
 208 
 209 # '--command -out' used?
 210 
 211 our $command_out_activated;
 212 
 213 # Counter for the subroutines entered
 214 
 215 our $counter_subroutines;
 216 
 217 # Counter for the switches
 218 # --me --moron: --me would be 0, --moron 1
 219 
 220 our $counter_switches;
 221 
 222 # daumode
 223 
 224 our %daumode;
 225 
 226 # daumode activated?
 227 
 228 our $daumode_activated;
 229 
 230 # Help text
 231 
 232 our %help;
 233 $help{options} = <<END;
 234 %9--away%9
 235     Toggle away mode
 236 
 237     %9-channels%9 %U'#channel1/network1, #channel2/network2, ...'%U:
 238         Say away message in all those %Uchannels%U
 239 
 240     %9-interval%9 %Utime%U:
 241         Remind channel now and then that you're away
 242 
 243     %9-reminder%9 %Uon|off%U:
 244         Turn reminder on or off
 245 
 246 %9--babble%9
 247     Babble a message.
 248 
 249     %9-at%9 %Unicks%U:
 250         Comma separated list of nicks to babble at.
 251         \$nick1, \$nick2 and so forth of the babble line will be replaced
 252         by those nicks.
 253 
 254     %9-cancel%9 %Uon|off%U:
 255         Cancel active babble
 256 
 257     %9-filter%9 %Uregular expression%U:
 258         Only let through if the babble matches the %Uregular expression%U
 259 
 260     %9-history_size%9 %Un%U:
 261         Set the size of the history for this one babble to %Un%U
 262 
 263 %9--boxes%9
 264     Put words in boxes
 265 
 266 %9--bracket%9
 267     Bracket the text
 268 
 269     %9-left%9 %Ustring%U:
 270         Left bracket
 271 
 272     %9-right%9 %Ustring%U:
 273         Right bracket
 274 
 275 %9--changelog%9
 276     Print the changelog
 277 
 278 %9--chars%9
 279     Only one character each line
 280 
 281 %9--color%9
 282     Write in colors
 283 
 284     %9-codes%9 %Ucodes%U:
 285         Overrides setting dau_color_codes
 286 
 287     %9-random%9 %Uon|off%U:
 288         Choose color randomly from setting dau_color_codes resp.
 289         %9--color -codes%9 or take one by one in the exact order given.
 290 
 291     %9-split%9
 292         %Ucapitals%U:   Split by capitals
 293         %Uchars%U:      Every character another color
 294         %Ulines%U:      Every line another color
 295         %Uparagraph%U:  The whole paragraph in one color
 296         %Urchars%U:     Some characters one color
 297         %Uwords%U:      Every word another color
 298 
 299 %9--command%9
 300     %9-in%9 %Ucommand%U:
 301         Feed dau.pl with the output (the public message)
 302         that %Ucommand%U produces
 303 
 304     %9-out%9 %Ucommand%U:
 305         %Utopic%U for example will set a dauified topic
 306 
 307 %9--cool%9
 308     Be \$cool[tm]!!!!11one
 309 
 310     %9-eol_style%9 %Ustring%U:
 311         Override setting dau_cool_eol_style
 312 
 313     %9-max%9 %Un%U:
 314         \$Trademarke[tm] only %Un%U words per line tops
 315 
 316     %9-prob_eol%9 %U0-100%U:
 317         Probability that "!!!11one" or something like that will be put at EOL.
 318         Set it to 100 and every line will be.
 319         Set it to 0 and no line will be.
 320 
 321     %9-prob_word%9 %U0-100%U:
 322         Probability that a word will be \$trademarked[tm].
 323         Set it to 100 and every word will be.
 324         Set it to 0 and no word will be.
 325 
 326 %9--cowsay%9
 327     Use cowsay to write
 328 
 329     %9-arguments%9 %Uarguments%U:
 330         Pass any option to cowsay, f.e. %U'-b'%U or %U'-e XX'%U.
 331         Look in the cowsay manualpage for details.
 332 
 333     %9-cow%9 %Ucow%U:
 334         The cow to use
 335 
 336     %9-think%9 %Uon|off%U:
 337         Thinking instead of speaking
 338 
 339 %9--create_files%9
 340     Create files and directories of all dau_files_* settings
 341 
 342 %9--daumode%9
 343     Toggle daumode.
 344     Works on a per channel basis!
 345 
 346     %9-modes_in%9 %Umodes%U:
 347         All incoming messages will be dauified and the
 348         specified modes are used by dau.pl.
 349 
 350     %9-modes_out%9 %Umodes%U:
 351         All outgoing messages will be dauified and the
 352         specified modes are used by dau.pl.
 353 
 354     %9-perm%9 %U[01][01]%U:
 355         Dauify incoming/outgoing messages?
 356 
 357 %9--delimiter%9
 358     Insert a delimiter-string after each character
 359 
 360     %9-string%9 %Ustring%U:
 361         Override setting dau_delimiter_string. If this string
 362         contains whitespace, you should quote the string with
 363         single quotes.
 364 
 365 %9--dots%9
 366     Put dots... after words...
 367 
 368 %9--figlet%9
 369     Use figlet to write
 370 
 371     %9-font%9 %Ufont%U:
 372         The font to use
 373 
 374 %9--help%9
 375     Print help
 376 
 377     %9-setting%9 %Usetting%U:
 378         More information about a specific setting
 379 
 380 %9--leet%9
 381     Write in leet speech
 382 
 383 %9--long_help%9
 384     Long help, i.e. examples, more about some features, ...
 385 
 386 %9--me%9
 387     Send a CTCP ACTION instead of a PRIVMSG
 388 
 389 %9--mix%9
 390     Mix all the characters in a word except for the first and last
 391 
 392 %9--mixedcase%9
 393     Write in mixed case
 394 
 395 %9--moron%9
 396     Write in uppercase, mix in some typos, perform some
 397     substitutions on the text, ... Just write like a
 398     moron
 399 
 400     %9-eol_style%9 %Ustring%U:
 401         Override setting dau_moron_eol_style
 402 
 403     %9-level%9 %Un%U:
 404         %Un%U gives the level of stupidity applied to text,
 405         the higher the stupider.
 406         %U0%U is the minimum, %U1%U currently only implemented for dau_language = de.
 407 
 408     %9-omega%9 %Uon|off%U:
 409         The fantastic omega mode
 410 
 411     %9-typo%9 %Uon|off%U:
 412         Mix in random typos
 413 
 414     %9-uppercase%9 %Uon|off%U:
 415         Uppercase text
 416 
 417 %9--nothing%9
 418     Do nothing
 419 
 420 %9--parse_special%9
 421     Parse for special metasequences and substitute them.
 422 
 423     %9-irssi_variables%9 %Uon|off%U:
 424         Parse irssi special variables like \$N
 425 
 426     %9-list_delimiter%9 %Ustring%U:
 427         Set the list delimiter used for \@nicks and \@opnicks to %Ustring%U.
 428 
 429     The special metasequences are:
 430 
 431     - \\n:
 432       real newline
 433     - \$nick1 .. \$nickN:
 434       N different randomly selected nicks
 435     - \@nicks:
 436       All nicks in channel
 437     - \$opnick1 .. \$opnickN:
 438       N different randomly selected opnicks
 439     - \@opnicks:
 440       All nicks in channel with operator status
 441     - \$?{ code }:
 442       the (perl)code will be evaluated and the last expression
 443       returned will replace that metasequence
 444     - irssis special variables like \$C for the current
 445       channel and \$N for your current nick
 446 
 447     Quoting:
 448 
 449     - \\\$: literal \$
 450     - \\\\: literal \\
 451 
 452 %9--random%9
 453     Let dau.pl choose the options randomly. Get these options from the setting
 454     dau_random_options.
 455 
 456     %9-verbose%9 %Uon|off%U:
 457         Print what options --random has chosen
 458 
 459 %9--reverse%9
 460     Reverse the input string
 461 
 462 %9--stutter%9
 463     Stutter a bit
 464 
 465 %9--substitute%9
 466     Apply own substitutions from file
 467 
 468 %9--underline%9
 469     Underline text
 470 
 471 %9--uppercase%9
 472     Write in upper case
 473 
 474 %9--words%9
 475     Only a few words each line
 476 END
 477 
 478 # Containing irssi's 'cmdchars'
 479 
 480 our $k = Irssi::parse_special('$k');
 481 
 482 # Remember your nick mode
 483 
 484 our %nick_mode;
 485 
 486 # All the options
 487 
 488 our %option;
 489 
 490 # print() the message or not?
 491 
 492 our $print_message;
 493 
 494 # Queue holding the switches
 495 
 496 our %queue;
 497 
 498 # Remember the last switches used by --random so that they don't repeat
 499 
 500 our $random_last;
 501 
 502 # Signals
 503 
 504 our %signal = (
 505     'complete word'     => 0,
 506     'daumode in'        => 0,
 507     'event 404'         => 0,
 508     'event privmsg'     => 0,
 509     'nick mode changed' => 0,
 510     'send text'         => 0,
 511 );
 512 
 513 # All switches that may be given at commandline
 514 
 515 our %switches = (
 516 
 517     # These switches may be combined
 518 
 519     combo  => {
 520                 boxes     => { 'sub'  => \&switch_boxes },
 521                 bracket   => {
 522                               'sub' => \&switch_bracket,
 523                                left  => { '*' => 1 },
 524                                right => { '*' => 1 },
 525                              },
 526                 chars     => { 'sub' => \&switch_chars },
 527                 color     => {
 528                               'sub'   => \&switch_color,
 529                               codes   => { '*' => 1 },
 530                               random  => {
 531                                            off => 1,
 532                                            on  => 1,
 533                                           },
 534                               'split' => {
 535                                           capitals  => 1,
 536                                           chars     => 1,
 537                                           lines     => 1,
 538                                           paragraph => 1,
 539                                           rchars    => 1,
 540                                           words     => 1,
 541                                          },
 542                              },
 543                 command   => {
 544                               'sub' => \&switch_command,
 545                                in   => { '*' => 1 },
 546                                out  => { '*' => 1 },
 547                                },
 548                 cool      => {
 549                               'sub'      => \&switch_cool,
 550                                eol_style => {
 551                                              suffixes          => 1,
 552                                              exclamation_marks => 1,
 553                                              random            => 1,
 554                                             },
 555                                max       => { '*' => 1 },
 556                                prob_eol  => { '*' => 1 },
 557                                prob_word => { '*' => 1 },
 558                              },
 559                 cowsay    => {
 560                               'sub'       => \&switch_cowsay,
 561                                arguments  => { '*' => 1 },
 562                                think      => {
 563                                               off => 1,
 564                                               on  => 1,
 565                                              },
 566                              },
 567                 delimiter => {
 568                               'sub'    => \&switch_delimiter,
 569                                string  => { '*' => 1 },
 570                              },
 571                 dots      => { 'sub' => \&switch_dots },
 572                 figlet    => { 'sub' => \&switch_figlet },
 573                 me        => { 'sub' => \&switch_me },
 574                 mix       => { 'sub' => \&switch_mix },
 575                 moron     => {
 576                               'sub'      => \&switch_moron,
 577                                eol_style => {
 578                                              nothing => 1,
 579                                              random  => 1,
 580                                             },
 581                                level     => { '*' => 1 },
 582                                omega     => {
 583                                              off => 1,
 584                                              on  => 1,
 585                                             },
 586                                typo      => {
 587                                              off => 1,
 588                                              on  => 1,
 589                                             },
 590                                uppercase => {
 591                                              off => 1,
 592                                              on  => 1,
 593                                             },
 594                              },
 595                 leet          => { 'sub' => \&switch_leet },
 596                 mixedcase     => { 'sub' => \&switch_mixedcase },
 597                 nothing       => { 'sub' => \&switch_nothing },
 598                 parse_special => {
 599                                   'sub' => \&switch_parse_special,
 600                                   irssi_variables => {
 601                                                       off => 1,
 602                                                       on  => 1,
 603                                                      },
 604                                   list_delimiter  => { '*' => 1 },
 605                                  },
 606                 'reverse'     => { 'sub' => \&switch_reverse },
 607                 stutter       => { 'sub' => \&switch_stutter },
 608                 substitute    => { 'sub' => \&switch_substitute },
 609                 underline     => { 'sub' => \&switch_underline },
 610                 uppercase     => { 'sub' => \&switch_uppercase },
 611                 words         => { 'sub' => \&switch_words },
 612                },
 613 
 614     # The following switches must not be combined
 615 
 616     nocombo => {
 617                 away         => {
 618                                  'sub' => \&switch_away,
 619                                  channels => { '*' => 1 },
 620                                  interval => { '*' => 1 },
 621                                  reminder => {
 622                                               on  => 1,
 623                                               off => 1,
 624                                              },
 625                                 },
 626                 babble       => {
 627                                  'sub'        => \&switch_babble,
 628                                  at           => { '*' => 1 },
 629                                  cancel       => {
 630                                                   on  => 1,
 631                                                   off => 1,
 632                                                  },
 633                                  filter       => { '*' => 1 },
 634                                  history_size => { '*' => 1 },
 635                                 },
 636                 changelog    => { 'sub' => \&switch_changelog },
 637                 create_files => { 'sub' => \&switch_create_files },
 638                 daumode      => {
 639                                  'sub'      => \&switch_daumode,
 640                                   modes_in  => { '*' => 1 },
 641                                   modes_out => { '*' => 1 },
 642                                   perm      => {
 643                                                 '00' => 1,
 644                                                 '01' => 1,
 645                                                 '10' => 1,
 646                                                 '11' => 1,
 647                                                },
 648                                 },
 649                 help         => {
 650                                  'sub'     => \&switch_help,
 651 
 652                                  # setting changed/added => change/add it here
 653 
 654                                  setting => {
 655                                              # boolean
 656                                              dau_away_quote_reason               => 1,
 657                                              dau_away_reminder                   => 1,
 658                                              dau_babble_verbose                  => 1,
 659                                              dau_color_choose_colors_randomly    => 1,
 660                                              dau_cowsay_print_cow                => 1,
 661                                              dau_figlet_print_font               => 1,
 662                                              dau_silence                         => 1,
 663                                              dau_statusbar_daumode_hide_when_off => 1,
 664                                              dau_tab_completion                  => 1,
 665 
 666                                              # Integer
 667                                              dau_babble_history_size             => 1,
 668                                              dau_babble_verbose_minimum_lines    => 1,
 669                                              dau_cool_maximum_line               => 1,
 670                                              dau_cool_probability_eol            => 1,
 671                                              dau_cool_probability_word           => 1,
 672                                              dau_remote_babble_interval_accuracy => 1,
 673 
 674                                              # String
 675                                              dau_away_away_text                  => 1,
 676                                              dau_away_back_text                  => 1,
 677                                              dau_away_options                    => 1,
 678                                              dau_away_reminder_interval          => 1,
 679                                              dau_away_reminder_text              => 1,
 680                                              dau_babble_options_line_by_line     => 1,
 681                                              dau_babble_options_preprocessing    => 1,
 682                                              dau_color_codes                     => 1,
 683                                              dau_cool_eol_style                  => 1,
 684                                              dau_cowsay_cowlist                  => 1,
 685                                              dau_cowsay_cowpath                  => 1,
 686                                              dau_cowsay_cowpolicy                => 1,
 687                                              dau_cowsay_cowsay_path              => 1,
 688                                              dau_cowsay_cowthink_path            => 1,
 689                                              dau_daumode_channels                => 1,
 690                                              dau_delimiter_string                => 1,
 691                                              dau_figlet_fontlist                 => 1,
 692                                              dau_figlet_fontpath                 => 1,
 693                                              dau_figlet_fontpolicy               => 1,
 694                                              dau_figlet_path                     => 1,
 695                                              dau_files_away                      => 1,
 696                                              dau_files_babble_messages           => 1,
 697                                              dau_files_cool_suffixes             => 1,
 698                                              dau_files_root_directory            => 1,
 699                                              dau_files_substitute                => 1,
 700                                              dau_language                        => 1,
 701                                              dau_moron_eol_style                 => 1,
 702                                              dau_parse_special_list_delimiter    => 1,
 703                                              dau_random_options                  => 1,
 704                                              dau_remote_babble_channellist       => 1,
 705                                              dau_remote_babble_channelpolicy     => 1,
 706                                              dau_remote_babble_interval          => 1,
 707                                              dau_remote_channellist              => 1,
 708                                              dau_remote_channelpolicy            => 1,
 709                                              dau_remote_deop_reply               => 1,
 710                                              dau_remote_devoice_reply            => 1,
 711                                              dau_remote_op_reply                 => 1,
 712                                              dau_remote_permissions              => 1,
 713                                              dau_remote_question_regexp          => 1,
 714                                              dau_remote_question_reply           => 1,
 715                                              dau_remote_voice_reply              => 1,
 716                                              dau_standard_messages               => 1,
 717                                              dau_standard_options                => 1,
 718                                              dau_words_range                     => 1,
 719                                             },
 720                                 },
 721                 long_help => { 'sub'    => \&switch_long_help },
 722                 random    => { 'sub'    => \&switch_random,
 723                                 verbose => {
 724                                             off => 1,
 725                                             on  => 1,
 726                                            },
 727                              },
 728                },
 729 );
 730 
 731 ################################################################################
 732 # Code run once at start
 733 ################################################################################
 734 
 735 print CLIENTCRAP "dau.pl $VERSION loaded. For help type %9${k}dau --help%9 or %9${k}dau --long_help%9";
 736 
 737 signal_setup_changed();
 738 build_nick_mode_struct();
 739 signal_handling();
 740 
 741 ################################################################################
 742 # Subroutines (commands)
 743 ################################################################################
 744 
 745 sub command_dau {
 746 	my ($data, $server, $witem) = @_;
 747 	my $output;
 748 
 749 	$output = parse_text($data, $witem);
 750 
 751 	unless (defined($server) && $server && $server->{connected}) {
 752 		$print_message = 1;
 753 	}
 754 	unless ((defined($witem) && $witem &&
 755 	       ($witem->{type} eq 'CHANNEL' || $witem->{type} eq 'QUERY')))
 756 	{
 757 		$print_message = 1;
 758 	}
 759 
 760 	if ($daumode_activated) {
 761 
 762 		if (defined($witem) && $witem &&
 763 		   ($witem->{type} eq 'CHANNEL' || $witem->{type} eq 'QUERY'))
 764 		{
 765 			my $modes_set = 0;
 766 
 767 			# daumode set with parameters (modes_in)
 768 
 769 			if ($queue{0}{daumode}{modes_in}) {
 770 				$daumode{channels_in}{$server->{tag}}{$witem->{name}} = 1;
 771 				$daumode{channels_in_modes}{$server->{tag}}{$witem->{name}} =
 772 				$queue{0}{daumode}{modes_in};
 773 				$modes_set = 1;
 774 			}
 775 
 776 			# daumode set with parameters (modes_out)
 777 
 778 			if ($queue{0}{daumode}{modes_out}) {
 779 				$daumode{channels_out}{$server->{tag}}{$witem->{name}} = 1;
 780 				$daumode{channels_out_modes}{$server->{tag}}{$witem->{name}} =
 781 				$queue{0}{daumode}{modes_out};
 782 				$modes_set = 1;
 783 			}
 784 
 785 			# daumode set without parameters
 786 
 787 			if (!$daumode{channels_in}{$server->{tag}}{$witem->{name}} &&
 788 			    !$daumode{channels_out}{$server->{tag}}{$witem->{name}} &&
 789 			    !$modes_set)
 790 			{
 791 				$daumode{channels_in}{$server->{tag}}{$witem->{name}} = 1;
 792 				$daumode{channels_out}{$server->{tag}}{$witem->{name}} = 1;
 793 				$daumode{channels_in_modes}{$server->{tag}}{$witem->{name}} = '';
 794 				$daumode{channels_out_modes}{$server->{tag}}{$witem->{name}} = '';
 795 			}
 796 
 797 			# daumode unset
 798 
 799 			elsif (($daumode{channels_in}{$server->{tag}}{$witem->{name}}  ||
 800 			        $daumode{channels_out}{$server->{tag}}{$witem->{name}}) &&
 801 			        !$modes_set)
 802 			{
 803 				$daumode{channels_in}{$server->{tag}}{$witem->{name}} = 0;
 804 				$daumode{channels_out}{$server->{tag}}{$witem->{name}} = 0;
 805 				$daumode{channels_in_modes}{$server->{tag}}{$witem->{name}} = '';
 806 				$daumode{channels_out_modes}{$server->{tag}}{$witem->{name}} = '';
 807 			}
 808 
 809 
 810 			# the perm-option overrides everything
 811 
 812 			# perm: 00
 813 
 814 			if ($queue{0}{daumode}{perm} eq '00') {
 815 				$daumode{channels_in}{$server->{tag}}{$witem->{name}} = 0;
 816 				$daumode{channels_out}{$server->{tag}}{$witem->{name}} = 0;
 817 				$daumode{channels_in_modes}{$server->{tag}}{$witem->{name}} = '';
 818 				$daumode{channels_out_modes}{$server->{tag}}{$witem->{name}} = '';
 819 			}
 820 
 821 			# perm: 01
 822 
 823 			if ($queue{0}{daumode}{perm} eq '01') {
 824 				$daumode{channels_in}{$server->{tag}}{$witem->{name}} = 0;
 825 				$daumode{channels_out}{$server->{tag}}{$witem->{name}} = 1;
 826 				$daumode{channels_in_modes}{$server->{tag}}{$witem->{name}} = '';
 827 			}
 828 
 829 			# perm: 10
 830 
 831 			if ($queue{0}{daumode}{perm} eq '10') {
 832 				$daumode{channels_in}{$server->{tag}}{$witem->{name}} = 1;
 833 				$daumode{channels_out}{$server->{tag}}{$witem->{name}} = 0;
 834 				$daumode{channels_out_modes}{$server->{tag}}{$witem->{name}} = '';
 835 			}
 836 
 837 			# perm: 11
 838 
 839 			if ($queue{0}{daumode}{perm} eq '11') {
 840 				$daumode{channels_in}{$server->{tag}}{$witem->{name}} = 1;
 841 				$daumode{channels_out}{$server->{tag}}{$witem->{name}} = 1;
 842 			}
 843 
 844 			Irssi::statusbar_items_redraw('daumode');
 845 		}
 846 
 847 		# Signal handling (for daumode and signal 'send text')
 848 
 849 		signal_handling();
 850 
 851 		return;
 852 	}
 853 
 854 	# MSG (or CTCP ACTION) $output to active channel/query-window
 855 
 856 	{
 857 		no strict 'refs';
 858 
 859 		$output = $output || '';
 860 		output_text($witem, $witem->{name}, $output);
 861 	}
 862 }
 863 
 864 ################################################################################
 865 # Subroutines (switches, must not be combined)
 866 ################################################################################
 867 
 868 sub switch_away {
 869 	my ($reason, $channel_rec, $reminder, $interval) = @_;
 870 	my $output;
 871 	my $time;
 872 	my $status = 'away';
 873 
 874 	################################################################################
 875 	################################################################################
 876 	# Get and handle options
 877 	################################################################################
 878 	################################################################################
 879 
 880 	################################################################################
 881 	# "/dau --away -interval <interval>" resp. dau_away_reminder_interval setting
 882 	################################################################################
 883 
 884 	# If called from command line, i.e. not by the
 885 	# "/dau --away -channels '<channels>'" workaround, $interval will be defined
 886 	# here
 887 	if (!defined($interval)) {
 888 		$interval = time_parse(return_option('away', 'interval', $option{dau_away_reminder_interval}));
 889 	}
 890 	if ($interval < 10 || $interval > 1000000000) {
 891 		print_err('Invalid value for away timer!');
 892 		return;
 893 	}
 894 
 895 	################################################################################
 896 	# setting dau_away_options
 897 	################################################################################
 898 
 899 	my $options = return_random_list_item($option{dau_away_options});
 900 
 901 	################################################################################
 902 	# "/dau --away -reminder <on|off>" resp. dau_away_reminder setting
 903 	################################################################################
 904 
 905 	# If called from command line, i.e. not by "/dau --away -channels '<channels>'"
 906 	# workaround, $reminder will be defined here
 907 	if (!defined($reminder)) {
 908 		$reminder = return_option('away', 'reminder', $option{dau_away_reminder});
 909 	}
 910 
 911 	# on -> 1, off -> 0
 912 	if ($reminder eq 'on' || $reminder == 1) {
 913 		$reminder = 1;
 914 	} else {
 915 		$reminder = 0;
 916 	}
 917 
 918 	################################################################################
 919 	# "/dau --away -channels '<channels>'"
 920 	################################################################################
 921 
 922 	# Go through all channels and for each call this subroutine again with
 923 	# $reminder and $interval as additional parameter as those otherwise would be
 924 	# lost. Sad world.
 925 
 926 	my $channels = return_option('away', 'channels');
 927 	# If not deleted, the program may loop here.
 928 	undef($queue{0}{away}{channels});
 929 	while ($channels =~ m{([^/]+)/([^,]+),?\s*}g) {
 930 		my $channel = $1;
 931 		my $network = $2;
 932 
 933 		my $server_rec  = Irssi::server_find_tag($network);
 934 		my $channel_rec = $server_rec->channel_find($channel);
 935 
 936 		if (defined($channel_rec) && $channel_rec &&
 937 		       ($channel_rec->{type} eq 'CHANNEL' || $channel_rec->{type} eq 'QUERY'))
 938 		{
 939 			switch_away($reason, $channel_rec, $reminder, $interval);
 940 		}
 941 
 942 	}
 943 	# "/dau --away -channels '<channels>'" first run => exit
 944 	return if ($channels);
 945 
 946 	################################################################################
 947 	# Now we are clear (from -channels)...
 948 	################################################################################
 949 
 950 	# Normal "/dau --away" (i.e. no -channels), but called from non
 951 	# channel/query window => exit
 952 	unless (defined($channel_rec) && $channel_rec &&
 953 	       ($channel_rec->{type} eq 'CHANNEL' || $channel_rec->{type} eq 'QUERY'))
 954 	{
 955 		return;
 956 	}
 957 
 958 	my $channel = $channel_rec->{name};
 959 	my $network = $channel_rec->{server}->{tag};
 960 	my $id      = "$channel/$network";
 961 
 962 	################################################################################
 963 	# Open file
 964 	################################################################################
 965 
 966 	my $file = "$option{dau_files_root_directory}/$option{dau_files_away}";
 967 	my @file;
 968 	unless (tie(@file, 'Tie::File', $file)) {
 969 		print_err("Cannot tie $file!");
 970 		return;
 971 	}
 972 
 973 	################################################################################
 974 	# Go through/edit file
 975 	################################################################################
 976 
 977 	# Format:
 978 	# channel | network | time | options | reminder | interval | reason
 979 	my $i = 0;
 980 	foreach my $line (@file) {
 981 		if ($line =~ m{^\Q$channel\E\x02\Q$network\E\x02(\d+)\x02([^\x02]*)\x02(?:\d)\x02(?:\d+)\x02(.*)}) {
 982 			$time = $1;
 983 			$options = $2;
 984 			$reason = $3;
 985 			$status = 'back';
 986 			last;
 987 		}
 988 		$i++;
 989 	}
 990 
 991 	if ($status eq 'away' && $reason eq '') {
 992 		print_out('Please set reason for your being away!');
 993 		return;
 994 	}
 995 
 996 	if ($status eq 'away') {
 997 		push(@file, "$channel\x02$network\x02" . time . "\x02$options\x02$reminder\x02$interval\x02$reason");
 998 		$output = $option{dau_away_away_text};
 999 	}
1000 
1001 	if ($status eq 'back') {
1002 		splice(@file, $i, 1);
1003 		$output = $option{dau_away_back_text};
1004 	}
1005 
1006 	################################################################################
1007 	# Special variables
1008 	################################################################################
1009 
1010 	# $time
1011 
1012 	if ($status eq 'back') {
1013 		my $difference = time_diff_verbose(time, $time);
1014 		$output =~ s/\$time/$difference/g;
1015 	}
1016 
1017 	# $reason
1018 
1019 	if ($option{dau_away_quote_reason}) {
1020 		$reason =~ s/\\/\\\\/g;
1021 		$reason =~ s/\$/\\\$/g;
1022 	}
1023 	$output =~ s/\$reason/$reason/g;
1024 
1025 	################################################################################
1026 	# Write changes back to file
1027 	################################################################################
1028 
1029 	untie(@file);
1030 
1031 	################################################################################
1032 	# The reminder timer
1033 	################################################################################
1034 
1035 	if ($status eq 'away' && $reminder) {
1036 		$away_timer{$id} = Irssi::timeout_add($interval, \&timer_away_reminder, $id);
1037 	} else {
1038 		Irssi::timeout_remove($away_timer{$id});
1039 	}
1040 
1041 	################################################################################
1042 	# Print message to channel
1043 	################################################################################
1044 
1045 	$output = parse_text("$options $output", $channel_rec);
1046 	output_text($channel_rec, $channel_rec->{name}, $output);
1047 
1048 	return;
1049 }
1050 
1051 sub switch_babble {
1052 	my ($data, $channel) = @_;
1053 	my $text;
1054 
1055 	# Cancel babble?
1056 
1057 	if (lc(return_option('babble', 'cancel')) eq 'on') {
1058 		if (defined($babble{timer_writing})) {
1059 			Irssi::timeout_remove($babble{timer_writing});
1060 			undef($babble{timer_writing});
1061 
1062 			if ($babble{remote}) {
1063 				timer_remote_babble_reset();
1064 			}
1065 
1066 			print_out("Babble cancelled.");
1067 		}
1068 		return;
1069 	}
1070 
1071 	# Filters
1072 
1073 	my @filter = ();
1074 	my $option_babble_at           = return_option('babble', 'at');
1075 	my $option_babble_filter       = return_option('babble', 'filter');
1076 	my $option_babble_history_size = return_option('babble', 'history_size', $option{dau_babble_history_size});
1077 
1078 	if ($option_babble_filter) {
1079 		push(@filter, $option_babble_filter);
1080 	}
1081 
1082 	# If something is babbling right now, exit
1083 
1084 	if (defined($babble{timer_writing})) {
1085 		print_err("You are already babbling something!");
1086 		return;
1087 	}
1088 
1089 	# get text from file
1090 
1091 	if ($option_babble_at) {
1092 		my @nicks;
1093 		foreach my $nick (split(/\s*,\s*/, $option_babble_at)) {
1094 			push(@nicks, $nick);
1095 		}
1096 		if (@nicks > 0) {
1097 			for (my $i = 1; $i <= $#nicks + 1; $i++) {
1098 				push(@filter, '\$nick' . $i);
1099 			}
1100 		}
1101 
1102 		$text = &babble_get_text($channel, \@filter, \@nicks, $option_babble_history_size);
1103 	} else {
1104 		$text = &babble_get_text($channel, \@filter, undef, $option_babble_history_size);
1105 	}
1106 
1107 	# babble only in channels
1108 
1109 	unless (defined($channel) && $channel && $channel->{type} eq 'CHANNEL') {
1110 		print_out('%9--babble%9 will only work in channel windows!');
1111 		return;
1112 	}
1113 
1114 	# Start the babbling
1115 
1116 	babble_start($channel, $text, 0);
1117 
1118 	return;
1119 }
1120 
1121 sub switch_changelog {
1122