]> git.99rst.org Git - irssi-scripts.irssi.org.git/commitdiff
Delete iquiz_en.pl
authorwilk <redacted>
Tue, 23 May 2017 17:27:06 +0000 (19:27 +0200)
committerGitHub <redacted>
Tue, 23 May 2017 17:27:06 +0000 (19:27 +0200)
This script is now obsolete. iquiz.pl now includes both language versions switchable by /set quiz_lang en/pl

scripts/iquiz_en.pl [deleted file]

diff --git a/scripts/iquiz_en.pl b/scripts/iquiz_en.pl
deleted file mode 100644 (file)
index 883ef65..0000000
+++ /dev/null
@@ -1,1310 +0,0 @@
-##################################################################
-##    irssi Quiz (iQuiz) script (2010-2017) by wilk/xorandor    ##
-##################################################################
-## Script inspired by classic mIRC scripts: "Dizzy" by Dizzy,   ##
-##   "Mieszacz" & "Familiada" by snajperx (both with my later   ##
-##   upgrades).                                                 ##
-## Other credits:                                               ##
-##   Bjoern 'fuchs' Krombholz for splitlong.pl calculations     ##
-##################################################################
-
-# Tested more or less with irssi 0.8.15 & 0.8.18 and Perl 5.8.8, 5.10.1, 5.14.2, 5.16.3 & 5.18.2
-
-# Script works with:
-#
-# - standard "Dizzy"/"Pomieszany" files (also without "pyt"/"odp" prefixes):
-#
-# pyt Evaluate: 2+2=?
-# odp four
-# pyt Star closest to Earth?
-# odp Sun
-# ...
-#
-# - standard "Mieszacz" files (also without line numbers):
-#
-# 1 alpha
-# 2 beta
-# 3 gamma
-# 4 delta
-# ...
-#
-# - standard "Familiada" files (can have any number of answers per question, not only 10; used also for "Multi"):
-#
-# Planets of our Solar System:
-# Mercury*Venus*Earth*Mars*Jupiter*Saturn*Uranus*Neptune
-# First six alkanes:
-# methane*ethane*propane*butane*pentane*hexane
-# ...
-
-# >>> To review all available commands and settings type: /quiz OR /help quiz
-
-# only core modules
-use strict;
-use warnings;
-use Irssi qw(theme_register current_theme command_bind settings_add_int settings_add_bool settings_add_str settings_get_int settings_get_bool settings_get_str settings_set_int settings_set_bool settings_set_str printformat timeout_add_once timeout_remove signal_add_last signal_remove signal_stop signal_emit active_win);
-use Time::HiRes qw(time);
-
-our $VERSION = '170202_en';
-our %IRSSI = (
-       authors                 => 'wilk',
-       name                    => 'iQuiz',
-       description             => 'irssi quiz script', # one script to bind them all
-       license                 => 'GNU GPL v3 or any later version',
-       changed                 => (($VERSION =~ /^(\d\d)(\d\d)(\d\d)/) ? "20$1-$2-$3" : $VERSION),
-       url                             => 'http://iquiz.quizpl.net',
-       contact                 => 'http://mail.quizpl.net',
-       changes                 => 'see http://www.quizpl.net/viewtopic.php?f=3&t=404',
-       usage                   => 'see http://www.quizpl.net/viewtopic.php?f=3&t=587'
-);
-
-##### Hardcoded settings #####
-my $_display_delay = 100;                      # msec; workaround for display issue (response before request)
-my $_start_delay = 5000;                       # msec; delay between /qon and showing first question (or 0)
-my $_standby_delay = 1000;                     # msec; delay between /qon and showing first question (or 0) while on standby
-my $_max_teams = 5;                                    # int; max allowed teams (5 is reasonable)
-my $_shuffle_watchdog = 10;                    # int; max shuffling repetitions to prevent mixed == original, but avoid infinite loop
-my $_shuffle_threshold = 3;                    # int; below this length reshuffling is off (to prevent mixed == original)
-my $_randomized_antigoogler = 0;       # bool; use better, randomized antigoogler? (will increase question length)
-my $_smarter_antigoogler = 1;          # bool; use smarter antigoogler? (leaves some empty spaces for better line breaking)
-my $_smarter_antigoogler_chunk = 2;    # int; leaves empty space every after this many substitutions (for use with $_smarter_antigoogler)
-my $_protect_urls = 1;                         # bool; turn off antigoogler if URL is detected in question?
-my $_round_warn_time = 15;                     # sec; seconds before round end to show warning (0 = off)
-my $_round_warn_coeff = 1.5;           # float; round duration must be longer than coeff * $_round_warn_time to show warning (protection)
-my $_qstats_ranks = 0;                         # bool; 0: /qstats param corresponds to number of players, 1: /qstats param corresponds to rank
-my $_qstats_records = 5;                       # int; number of time/speed record places in /qstats (0 - off)
-my $_no_hints_spam = 1;                                # bool; do not show fully revealed answer as a hint (except the first)?
-
-my $_flex_separator = '/';                     # char; separator used in quiz_flx_* formats
-my $_team_separator = ', ';                    # str; team players separator eq. "nick1, nick2, nick3"
-
-my $_next_delay = 10;                          # sec; default delay between questions
-my $_next_delay_long = 20;                     # sec; default delay between questions (fam/mul) (longer delay to prevent flooding and give a breath)
-my $_round_duration = 90;                      # sec; default round duration
-my $_hints_interval = 10;                      # sec; default hints interval
-my $_hint_alpha = '.';                         # char; default substitution symbol for alphabet characters in hints (special characters are left intact)
-my $_hint_digit = '.';                         # char; default substitution symbol for digit characters in hints (special characters are left intact)
-
-my $_quiz_types = 5;                           # (do not change)
-
-##### Internal stuff #####
-use constant { QT_STD => 1, QT_MIX => 2, QT_FAM => 3, QT_MUL => 4, QT_SCR => 5 }; # QT_MIL => 6, QT_FOR => 7
-use constant { T_HMS => 0, T_S => 1, T_MS => 2 }; # 0: h/m/s, 1: s only, 2: s.ms
-use constant { INSTANT => 1, PREPDOTS => 1, V_INT => 1, V_BOOL => 2, V_STR => 3 };
-
-my %quiz = (
-       chan => undef, file => '',
-       type => 0, tcnt => 0, # copies just in case someone modifies settings directly while quiz is running
-       ison => 0,              # /qon ... /qoff (or error while /qreload)
-       inq => 0,               # in question
-       standby => 0,   # /qon QT_FAM ... /qon (/qoff or error in /qreload)
-       ended => 0,             # after last question till /qoff (or error in /qreload)
-       stime => 0, qtime => 0,
-       qcnt => 0, qnum => 0, hnum => 0,
-       score => 0, answers => 0,
-       tnext => undef, tround => undef, thint => undef, thinter => undef, tremind => undef, twarn => undef,
-       hprot => 0, rprot => 0,
-       data => [],             # data[]{question realquestion answer answers{}}
-       teams => [],    # teams[]{score answers}
-       players => {},  # players{}{nick timestamp score answers team joined besttime alltime bestspeed allspeed}
-       lookup => {},
-       dcnt => 0,              # total number of currently unrevealed letters
-       dmax => 0,              # number of currently unrevealed letters in the "most hidden" word
-       dots => [], hwords => []
-);
-
-my %settings_int = (
-       'quiz_type' => QT_STD,
-       'quiz_teams' => 2,
-       'quiz_delay' => $_next_delay,
-       'quiz_delay_long' => $_next_delay_long,
-       'quiz_timeout' => $_round_duration,
-       'quiz_hints_interval' => $_hints_interval,
-       'quiz_max_hints' => 0,
-       'quiz_words_style' => 0,
-       'quiz_anticheat_delay' => 3,
-       'quiz_first_anticheat_delay' => 7,
-       'quiz_points_per_answer' => 1,
-       'quiz_min_points' => 1,
-       'quiz_max_points' => 50,
-       'quiz_scoring_mode' => 4,
-       'quiz_ranking_type' => 3,
-);
-
-my %settings_bool = (
-       'quiz_antigoogler' => 1,
-       'quiz_autohinter' => 0,
-       'quiz_split_long_lines' => 1,
-       'quiz_show_first_hint' => 0,
-       'quiz_first_hint_dots' => 0,
-       'quiz_random_hints' => 1,
-       'quiz_nonrandom_first_hint' => 1,
-       'quiz_words_mode' => 1,
-       'quiz_smart_mix' => 1,
-       'quiz_mix_on_remind' => 1,
-       'quiz_strict_match' => 1,
-       'quiz_join_anytime' => 1,
-       'quiz_team_play' => 1,
-       'quiz_transfer_points' => 0,
-       'quiz_limiter' => 0,
-       'quiz_keep_scores' => 0,
-       'quiz_keep_teams' => 1,
-       'quiz_cmd_hint' => 1,
-       'quiz_cmd_remind' => 1,
-);
-
-my %settings_str = (
-       'quiz_hint_alpha' => $_hint_alpha,
-       'quiz_hint_digit' => $_hint_digit,
-       'quiz_smart_mix_chars' => '\d()",.;:?!',
-);
-
-##### Theme (only channel messages are localized by default, feel free to customize here or via /format, except authorship) #####
-# quiz_inf_*, quiz_wrn_* & quiz_err_* messages are irssi only  - use irssi formatting and irssi color codes
-# quiz_msg_* messages are sent on channel                                              - use sprintf formatting and mIRC color codes:
-# \002 - bold  \003$fg(,$bg)? - color  \017 - plain  \026 - reverse  \037 - underline
-# quiz_inc_* - not sent directly, used as inclusions
-# quiz_flx_* - not sent directly, words' inflections
-# Important: To prevent visual glitches use two digit color codes! i.e. \00304 instead of \0034
-theme_register([
-       'quiz_inf_start',               '%_iQuiz:%_ Type /quiz to get more help.',
-       'quiz_inf_delay',               '%_iQuiz:%_ %gChanged delay between questions to: %_$0%_s%n',
-       'quiz_inf_duration',    '%_iQuiz:%_ %gChanged round duration to: %_$0%_s%n',
-       'quiz_inf_type',                '%_iQuiz:%_ %gChanged quiz type to: %_$0%_%n',
-       'quiz_inf_teams',               '%_iQuiz:%_ %gChanged number of teams to: %_$0%_%n',
-       'quiz_inf_reset',               '%_iQuiz:%_ %gAll settings has been reset to default values%n',
-       'quiz_inf_reload',              '%_iQuiz:%_ %gFile reloaded%n',
-
-       'quiz_wrn_reload',              '%_iQuiz:%_ %YQuestions\' count mismatch after reloading%n',
-
-       'quiz_err_ison',                '%_iQuiz:%_ %RQuiz is already on%n',
-       'quiz_err_isoff',               '%_iQuiz:%_ %RQuiz is already off%n',
-       'quiz_err_server',              '%_iQuiz:%_ %RNot connected to server%n',
-       'quiz_err_channel',             '%_iQuiz:%_ %RInvalid channel%n',
-       'quiz_err_nochannel',   '%_iQuiz:%_ %RChannel "$0" is not open%n',
-       'quiz_err_filename',    '%_iQuiz:%_ %RInvalid filename%n',
-       'quiz_err_nofile',              '%_iQuiz:%_ %RFile "$0" not found%n',
-       'quiz_err_file',                '%_iQuiz:%_ %RFile "$0" seems to be corrupted%n',
-       'quiz_err_argument',    '%_iQuiz:%_ %RInvalid argument%n',
-       'quiz_err_noquestion',  '%_iQuiz:%_ %RWait until question is asked%n',
-       'quiz_err_type',                '%_iQuiz:%_ %RInvalid quiz type%n',
-       'quiz_err_delay',               '%_iQuiz:%_ %RInvalid delay between questions%n',
-       'quiz_err_duration',    '%_iQuiz:%_ %RInvalid round duration%n',
-       'quiz_err_teams',               '%_iQuiz:%_ %RInvalid number of teams%n',
-       'quiz_err_ranking',             '%_iQuiz:%_ %RInvalid number of players%n',
-       'quiz_err_na',                  '%_iQuiz:%_ %RFeature is not available at this time%n',
-
-       'quiz_msg',                                             '%s', # custom text
-       'quiz_msg_start1',                              "\00303>>> \00310iQuiz by wilk - let's start! \00303<<<",
-       'quiz_msg_start2',                              "\00303Commands: !hint, !remind, !score, !score nick",
-       'quiz_msg_start2_f',                    "\00303Commands: !remind, !score, !score nick, !join 1-%u", # 1: max teams
-       'quiz_msg_start2_m',                    "\00303Commands: !remind, !score, !score nick",
-       'quiz_msg_stop1',                               "\00303>>> \00310iQuiz by wilk - the end \00303<<<",
-       'quiz_msg_stop2',                               "\00303Rounds: \00304%u \00303Play time: \00304%s", # 1: round, 2: time_str (hms)
-       'quiz_msg_question',                    "\00303\037Question %u/%u:\037 %s", # see below
-       'quiz_msg_question_x',                  "\00303\037Word %u/%u:\037 %s", # see below
-       'quiz_msg_question_fm',                 "\00303\037Question %u/%u:\037 %s \00303(\00313%u\00303 %s, time: %us)", # 1: round, 2: rounds, 3: question (quiz_inc_question), 4: answers, 5: quiz_flx_answers, 6: round time (s)
-       'quiz_inc_question',                    "\00300,01 %s \017", # 1: question (antygoogler takes first color code to harden question - must use background color if using antigoogler; if any color is used finish with "\017" to reset it)
-       'quiz_msg_hint',                                "\00303Hint: \00304%s", # 1: hint
-       'quiz_inc_hint_alpha',                  "\00310%s\00304", # 1: symbol (color codes are used to distinguish between hidden letter and real dot, but you may omit them)
-       'quiz_inc_hint_digit',                  "\00310%s\00304", # 1: symbol (same as above)
-       'quiz_msg_remind',                              "\00303Reminder: %s", # 1: question (quiz_inc_question)
-       'quiz_msg_delay',                               "\00303Delay between questions: \00304%u\00303s", # 1: time (s)
-       'quiz_msg_duration',                    "\00303Round duration: \00304%u\00303s", # 1: time (s)
-       'quiz_msg_score',                               "\00304%s\00303\002\002, you have scored \00304%d\00303 %s so far.", # 1: nick, 2: score, 3: quiz_flx_points
-       'quiz_msg_noscore',                             "\00304%s\00303\002\002, you haven't scored any point so far!", # 1: nick
-       'quiz_msg_score_other',                 "\00304%s\00303 scored \00304%d\00303 %s so far.", # see quiz_msg_score
-       'quiz_msg_noscore_other',               "\00304%s\00303 hasn't scored any point so far!", # 1: nick
-       'quiz_msg_noscores',                    "\00303Scoreboard is empty.",
-       'quiz_msg_scores',                              "\00303Quiz scores after %s and %u %s:", # 1: time_str (hms), 2: question, 3: quiz_flx_aquestions, 4: questions (total), 5: quiz_flx_fquestions (total)
-       'quiz_msg_scores_place',                "\00303%u. place: \00304%s\00303 - \00304%d\00303 %s [%.1f%%] (avg. guessing time: %10\$.3fs)", # 1: place, 2: nick, 3: score, 4: quiz_flx_points, 5: score%, 6: answers, 7: quiz_flx_answers, 8: answers%, 9: best time, 10: avg time, 11: best speed, 12: avg speed, 13: spacer
-       'quiz_msg_scores_place_full',   "\00303%u. place: \00304%s\00303 - \00304%d\00303 %s [%.1f%%] (%u %s, avg. guessing time: %10\$.3fs)", # see quiz_msg_scores_place
-       'quiz_msg_team_score',                  "\00303Team %u (%s): \00304%d\00303 %s", # 1: team, 2: players (comma separated), 3: score, 4: quiz_flx_points, 5: score%, 6: answers, 7: quiz_flx_answers, 8: answers%
-       'quiz_msg_team_score_full',             "\00303Team %u (%s): \00304%d\00303 %s (%6\$u %7\$s)", # see quiz_msg_team_score
-       'quiz_msg_team_join',                   "\00303You have joined to Team %u (%s).", # 1: team, 2: players (comma separated)
-       'quiz_inc_team_nick',                   "\00307%s\00303", # 1: nick
-       'quiz_msg_scores_times',                "\00303Fastest players (time): %s", # 1: players (comma separated)
-       'quiz_msg_scores_speeds',               "\00303Fastest players (ch/s): %s", # 1: players (comma separated)
-       'quiz_inc_scores_record',               "\00303%u. \00304%s\00303 (%.3f)", # 1: place, 2: nick, 3: time/speed record
-       'quiz_msg_congrats',                    "\00303Congrats, \00304%s\00303! You get %s for answer \00304%s\00303 given after %.3fs (%.3f chars/s) - total points: \00304%d\00303.", # 1: nick, 2: quiz_inc_got_point*, 3: answer, 4: time (ms), 5: speed (chars/s), 6: total score
-       'quiz_inc_got_points',                  "\00304%d\00303 %s", # 1: points, 2: quiz_flx_points
-       'quiz_inc_got_point',                   "\00303a %s", # 1: quiz_flx_point
-       'quiz_msg_limit',                               "\00307You've just got 50%%+1 points - let others play. ;)",
-       'quiz_inc_hours',                               '%u hr',                        # 1: hours
-       'quiz_inc_minutes',                             '%u min',                       # 1: minutes
-       'quiz_inc_seconds',                             '%u sec',                       # 1: seconds
-       'quiz_inc_seconds_ms',                  '%.3f sec',                     # 1: seconds.milliseconds
-       'quiz_msg_warn_timeout',                "\00307Warning, only \00304%u\00307s left for answering!", # 1: time (s)
-       'quiz_msg_all_answers',                 "\00303All answers were guessed!",
-       'quiz_msg_timeout',                             "\00303Timeout!",
-       'quiz_msg_next',                                "\00303Next question in %us...", # 1: time (s)
-       'quiz_msg_next_x',                              "\00303Next word in %us...", # 1: time (s)
-       'quiz_msg_last',                                "\00307No more questions!",
-       'quiz_msg_skipped',                             "\00303This question has been skipped.",
-       # 1 point / x points / 2-4, x2-x4 points (x != 1)       |       1 punkt / x punktow / 2-4, x2-x4 punkty (x != 1)
-       'quiz_flx_points',                              'point/points/points',
-       # 1 answer / x answers / 2-4, x2-x4 answers (x != 1)    |       1 odpowiedz / x odpowiedzi / 2-4, x2-x4 odpowiedzi (x != 1)
-       'quiz_flx_answers',                             'answer/answers/answers',
-       # (after) 1 question / x questions / 2-4, x2-x4 questions (x != 1)      |       (po) 1 pytaniu / x pytaniach / 2-4, x2-x4 pytaniach (x != 1)
-       'quiz_flx_aquestions',                  'question/questions/questions',
-       # (from) 1 question / x questions / 2-4, x2-x4 questions (x != 1)       |       (z) 1 pytania / x pytan / 2-4, x2-x4 pytan (x != 1)
-       'quiz_flx_fquestions',                  'question/questions/questions',
-]);
-
-##### Support routines #####
-sub load_quiz {
-       my ($fname, $lines) = (shift, 0);
-       $quiz{data} = [];
-       $quiz{qcnt} = 0;
-       return 0 unless (open(my $fh, '<', $fname));
-       while (<$fh>) {
-               s/[\n\r]//g;    # chomp is platform dependent ($/)
-               tr/\t/ /;               # tabs to spaces
-               s/ {2,}/ /g;    # fix double spaces
-               s/^ +| +$//g;   # trim leading/trailing spaces/tabs
-               next if (/^ *$/);
-               if (($quiz{type} == QT_STD) || ($quiz{type} == QT_SCR)) {
-                       if ($lines % 2) {
-                               s/^o(dp|pd) //i; # remove format (broken as well)
-                               $quiz{data}[++$quiz{qcnt}]{answer} = $_; # ++ only on complete question
-                       } else {
-                               s/^p(yt|ty) //i; # remove format (broken as well)
-                               $quiz{data}[$quiz{qcnt} + 1]{($quiz{type} == QT_STD) ? 'question' : 'realquestion'} = $_;
-                       }
-               } elsif ($quiz{type} == QT_MIX) {
-                       s/^\d+ //; # remove format
-                       $quiz{data}[++$quiz{qcnt}]{answer} = $_;
-               } elsif (($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL)) {
-                       if ($lines % 2) {
-                               s/ +\*/*/g; # fix format
-                               s/\* +/*/g; # fix format
-                               my $enum = 1;
-                               # ++ only on complete question
-                               %{$quiz{data}[++$quiz{qcnt}]{answers}} = map { $_ => $enum++ } split /\*/;
-                       } else {
-                               $quiz{data}[$quiz{qcnt} + 1]{question} = $_;
-                       }
-               }
-               $lines++;
-       }
-       close($fh);
-       return $lines;
-}
-
-sub get_format {
-       my ($format, $args) = @_;
-       return sprintf(current_theme()->get_format(__PACKAGE__, $format), ref($args) ? @{$args} : (defined($args) ? $args : ()));
-}
-
-sub send_ui {
-       my ($format, @rest) = @_;
-       printformat(MSGLEVEL_CRAP, $format, @rest);
-}
-
-sub send_ui_raw {
-       print CLIENTCRAP shift;
-}
-
-sub send_irc {
-       my (undef, undef, $instant) = @_;
-       my $msg = get_format(@_);
-       if ($quiz{chan}{server}{connected}) {
-               if ($instant) { # instant or queued
-                       $quiz{chan}{server}->send_raw_now("PRIVMSG $quiz{chan}{name} :$msg");
-               } else {
-                       $quiz{chan}{server}->send_raw("PRIVMSG $quiz{chan}{name} :$msg");
-               }
-               timeout_add_once($_display_delay, 'evt_delayed_show_msg', $msg); # le trick (workaround for chantext showing after owntext)
-       } else {
-               send_ui_raw($msg); # this helps when we got disconnected not to lose any messages (like stats)
-               send_ui('quiz_err_server');
-       }
-}
-
-sub send_irc_whisper {
-       my (undef, undef, $nick, $instant) = @_;
-       my $msg = get_format(@_);
-       if ($quiz{chan}{server}{connected}) {
-               if ($instant) { # instant or queued
-                       $quiz{chan}{server}->send_raw_now("NOTICE $nick :$msg");
-               } else {
-                       $quiz{chan}{server}->send_raw("NOTICE $nick :$msg");
-               }
-               timeout_add_once($_display_delay, 'evt_delayed_show_notc', [$msg, $nick]); # le trick (workaround for chantext showing after owntext)
-       } else {
-               send_ui_raw($msg); # this helps when we got disconnected not to lose any messages (like stats)
-               send_ui('quiz_err_server');
-       }
-}
-
-sub shuffle_text {
-       my ($old, $new, $length) = (shift, '', 0);
-       my @old = split(//, $old);
-       my @mov;
-       my $smart = ($quiz{type} == QT_SCR) ? settings_get_bool('quiz_smart_mix') : 0;
-       if ($smart) {
-               my $chars = settings_get_str('quiz_smart_mix_chars'); #? quotemeta?
-               for (my $i = 0; $i < @old; $i++) {
-                       if ($old[$i] !~ /^[$chars]$/) { # hypen, apostrophe, math symbols will float
-                               push(@mov, $i);
-                               $length++;
-                       }
-               }
-               $smart = 0 if ($length == length($old)); # no punctations & digits
-       } else {
-               $length = length($old);
-       }
-       return $old if ($length < 2); # skip short (and empty)
-       my $watchdog = ($length < $_shuffle_threshold) ? 1 : $_shuffle_watchdog;
-       do {
-               if ($smart) {
-                       my @new = @old;
-                       my @tmp = @mov;
-                       my $i = 0;
-                       while (@tmp) {
-                               $i++ while (!grep { $_ == $i } @mov);
-                               my $j = splice(@tmp, int(rand(@tmp)), 1);
-                               $new[$i++] = $old[$j];
-                       }
-                       $new = join('', @new);
-               } else {
-                       my @tmp = @old;
-                       $new = '';
-                       $new .= splice(@tmp, int(rand(@tmp)), 1) while (@tmp);
-               }
-       } until (($old ne $new) || (--$watchdog <= 0));
-       return $new;
-}
-
-sub shuffle {
-       my ($text, $style) = (shift, settings_get_int('quiz_words_style'));
-       my $keepfmt = ($quiz{type} == QT_SCR) ? 1 : settings_get_bool('quiz_words_mode');
-       if ($style == 1) {
-               $text = lc $text;
-       } elsif ($style == 2) {
-               $text = uc $text;
-       } elsif ($style == 3) {
-               $text = join(' ', map { ucfirst lc } split(/ /, $text));
-       }
-       if ($keepfmt) {
-               return join(' ', map { shuffle_text($_) } split(/ /, $text));
-       } else {
-               $text =~ s/ //g;
-               return shuffle_text($text);
-       }
-}
-
-sub antigoogle {
-       my $text = shift;
-       return $text unless (settings_get_bool('quiz_antigoogler') && ($text =~ / /));
-       return $text if ($_protect_urls && ($text =~ m<https?://|www\.>));
-       my ($fg, $bg) = (get_format('quiz_inc_question', '') =~ /^\003(\d{1,2}),(\d{1,2})/);
-       return $text unless (defined($fg) && defined($bg));
-       ($fg, $bg) = map { int } ($fg, $bg);
-       my @set = ('a'..'z', 'A'..'Z', 0..9);
-       my @h; my @v;
-       #t = \00300,01 (quiz_inc_question)
-       #h = \0031,01 \00301,01 \00301
-       #v = \0030,01 \00300,01 \00300
-       if ($bg < 10) {
-               push(@h, "\0030$bg");
-               push(@h, "\003$bg,0$bg", "\0030$bg,0$bg") if ($_randomized_antigoogler);
-       } else {
-               push(@h, "\003$bg");
-               push(@h, "\003$bg,$bg") if ($_randomized_antigoogler);
-       }
-       $bg = substr("0$bg", -2); # make sure $bg is 2-char
-       if ($fg < 10) {
-               push(@v, "\0030$fg");
-               push(@v, "\003$fg,$bg", "\0030$fg,$bg") if ($_randomized_antigoogler);
-       } else {
-               push(@v, "\003$fg");
-               push(@v, "\003$fg,$bg") if ($_randomized_antigoogler);
-       }
-       my @lines;
-       if (settings_get_bool('quiz_split_long_lines')) {
-               # very ugly, but required calculations depending on type of question
-               my $raw_crap = length(get_format('quiz_inc_question', ''));
-               my $msg_crap = $raw_crap;
-               if (!$quiz{inq}) {
-                       my $suffix = ($quiz{type} == QT_MIX) ? '_x' : ((($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL)) ? '_fm' : '');
-                       my $answers = keys %{$quiz{lookup}};
-                       my $duration = abs(settings_get_int('quiz_timeout')) || $_round_duration; # abs in case of <0, || in case of ==0
-                       $msg_crap += length(get_format('quiz_msg_question' . $suffix, [$quiz{qnum}, $quiz{qcnt}, '', $answers, answers_str($answers), $duration]));
-               } else {
-                       $msg_crap += length(get_format('quiz_msg_remind', ''));
-               }
-               my $cutoff = 497 - length($quiz{chan}{server}{nick} . $quiz{chan}{server}{userhost} . $quiz{chan}{name});
-               my @words = split(/ /, $text);
-               $text = shift(@words);
-               my ($line, $subst) = (1, 1);
-               while (@words) {
-                       my $ag = $h[int(rand(@h))] . $set[int(rand(@set))] . $v[int(rand(@v))];
-                       $ag = ' ' if ($_smarter_antigoogler && ($subst % ($_smarter_antigoogler_chunk + 1) == 0));
-                       my $word = shift(@words);
-                       if (length($text . $ag . $word) > $cutoff - (($line == 1) ? $msg_crap : $raw_crap)) {
-                               push(@lines, $text);
-                               $text = $word;
-                               $line++;
-                               $subst = 1;
-                       } else {
-                               $text .= $ag . $word;
-                               $subst++;
-                       }
-               }
-       } else {
-               if ($_smarter_antigoogler) {
-                       my @words = split(/ /, $text);
-                       $text = shift(@words);
-                       my $subst = 1;
-                       while (@words) {
-                               my $ag = $h[int(rand(@h))] . $set[int(rand(@set))] . $v[int(rand(@v))];
-                               $ag = ' ' if ($subst++ % ($_smarter_antigoogler_chunk + 1) == 0);
-                               $text .= $ag . shift(@words);
-                       }
-               } else {
-                       while ($text =~ / /) {
-                               my $ag = $h[int(rand(@h))] . $set[int(rand(@set))] . $v[int(rand(@v))];
-                               $text =~ s/ /$ag/; # one by one, not /g
-                       }
-               }
-       }
-       push(@lines, $text);
-       return @lines;
-}
-
-sub put_dots {
-       my ($hint, $format, $setting, $default, $marker) = @_;
-       my $char = settings_get_str($setting); #? substr(settings_get_str($setting), 0, 1)
-       my $dot = get_format($format, ($char eq '') ? $default : $char);
-       $hint =~ s/$marker/$dot/g; # le trick grande finale
-       my ($scol, $ecol) = ($dot =~ /^(\003\d{1,2}(?:,\d{1,2})?).(\003\d{1,2}(?:,\d{1,2})?)$/);
-       if (defined($scol) && defined($ecol)) {
-               $hint =~ s/$ecol $scol/ /g; # optimize color codes
-               $hint =~ s/$ecol$scol//g;
-               $hint =~ s/$ecol$//;
-       }
-       return $hint;
-}
-
-sub make_hint {
-       my $dots_only = shift;
-       my @words = split(/ /, $quiz{data}[$quiz{qnum}]{answer});
-       if (!@{$quiz{dots}}) { # make first dots
-               @quiz{qw/dcnt dmax/} = (0) x 2;
-               $quiz{hwords} = [];
-               my ($w, $dmax) = (0) x 2;
-               foreach my $word (@words) {
-                       my ($l, $hword, $dcnt) = (0, '', 0);
-                       foreach my $letter (split(//, $word)) {
-                               if ($letter =~ /^[a-z0-9]$/i) {
-                                       push(@{$quiz{dots}[$w]}, $l);
-                                       $hword .= ($letter =~ /^[0-9]$/) ? "\002" : "\001"; # le trick (any ASCII non-printable char)
-                                       $quiz{dcnt}++;
-                                       $dcnt++;
-                               } else {
-                                       $hword .= $letter;
-                               }
-                               $l++;
-                       }
-                       push(@{$quiz{hwords}}, $hword);
-                       $dmax = $dcnt if ($dcnt > $dmax);
-                       $w++;
-               }
-               $quiz{dmax} = $dmax;
-       }
-       return '' if ($dots_only); # prep dots only
-       $quiz{hnum}++;
-       my $first_dots = settings_get_bool('quiz_first_hint_dots');
-       if (!$first_dots || ($quiz{hnum} > 1)) { # reveal some dots
-               my $random_hints = settings_get_bool('quiz_random_hints');
-               my $random_but_first = settings_get_bool('quiz_nonrandom_first_hint') && ($quiz{hnum} == ($first_dots ? 2 : 1));
-               my ($w, $dmax) = (0) x 2;
-               foreach my $r_wdots (@{$quiz{dots}}) {
-                       if ((ref $r_wdots) && (@$r_wdots > 0)) {
-                               my @letters = split(//, $words[$w]);
-                               my @hletters = split(//, $quiz{hwords}[$w]);
-                               my $sel = (!$random_hints || $random_but_first) ? 0 : int(rand(@$r_wdots));
-                               $hletters[@$r_wdots[$sel]] = $letters[@$r_wdots[$sel]];
-                               $quiz{hwords}[$w] = join('', @hletters);
-                               splice(@$r_wdots, $sel, 1);
-                               $quiz{dcnt}--;
-                               $dmax = @$r_wdots if (@$r_wdots > $dmax);
-                       }
-                       $w++;
-               }
-               $quiz{dmax} = $dmax;
-       }
-       my $hint = join(' ', @{$quiz{hwords}});
-       $hint = put_dots($hint, 'quiz_inc_hint_alpha', 'quiz_hint_alpha', $_hint_alpha, "\001");
-       $hint = put_dots($hint, 'quiz_inc_hint_digit', 'quiz_hint_digit', $_hint_digit, "\002");
-       return $hint;
-}
-
-sub make_remind {
-       if (!$quiz{inq} || settings_get_bool('quiz_mix_on_remind')) {
-               if ($quiz{type} == QT_SCR) {
-                       $quiz{data}[$quiz{qnum}]{question} = shuffle($quiz{data}[$quiz{qnum}]{realquestion});
-               } elsif ($quiz{type} == QT_MIX) {
-                       $quiz{data}[$quiz{qnum}]{question} = shuffle($quiz{data}[$quiz{qnum}]{answer});
-               }
-       }
-       return antigoogle($quiz{data}[$quiz{qnum}]{question});
-}
-
-sub time_str {
-       my ($s, $mode) = @_;
-       my ($h, $m) = (0) x 2;
-       if ($mode == T_HMS) {
-               $h = int($s / 3600);
-               $m = int($s / 60) % 60;
-               $s %= 60;
-       }
-       my $str = '';
-       $str .= get_format('quiz_inc_hours', $h) . ' ' if ($h);
-       $str .= get_format('quiz_inc_minutes', $m) . ' ' if ($m);
-       $str .= get_format('quiz_inc_seconds' . (($mode == T_MS) ? '_ms' : ''), $s) if ($s || (!$h && !$m));
-       $str =~ s/ $//;
-       return $str;
-}
-
-sub flex {
-       my ($value, $format, $flex) = (abs(shift), shift, 0);
-       my @flex = split(/$_flex_separator/, get_format($format));
-       if ($value != 1) {
-               $flex++;
-               $flex++ if ($value =~ /^[2-4]$|[^1][2-4]$/);
-       }
-       return defined($flex[$flex]) ? $flex[$flex] : '???'; # just a precaution when user messes up
-}
-
-sub score_str          { return flex(shift, 'quiz_flx_points'); }              # X points
-sub answers_str                { return flex(shift, 'quiz_flx_answers'); }             # X answers
-sub aquestions_str     { return flex(shift, 'quiz_flx_aquestions'); }  # after X questions <- AFTER!
-sub fquestions_str     { return flex(shift, 'quiz_flx_fquestions'); }  # from X questions <- FROM!
-
-sub percents {
-       my ($val, $of) = @_;
-       return ($of == 0) ? 0 : $val / $of * 100;
-}
-
-sub stop_timer {
-       my $timer = shift;
-       if ($quiz{$timer}) {
-               timeout_remove($quiz{$timer});
-               $quiz{$timer} = undef;
-       }
-}
-
-sub stop_question {
-       @quiz{qw/inq hnum hprot rprot dcnt dmax/} = (0) x 6;
-       stop_timer($_) foreach (qw/tround thint thinter tremind twarn/);
-       $quiz{dots} = [];
-       $quiz{hwords} = [];
-       $quiz{lookup} = {};
-}
-
-sub stop_quiz {
-       stop_question();
-       @quiz{qw/ison standby ended/} = (0) x 3;
-       stop_timer('tnext');
-       signal_remove('message public', 'sig_pubmsg');
-}
-
-sub init_first_question {
-       my $delay = shift;
-       if ($delay > 0) {
-               $quiz{tnext} = timeout_add_once($delay, 'evt_next_question', undef);
-       } else {
-               evt_next_question();
-       }
-}
-
-sub init_next_question {
-       my ($msg, $instant) = @_;
-       if ($quiz{qnum} >= $quiz{qcnt}) {
-               send_irc('quiz_msg', $msg . ' ' . get_format('quiz_msg_last'), $instant);
-               $quiz{ended} = 1;
-       } else {
-               my $delay;
-               if (($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL)) {
-                       $delay = abs(settings_get_int('quiz_delay_long')) || $_next_delay_long; # abs in case of <0, || in case of ==0
-               } else {
-                       $delay = abs(settings_get_int('quiz_delay')) || $_next_delay; # abs in case of <0, || in case of ==0
-               }
-               send_irc('quiz_msg', $msg . ' ' . get_format('quiz_msg_next' . (($quiz{type} == QT_MIX) ? '_x' : ''), $delay), $instant);
-               $quiz{tnext} = timeout_add_once($delay * 1000, 'evt_next_question', undef);
-       }
-}
-
-sub name_to_type {
-       my ($name, $type) = (shift, undef);
-       return $name if ($name =~ /^\d+$/);
-       my %type = (diz => 1, std => 1, sta => 1, nrm => 1, nor => 1, zwy => 1,
-                               mie => 2, mix => 2, lit => 2,
-                               fam => 3, dru => 3, tea => 3,
-                               mul => 4, all => 4, wsz => 4, bez => 4,
-                               pom => 5, scr => 5);
-       foreach my $key (keys %type) {
-               $type = $type{$key}, last if (lc($name) =~ /^$key/i);
-       }
-       return $type;
-}
-
-sub is_valid_data {
-       return (($quiz{qcnt} < 1) ||
-               ((($quiz{type} == QT_STD) || ($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL) ||
-               ($quiz{type} == QT_SCR)) && ($quiz{qcnt} * 2 != shift))) ? 0 : 1;
-}
-
-sub correct_answer {
-       my ($addr, $nick, $timestamp, $points, $answer) = @_;
-       @{$quiz{players}{$addr}}{qw/besttime bestspeed/} = (0) x 2 if (!exists $quiz{players}{$addr});
-       @{$quiz{players}{$addr}}{qw/nick timestamp/} = ($nick, $timestamp);
-       my $time = $timestamp - $quiz{qtime};
-       my $speed = length($answer) / $time;
-       $quiz{players}{$addr}{alltime} += $time;
-       $quiz{players}{$addr}{allspeed} += $speed;
-       $quiz{players}{$addr}{besttime} = $time if (($quiz{players}{$addr}{besttime} == 0) || ($quiz{players}{$addr}{besttime} > $time));
-       $quiz{players}{$addr}{bestspeed} = $speed if (($quiz{players}{$addr}{bestspeed} == 0) || ($quiz{players}{$addr}{bestspeed} < $speed));
-       $quiz{players}{$addr}{score} += $points;
-       $quiz{players}{$addr}{answers}++;
-       $quiz{score} += $points;
-       $quiz{answers}++;
-       if ($quiz{type} == QT_FAM) {
-               $quiz{players}{$addr}{team} = 0 if (!exists $quiz{players}{$addr}{team}); # team_play is on and player is an outsider
-               my $team = $quiz{players}{$addr}{team};
-               $quiz{teams}[$team]{score} += $points;
-               $quiz{teams}[$team]{answers}++;
-       }
-}
-
-sub hcmd {
-       return sprintf(' %-38s - ', shift);
-}
-
-sub hvar {
-       my ($setting, $type) = @_;
-       if ($type == V_INT) {
-               return sprintf(' %-26s : %-3d - ', $setting, settings_get_int($setting));
-       } elsif ($type == V_BOOL) {
-               return sprintf(' %-26s : %-3s - ', $setting, settings_get_bool($setting) ? 'on' : 'off');
-       } elsif ($type == V_STR) {
-               return sprintf(' %-26s : %-3s - ', $setting, settings_get_str($setting));
-       }
-}
-
-sub show_help {
-       my $type = settings_get_int('quiz_type');
-       send_ui_raw("%_$IRSSI{name}%_ v$VERSION by wilk (quiz currently: " . ($quiz{ison} ? ($quiz{standby} ? 'is on standby' : ($quiz{ended} ? 'has finished' : 'is running')) : 'is off') . ')');
-       send_ui_raw('%_Available commands:%_');
-       send_ui_raw(hcmd("/qtype [1-$_quiz_types/name]") . 'change quiz type (see quiz_type)');
-       if ($type == QT_FAM) {
-               send_ui_raw(hcmd("/qteams <2-$_max_teams>") . 'change number of teams');
-               send_ui_raw(hcmd("/qon [channel] <file> [1-$_quiz_types/name] [0-$_max_teams]") . 'start the quiz; you can give its type and number of teams');
-               send_ui_raw(hcmd('/qstats [places]') . 'display scoreboard (0: teams only)');
-       } else {
-               send_ui_raw(hcmd("/qon [channel] <file> [1-$_quiz_types/name]") . 'start the quiz; you can give its type');
-               send_ui_raw(hcmd('/qstats [places]') . 'display scoreboard');
-       }
-       send_ui_raw(hcmd('/qhint') . 'show next hint') if (($type != QT_FAM) && ($type != QT_MUL));
-       send_ui_raw(hcmd('/qremind') . 'remind a question');
-       send_ui_raw(hcmd('/qskip') . 'skip current question');
-       send_ui_raw(hcmd('/qoff') . 'stop the quiz');
-       send_ui_raw(hcmd('/qdelay <seconds>') . 'change delay between questions');
-       send_ui_raw(hcmd('/qtime <seconds>') . 'change round duration') if (($type == QT_FAM) || ($type == QT_MUL));
-       send_ui_raw(hcmd('/qreload') . 'reload questions from file');
-       send_ui_raw(hcmd('/qinit') . 'reset settings to defaults');
-       send_ui_raw('%_Available settings (/set):%_');
-       send_ui_raw(hvar('quiz_type', V_INT) . 'quiz type (1: Dizzy, 2: Mieszacz/Literaki, 3: Familiada, 4: Multi (Familiada w/o teams), 5: Pomieszany)');
-       send_ui_raw(hvar('quiz_teams', V_INT) . "number of teams (2-$_max_teams)") if ($type == QT_FAM);
-       send_ui_raw(hvar('quiz_delay', V_INT) . 'delay between questions (sec)');
-       if (($type == QT_FAM) || ($type == QT_MUL)) {
-               send_ui_raw(hvar('quiz_delay_long', V_INT) . 'delay between questions (sec)');
-               send_ui_raw(hvar('quiz_timeout', V_INT) . 'round duration (sec)');
-       } else {
-               send_ui_raw(hvar('quiz_max_hints', V_INT) . 'max. number of hints (0: no limit, >0: number of hints, <0: number of hidden chars)');
-               send_ui_raw(hvar('quiz_autohinter', V_BOOL) . 'show automatic hints?');
-               send_ui_raw(hvar('quiz_hints_interval', V_INT) . 'automatic hints interval (sec)');
-       }
-       send_ui_raw(hvar('quiz_words_style', V_INT) . 'word\'s style (0: no change, 1: l-case, 2: U-case, 3: Caps)') if (($type == QT_MIX) || ($type == QT_SCR));
-       send_ui_raw(hvar('quiz_antigoogler', V_BOOL) . 'mask questions with antigoogler?');
-       send_ui_raw(hvar('quiz_split_long_lines', V_BOOL) . 'split long lines?');
-       send_ui_raw(hvar('quiz_anticheat_delay', V_INT) . '!hint/!remind protection delay (sec; 0: wylaczone)');
-       send_ui_raw(hvar('quiz_first_anticheat_delay', V_INT) . 'first !hint/!remind protection delay (sec; 0: wylaczone)');
-       if (($type != QT_FAM) && ($type != QT_MUL)) {
-               send_ui_raw(hvar('quiz_show_first_hint', V_BOOL) . 'show questions along with first hint?');
-               send_ui_raw(hvar('quiz_first_hint_dots', V_BOOL) . 'first hint as dots only?');
-               send_ui_raw(hvar('quiz_random_hints', V_BOOL) . 'reveal random chars in hints? otherwise left to right');
-               send_ui_raw(hvar('quiz_nonrandom_first_hint', V_BOOL) . 'reveal random chars in hints, except first hint?');
-               send_ui_raw(hvar('quiz_hint_alpha', V_STR) . 'character substitution in place of letters');
-               send_ui_raw(hvar('quiz_hint_digit', V_STR) . 'character substitution in place of digits');
-       }
-       send_ui_raw(hvar('quiz_words_mode', V_BOOL) . 'scramble with word separation? otherwise all together') if ($type == QT_MIX);
-       if ($type == QT_SCR) {
-               send_ui_raw(hvar('quiz_smart_mix', V_BOOL) . 'anchor some characters?');
-               send_ui_raw(hvar('quiz_smart_mix_chars', V_STR) . 'anchor these characters (regex)');
-       }
-       send_ui_raw(hvar('quiz_mix_on_remind', V_BOOL) . 'scramble letters with each !remind?') if (($type == QT_MIX) || ($type == QT_SCR));
-       if ($type == QT_FAM) {
-               send_ui_raw(hvar('quiz_join_anytime', V_BOOL) . 'allow joining teams at any time?');
-               send_ui_raw(hvar('quiz_team_play', V_BOOL) . 'allow only team players to answer?');
-               send_ui_raw(hvar('quiz_transfer_points', V_BOOL) . 'transfer scores when player changes teams?');
-       }
-       send_ui_raw(hvar('quiz_strict_match', V_BOOL) . 'allow only strict answers? or allow *matching*') if (($type != QT_FAM) && ($type != QT_MUL));
-       send_ui_raw(hvar('quiz_points_per_answer', V_INT) . 'points per answer');
-       if (($type == QT_FAM) || ($type == QT_MUL)) {
-               send_ui_raw(hvar('quiz_min_points', V_INT) . 'min. points');
-               send_ui_raw(hvar('quiz_max_points', V_INT) . 'max. points');
-               send_ui_raw(hvar('quiz_scoring_mode', V_INT) . 'scoring mode (1: ppa, 2: ppa++, 3: ppa++:max, 4: min++ppa, 5: min++ppa:max, 6: max--ppa:min, 7: max->min');
-       } else {
-               send_ui_raw(hvar('quiz_limiter', V_BOOL) . 'limit best person scores to 50%+1 points?');
-       }
-       send_ui_raw(hvar('quiz_ranking_type', V_INT) . 'ranking type (1: ordinal "1234", 2: dense "1223", 3: competition "1224")');
-       send_ui_raw(hvar('quiz_keep_scores', V_BOOL) . 'keep scores between quizes?');
-       send_ui_raw(hvar('quiz_keep_teams', V_BOOL) . 'keep chosen teams?') if ($type == QT_FAM);
-       send_ui_raw(hvar('quiz_cmd_hint', V_BOOL) . '!hint command is enabled?');
-       send_ui_raw(hvar('quiz_cmd_remind', V_BOOL) . '!remind command is enabled?');
-}
-
-##### Commands' handlers #####
-sub cmd_start {
-       if ($quiz{standby}) {
-               $quiz{standby} = 0;
-               init_first_question($_standby_delay);
-               return;
-       }
-       send_ui('quiz_err_ison'), return if ($quiz{ison});
-       my ($args, $r_server, $window) = @_;
-       send_ui('quiz_err_server'), return if (!$r_server || !$r_server->{connected});
-       my ($chan, $file, $type, $teams) = split(/ /, $args);
-       ($file, $chan) = ($chan, active_win()->{active}->{name}) if (!defined $file); # single arg call
-       send_ui('quiz_err_channel'), return if (!$chan || !$r_server->ischannel($chan));
-       {
-               { package Irssi::Nick; } # should prevent irssi bug: "Can't locate package Irssi::Nick for @Irssi::Irc::Nick::ISA at ..."
-               $quiz{chan} = $r_server->channel_find($chan);
-       }
-       send_ui('quiz_err_nochannel', $chan), return if (!$quiz{chan});
-       $file = (glob $file)[0]; # open() does not support "~"
-       send_ui('quiz_err_filename'), return if (!$file);
-       send_ui('quiz_err_nofile', $file), return if (!-e $file);
-       $type = defined($type) ? name_to_type($type) : settings_get_int('quiz_type');
-       send_ui('quiz_err_type'), return if (!$type || ($type < 0) || ($type > $_quiz_types));
-       if (defined $teams) {
-               send_ui('quiz_err_type'), return if (($type != QT_FAM) && ($type != QT_MUL));
-               if (($type == QT_MUL) && ($teams >= 2)) {
-                       $type = QT_FAM;
-               } elsif (($type == QT_FAM) && ($teams < 2)) {
-                       $type = QT_MUL;
-               }
-       } else {
-               $teams = settings_get_int('quiz_teams');
-       }
-       send_ui('quiz_err_teams'), return if (($type == QT_FAM) && (($teams !~ /^\d+$/) || ($teams < 2) || ($teams > $_max_teams)));
-       settings_set_int('quiz_type', $type);
-       settings_set_int('quiz_teams', $teams) if ($teams >= 2);
-       @quiz{qw/type tcnt file/} = ($type, $teams, $file);
-       my $lines = load_quiz($file);
-       send_ui('quiz_err_file', $file), return if (!is_valid_data($lines));
-       if (!settings_get_bool('quiz_keep_scores')) {
-               $quiz{players} = {};
-               $quiz{teams} = [];
-               @quiz{qw/score answers/} = (0) x 2;
-       } else {
-               if (!settings_get_bool('quiz_keep_teams') && ($type == QT_FAM)) {
-                       delete $quiz{players}{$_}{team} for (keys %{$quiz{players}});
-               }
-       }
-       send_irc('quiz_msg_start1', INSTANT);
-       send_irc('quiz_msg_start2' . (($type == QT_FAM) ? '_f' : (($type == QT_MUL) ? '_m' : '')), $teams, INSTANT);
-       @quiz{qw/stime ison/} = (time(), 1);
-       @quiz{qw/qnum inq ended/} = (0) x 3;
-       if ($type == QT_FAM) {
-               $quiz{standby} = 1;
-               @{$quiz{teams}[$_]}{qw/score answers/} = (0) x 2 for (0 .. $teams);
-       } else {
-               $quiz{standby} = 0;
-               init_first_question($_start_delay);
-       }
-       signal_add_last('message public', 'sig_pubmsg');
-}
-
-sub cmd_stats {
-       send_ui('quiz_err_isoff'), return if (($quiz{score} == 0) && !$quiz{ison});
-       send_ui('quiz_err_nochannel'), return if (!$quiz{chan});
-       my $num = shift;
-       send_ui('quiz_err_ranking'), return if (($num ne '') && ($num !~ /^\d+$/));
-       $num = -1 if ($num eq '');
-       send_irc('quiz_msg_noscores'), return if (!keys %{$quiz{players}});
-       my $qnum = $quiz{qnum};
-       $qnum-- if ($quiz{inq});
-       send_irc('quiz_msg_scores', [
-               time_str(time() - $quiz{stime}, T_HMS),
-               $qnum, aquestions_str($qnum),
-               $quiz{qcnt}, fquestions_str($quiz{qcnt})]) if (!$quiz{standby});
-       my $suffix = '';
-       $suffix = '_full' if ((settings_get_int('quiz_points_per_answer') != 1) ||
-               ((($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL)) && (settings_get_int('quiz_scoring_mode') != 1)));
-       if ($quiz{type} == QT_FAM) {
-               my @teams;
-               push(@{$teams[$quiz{players}{$_}{team}]}, get_format('quiz_inc_team_nick', $quiz{players}{$_}{nick})) for (sort { $quiz{players}{$a}{joined} <=> $quiz{players}{$b}{joined} } keys %{$quiz{players}});
-               foreach my $team (1 .. $quiz{tcnt}) {
-                       my ($score, $answers) = @{$quiz{teams}[$team]}{qw/score answers/};
-                       send_irc('quiz_msg_team_score' . $suffix, [
-                               $team,
-                               (!defined $teams[$team]) ? '' : join($_team_separator, @{$teams[$team]}),
-                               $score, score_str($score), percents($score, $quiz{score}),
-                               $answers, answers_str($answers), percents($answers, $quiz{answers})]);
-               }
-       }
-       return if ($quiz{standby} || (($num == 0) && ($quiz{type} == QT_FAM)));
-       my ($rank, $place, $exaequo, $prev, $ranking) = (0, 1, 0, undef, settings_get_int('quiz_ranking_type'));
-       $ranking = (($ranking < 1) || ($ranking > 3)) ? 1 : $ranking;
-       foreach my $player (sort {
-                                               $quiz{players}{$b}{score} <=> $quiz{players}{$a}{score} or
-                                               $quiz{players}{$b}{answers} <=> $quiz{players}{$a}{answers} or
-                                               $quiz{players}{$a}{timestamp} <=> $quiz{players}{$b}{timestamp}
-                                       } keys %{$quiz{players}}) {
-               my ($score, $answers) = @{$quiz{players}{$player}}{qw/score answers/};
-               if (!defined($prev) || ($ranking == 1) || ($score != $prev)) { # 1234
-                       $rank += 1 + $exaequo;
-                       $exaequo = 0;
-                       $prev = $score;
-               } else {
-                       if ($ranking == 3) { # 1224
-                               $exaequo++;
-                       } elsif ($ranking == 2) { # 1223
-                               # nop
-                       } else { # 1234 / fallback
-                               $rank++;
-                       }
-               }
-               last if ($_qstats_ranks && ($num > 0) && ($rank > $num));
-               send_irc('quiz_msg_scores_place' . $suffix, [
-                       $rank,
-                       $quiz{players}{$player}{nick},
-                       $score, score_str($score), percents($score, $quiz{score}),
-                       $answers, answers_str($answers), percents($answers, $quiz{answers}),
-                       $quiz{players}{$player}{besttime}, ($answers > 0) ? $quiz{players}{$player}{alltime} / $answers : 0,
-                       $quiz{players}{$player}{bestspeed}, ($answers > 0) ? $quiz{players}{$player}{allspeed} / $answers : 0,
-                       ($rank < 10) ? ' ' : '']);
-               last if (!$_qstats_ranks && ($place == $num));
-               $place++;
-       }
-       return if ($num != -1);
-       $place = 1;
-       my @nicks;
-       foreach my $player (sort {
-                                               $quiz{players}{$a}{besttime} <=> $quiz{players}{$b}{besttime} or
-                                               $quiz{players}{$a}{timestamp} <=> $quiz{players}{$b}{timestamp}
-                                       } keys %{$quiz{players}}) {
-               push(@nicks, get_format('quiz_inc_scores_record', [$place, $quiz{players}{$player}{nick}, $quiz{players}{$player}{besttime}]));
-               last if (++$place > $_qstats_records);
-       }
-       send_irc('quiz_msg_scores_times', join(', ', @nicks)) if (@nicks);
-       $place = 1;
-       @nicks = ();
-       foreach my $player (sort {
-                                               $quiz{players}{$b}{bestspeed} <=> $quiz{players}{$a}{bestspeed} or
-                                               $quiz{players}{$a}{timestamp} <=> $quiz{players}{$b}{timestamp}
-                                       } keys %{$quiz{players}}) {
-               push(@nicks, get_format('quiz_inc_scores_record', [$place, $quiz{players}{$player}{nick}, $quiz{players}{$player}{bestspeed}]));
-               last if (++$place > $_qstats_records);
-       }
-       send_irc('quiz_msg_scores_speeds', join(', ', @nicks)) if (@nicks);
-}
-
-sub cmd_delay {
-       my $delay = shift;
-       send_ui('quiz_err_delay'), return if (($delay !~ /^\d+$/) || ($delay < 1));
-       my $type = $quiz{ison} ? $quiz{type} : settings_get_int('quiz_type');
-       settings_set_int('quiz_delay' . ((($type == QT_FAM) || ($type == QT_MUL)) ? '_long' : ''), $delay);
-       send_irc('quiz_msg_delay', $delay) if ($quiz{ison});
-       send_ui('quiz_inf_delay', $delay);
-}
-
-sub cmd_time {
-       my $duration = shift;
-       #? send_ui('quiz_err_na'), return if (($quiz{type} != QT_FAM) && ($quiz{type} != QT_MUL));
-       send_ui('quiz_err_duration'), return if (($duration !~ /^\d+$/) || ($duration < 1));
-       settings_set_int('quiz_timeout', $duration);
-       send_irc('quiz_msg_duration', $duration) if ($quiz{ison});
-       send_ui('quiz_inf_duration', $duration);
-}
-
-sub cmd_teams {
-       my $teams = shift;
-       #? send_ui('quiz_err_na'), return if (($quiz{type} != QT_FAM) && ($quiz{type} != QT_MUL));
-       send_ui('quiz_err_ison'), return if ($quiz{ison});
-       send_ui('quiz_err_teams'), return if (($teams !~ /^\d+$/) || ($teams < 2) || ($teams > $_max_teams));
-       settings_set_int('quiz_teams', $teams);
-       send_ui('quiz_inf_teams', $teams);
-}
-
-sub cmd_type {
-       send_ui('quiz_err_ison'), return if ($quiz{ison});
-       my $type = shift;
-       if ($type ne '') {
-               $type = name_to_type($type);
-               send_ui('quiz_err_type'), return if (!$type || ($type < 1) || ($type > $_quiz_types));
-       } else {
-               $type = (settings_get_int('quiz_type') % $_quiz_types) + 1;
-       }
-       settings_set_int('quiz_type', $type);
-       send_ui('quiz_inf_type', ('Dizzy', 'Mieszacz/Literaki', 'Familiada', 'Multi (Familiada bez druzyn)', 'Pomieszany')[$type - 1]);
-}
-
-sub cmd_skip {
-       send_ui('quiz_err_isoff'), return if (!$quiz{ison});
-       send_ui('quiz_err_noquestion'), return if (!$quiz{inq});
-       stop_question();
-       init_next_question(get_format('quiz_msg_skipped'));
-}
-
-sub cmd_hint {
-       send_ui('quiz_err_isoff'), return if (!$quiz{ison});
-       send_ui('quiz_err_na'), return if (($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL));
-       send_ui('quiz_err_noquestion'), return if (!$quiz{inq});
-       send_irc('quiz_msg_hint', make_hint());
-}
-
-sub cmd_remind {
-       send_ui('quiz_err_isoff'), return if (!$quiz{ison});
-       send_ui('quiz_err_na'), return if (($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL));
-       send_ui('quiz_err_noquestion'), return if (!$quiz{inq});
-       my @lines = make_remind();
-       my $line = 1;
-       foreach my $text (@lines) {
-               if ($line++ == 1) {
-                       send_irc('quiz_msg_remind', get_format('quiz_inc_question', $text));
-               } else {
-                       send_irc('quiz_inc_question', $text);
-               }
-       }
-}
-
-sub cmd_stop {
-       send_ui('quiz_err_isoff'), return if (!$quiz{ison});
-       stop_quiz();
-       send_irc('quiz_msg_stop1');
-       send_irc('quiz_msg_stop2', [$quiz{qnum}, time_str(time() - $quiz{stime}, T_HMS)]);
-}
-
-sub cmd_init {
-       settings_set_int($_, $settings_int{$_}) for (keys %settings_int);
-       settings_set_bool($_, $settings_bool{$_}) for (keys %settings_bool);
-       settings_set_str($_, $settings_str{$_}) for (keys %settings_str);
-       send_ui('quiz_inf_reset');
-}
-
-sub cmd_reload {
-       send_ui('quiz_err_isoff'), return if (!$quiz{ison});
-       my $cnt = $quiz{qcnt};
-       my $lines = load_quiz($quiz{file});
-       if (is_valid_data($lines)) {
-               send_ui(($quiz{qcnt} != $cnt) ? 'quiz_wrn_reload' : 'quiz_inf_reload');
-               if ((($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL)) && $quiz{inq}) {
-                       %{$quiz{lookup}} = map { lc($_) => $_ } keys %{$quiz{data}[$quiz{qnum}]{answers}};
-               }
-       } else {
-               stop_quiz();
-               send_irc('quiz_msg_stop1');
-               send_irc('quiz_msg_stop2', [$quiz{qnum}, time_str(time() - $quiz{stime}, T_HMS)]);
-               send_ui('quiz_err_file', $quiz{file});
-       }
-}
-
-sub cmd_help {
-       show_help();
-}
-
-sub cmd_irssi_help {
-       my $cmd = shift;
-       if ($cmd =~ /^i?quiz$/) {
-               show_help();
-               signal_stop();
-       }
-}
-
-##### Timers' events #####
-sub evt_delayed_show_msg {
-       my ($msg) = @_;
-       signal_emit('message own_public', $quiz{chan}{server}, $msg, $quiz{chan}{name});
-}
-
-sub evt_delayed_show_notc {
-       my $ref = shift;
-       my ($msg, $nick) = @{$ref};
-       signal_emit('message irc own_notice', $quiz{chan}{server}, $msg, $nick);
-}
-
-sub evt_delayed_load_info {
-       send_ui('quiz_inf_start');
-}
-
-sub evt_next_question {
-       $quiz{qtime} = time();
-       $quiz{qnum}++;
-       my $suffix = '';
-       if ($quiz{type} == QT_MIX) {
-               $suffix = '_x';
-       } elsif (($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL)) {
-               %{$quiz{lookup}} = map { lc($_) => $_ } keys %{$quiz{data}[$quiz{qnum}]{answers}};
-               $suffix = '_fm';
-       }
-       my $duration = abs(settings_get_int('quiz_timeout')) || $_round_duration; # abs in case of <0, || in case of ==0
-       my @lines = make_remind();
-       my $line = 1;
-       foreach my $text (@lines) {
-               if ($line++ == 1) {
-                       my $answers = keys %{$quiz{lookup}};
-                       send_irc('quiz_msg_question' . $suffix, [
-                               $quiz{qnum}, $quiz{qcnt},
-                               get_format('quiz_inc_question', $text),
-                               $answers, answers_str($answers),
-                               $duration], INSTANT);
-               } else {
-                       send_irc('quiz_inc_question', $text, INSTANT); #? not INSTANT?
-               }
-       }
-       if (($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL)) {
-               $quiz{tround} = timeout_add_once($duration * 1000, 'evt_round_timeout', undef);
-               if (($_round_warn_time > 0) && ($duration > $_round_warn_time * $_round_warn_coeff)) {
-                       $quiz{twarn} = timeout_add_once(($duration - $_round_warn_time) * 1000, 'evt_round_timeout_warn', undef);
-               }
-       } else {
-               send_irc('quiz_msg_hint', make_hint()) if (settings_get_bool('quiz_show_first_hint'));
-               my $delay = settings_get_int('quiz_first_anticheat_delay');
-               if ($delay > 0) {
-                       $quiz{hprot} = 1;
-                       $quiz{thint} = timeout_add_once($delay * 1000, sub { $quiz{hprot} = 0 }, undef);
-                       if ((($quiz{type} == QT_MIX) || ($quiz{type} == QT_SCR)) && settings_get_bool('quiz_mix_on_remind')) {
-                               $quiz{rprot} = 1;
-                               $quiz{tremind} = timeout_add_once($delay * 1000, sub { $quiz{rprot} = 0 }, undef);
-                       }
-               }
-               if (settings_get_bool('quiz_autohinter')) {
-                       $delay = abs(settings_get_int('quiz_hints_interval')) || $_hints_interval; # abs in case of <0, || in case of ==0
-                       $quiz{thinter} = timeout_add_once($delay * 1000, 'evt_show_hint', undef);
-               }
-       }
-       $quiz{inq} = 1;
-}
-
-sub evt_round_timeout_warn {
-       send_irc('quiz_msg_warn_timeout', $_round_warn_time);
-}
-
-sub evt_round_timeout {
-       stop_question();
-       init_next_question(get_format('quiz_msg_timeout')); #? INSTANT?
-}
-
-sub evt_show_hint {
-       show_hint();
-}
-
-##### User interaction - responses / handlers #####
-sub show_score {
-       my ($nick, $addr, $who) = @_;
-       if ($who && (lc($nick) ne lc($who))) {
-               my $found = 0;
-               foreach my $player (keys %{$quiz{players}}) {
-                       if (lc($quiz{players}{$player}{nick}) eq lc($who)) {
-                               send_irc('quiz_msg_score_other', [$quiz{players}{$player}{nick}, $quiz{players}{$player}{score}, score_str($quiz{players}{$player}{score})]);
-                               $found++;
-                               last;
-                       }
-               }
-               send_irc('quiz_msg_noscore_other', $who) if (!$found);
-       } else {
-               if (exists $quiz{players}{$addr}) {
-                       send_irc('quiz_msg_score', [$nick, $quiz{players}{$addr}{score}, score_str($quiz{players}{$addr}{score})]);
-               } else {
-                       send_irc('quiz_msg_noscore', $nick);
-               }
-       }
-}
-
-sub join_team {
-       my ($nick, $addr, $team) = @_;
-       return unless (($quiz{type} == QT_FAM) && (settings_get_bool('quiz_join_anytime') || $quiz{standby}));
-       return if (($team < 1) || ($team > $quiz{tcnt}));
-       my $time = time();
-       if (exists $quiz{players}{$addr}) {
-               if (settings_get_bool('quiz_transfer_points')) {
-                       my ($score, $answers) = @{$quiz{players}{$addr}}{qw/score answers/};
-                       if (exists($quiz{players}{$addr}{team}) && ($quiz{players}{$addr}{team} != 0)) { # not an outsider
-                               my $from = $quiz{players}{$addr}{team};
-                               $quiz{teams}[$from]{score} -= $score;
-                               $quiz{teams}[$from]{answers} -= $answers;
-                       }
-                       $quiz{teams}[$team]{score} += $score;
-                       $quiz{teams}[$team]{answers} += $answers;
-               }
-       } else {
-               @{$quiz{players}{$addr}}{qw/nick timestamp/} = ($nick, $time);
-               @{$quiz{players}{$addr}}{qw/score answers besttime alltime bestspeed allspeed/} = (0) x 6;
-       }
-       @{$quiz{players}{$addr}}{qw/team joined/} = ($team, $time);
-       my @teams;
-       push(@{$teams[$quiz{players}{$_}{team}]}, get_format('quiz_inc_team_nick', $quiz{players}{$_}{nick})) for (sort { $quiz{players}{$a}{joined} <=> $quiz{players}{$b}{joined} } keys %{$quiz{players}});
-       send_irc_whisper('quiz_msg_team_join', [$team, join($_team_separator, @{$teams[$team]})], $nick) if (defined $teams[$team]);
-}
-
-sub show_hint {
-       return if ($quiz{hprot} || ($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL) || !settings_get_bool('quiz_cmd_hint'));
-       my $hints_limit = settings_get_int('quiz_max_hints');
-       make_hint(PREPDOTS) if (($quiz{hnum} == 0) && ($hints_limit < 0));
-       return unless (($quiz{hnum} == 0) || !$_no_hints_spam || ($quiz{dcnt} > 0));
-       if (($hints_limit == 0) ||
-               (($hints_limit > 0) && ($quiz{hnum} < $hints_limit)) ||
-               (($hints_limit < 0) && ($quiz{dmax} > abs($hints_limit)))) {
-                       send_irc('quiz_msg_hint', make_hint());
-                       my $delay = settings_get_int('quiz_anticheat_delay');
-                       if ($delay > 0) {
-                               $quiz{hprot} = 1;
-                               $quiz{thint} = timeout_add_once($delay * 1000, sub { $quiz{hprot} = 0 }, undef);
-                       }
-       }
-       if (settings_get_bool('quiz_autohinter')) {
-               stop_timer('thinter');
-               my $delay = abs(settings_get_int('quiz_hints_interval')) || $_hints_interval; # abs in case of <0, || in case of ==0
-               $quiz{thinter} = timeout_add_once($delay * 1000, 'evt_show_hint', undef);
-       }
-}
-
-sub show_remind {
-       return unless (settings_get_bool('quiz_cmd_remind'));
-       if ((($quiz{type} == QT_MIX) || ($quiz{type} == QT_SCR)) && settings_get_bool('quiz_mix_on_remind')) {
-               return if ($quiz{rprot});
-               my $delay = settings_get_int('quiz_anticheat_delay');
-               if ($delay > 0) {
-                       $quiz{rprot} = 1;
-                       $quiz{tremind} = timeout_add_once($delay * 1000, sub { $quiz{rprot} = 0 }, undef);
-               }
-       }
-       my @lines = make_remind();
-       my $line = 1;
-       foreach my $text (@lines) {
-               if ($line++ == 1) {
-                       send_irc('quiz_msg_remind', get_format('quiz_inc_question', $text));
-               } else {
-                       send_irc('quiz_inc_question', $text);
-               }
-       }
-}
-
-sub check_answer {
-       my ($nick, $addr, $answer) = @_;
-       if (($quiz{type} == QT_FAM) || ($quiz{type} == QT_MUL)) {
-               return unless (exists($quiz{lookup}{lc $answer}) &&
-                                               ($quiz{data}[$quiz{qnum}]{answers}{$quiz{lookup}{lc $answer}} > 0));
-               return unless (($quiz{type} == QT_MUL) || !settings_get_bool('quiz_team_play') ||
-                                               (exists($quiz{players}{$addr}) && exists($quiz{players}{$addr}{team}) && ($quiz{players}{$addr}{team} != 0))); # last condition: for non team players there is no record yet // autovivification...
-               my ($time, $match) = (time(), $quiz{lookup}{lc $answer});
-               my $answers = keys %{$quiz{data}[$quiz{qnum}]{answers}};
-               my $id = $quiz{data}[$quiz{qnum}]{answers}{$match};
-               my $value = $answers - $id + 1;
-               my $points = settings_get_int('quiz_points_per_answer'); # ppa
-               my $min = settings_get_int('quiz_min_points');
-               my $max = settings_get_int('quiz_max_points');
-               my $mode = settings_get_int('quiz_scoring_mode');
-               if ($mode == 2) { # ppa++
-                       $points *= $value;
-               } elsif ($mode == 3) { # ppa++:max
-                       $points *= $value;
-                       $points = $max if ($points > $max);
-               } elsif ($mode == 4) { # min++ppa
-                       ($points *= $value - 1) += $min;
-               } elsif ($mode == 5) { # min++ppa:max
-                       ($points *= $value - 1) += $min;
-                       $points = $max if ($points > $max);
-               } elsif ($mode == 6) { # max--ppa:min
-                       $points = $max - $points * ($id - 1);
-                       $points = $min if ($points < $min);
-               } elsif ($mode == 7) { # max->min
-                       $points = int(($value - 1) * ($max - $min) / ($answers - 1) + $min + 0.5);
-               #} elsif ($mode == 8) { # max%:min
-               #       $points = int($max * $value / $answers + 0.5);
-               #       $points = $min if ($points < $min);
-               }
-               correct_answer($addr, $nick, $time, $points, $answer);
-               send_irc('quiz_msg_congrats', [
-                       $nick,
-                       ($points == 1) ? get_format('quiz_inc_got_point', score_str($points)) : get_format('quiz_inc_got_points', [$points, score_str($points)]),
-                       $match,
-                       $time - $quiz{qtime},
-                       length($answer) / ($time - $quiz{qtime}),
-                       $quiz{players}{$addr}{score}]);
-               $quiz{data}[$quiz{qnum}]{answers}{$match} *= -1;
-               if (!grep { $_ > 0 } values %{$quiz{data}[$quiz{qnum}]{answers}}) {
-                       stop_question();
-                       init_next_question(get_format('quiz_msg_all_answers')); #? not INSTANT
-               }
-       } else {
-               return unless ((lc($answer) eq lc($quiz{data}[$quiz{qnum}]{answer})) ||
-                       (!settings_get_bool('quiz_strict_match') && (index(lc $answer, lc $quiz{data}[$quiz{qnum}]{answer}) >= 0)));
-               my ($time, $points) = (time(), settings_get_int('quiz_points_per_answer'));
-               my $limit = int($quiz{qcnt} * 0.5 + 1) * $points; # 50%+1
-               my $limiter = settings_get_bool('quiz_limiter');
-               return unless (!$limiter || !exists($quiz{players}{$addr}) || ($quiz{players}{$addr}{score} < $limit));
-               stop_question();
-               correct_answer($addr, $nick, $time, $points, $answer);
-               init_next_question(get_format('quiz_msg_congrats', [
-                       $nick,
-                       ($points == 1) ? get_format('quiz_inc_got_point', score_str($points)) : get_format('quiz_inc_got_points', [$points, score_str($points)]),
-                       $quiz{data}[$quiz{qnum}]{answer},
-                       $time - $quiz{qtime},
-                       length($answer) / ($time - $quiz{qtime}),
-                       $quiz{players}{$addr}{score}]) . (($limiter && ($quiz{players}{$addr}{score} >= $limit)) ? ' ' . get_format('quiz_msg_limit') : ''), INSTANT);
-       }
-}
-
-##### Signals' handlers #####
-sub sig_pubmsg {
-       my ($r_server, $msg, $nick, $addr, $target) = @_;
-       return if (!$quiz{ison} || ($r_server->{tag} ne $quiz{chan}{server}{tag}) || (lc($target) ne lc($quiz{chan}{name})));
-       for ($msg) {
-               tr/\t/ /;                       # tabs to spaces
-               s/ {2,}/ /g;            # fix double spaces
-               s/^ +| +$//g;           # trim leading/trailing spaces
-               s/\002|\003(?:\d{1,2}(?:,\d{1,2})?)?|\017|\026|\037//g;         # remove formatting
-               # \002 - bold  \003$fg(,$bg)? - color  \017 - plain  \026 - reverse  \037 - underline
-       }
-       return if ($msg eq '');
-       show_score($nick, $addr, $1) if ($msg =~ /^!score(?:\s+([^\s]+))?/i);
-       return if ($quiz{ended});
-       join_team($nick, $addr, $1) if ($msg =~ /^!join\s+(\d)$/i);
-       return if (!$quiz{inq});
-       my $lmsg = lc $msg;
-       if ($lmsg eq '!hint') {
-               show_hint();
-       } elsif ($lmsg eq '!remind') {
-               show_remind();
-       }
-       check_answer($nick, $addr, $msg);
-}
-
-##### Bindings #####
-command_bind('help',   'cmd_irssi_help');
-command_bind('quiz',   'cmd_help');
-command_bind('qtype',  'cmd_type');
-command_bind('qteams', 'cmd_teams');
-command_bind('qon',            'cmd_start');
-command_bind('qdelay', 'cmd_delay');
-command_bind('qtime',  'cmd_time');
-command_bind('qhint',  'cmd_hint');
-command_bind('qremind',        'cmd_remind');
-command_bind('qskip',  'cmd_skip');
-command_bind('qstats', 'cmd_stats');
-command_bind('qoff',   'cmd_stop');
-command_bind('qreload',        'cmd_reload');
-command_bind('qinit',  'cmd_init');
-
-##### User settings #####
-settings_add_int($IRSSI{name}, $_, $settings_int{$_}) for (keys %settings_int);
-settings_add_bool($IRSSI{name}, $_, $settings_bool{$_}) for (keys %settings_bool);
-settings_add_str($IRSSI{name}, $_, $settings_str{$_}) for (keys %settings_str);
-
-##### Initialization #####
-timeout_add_once($_display_delay, 'evt_delayed_load_info', undef); # le trick (workaround for info showing before script load message)
git clone https://git.99rst.org/PROJECT