/ Published in: TCL
here is a little update for the popular moxquizz script for eggdrop i wrote
you can download the script here: http://moxquiz.bplaced.net/homepage/?seite=download
an also see a list of the new features there
you can download the script here: http://moxquiz.bplaced.net/homepage/?seite=download
an also see a list of the new features there
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
## ### moxquizz.tcl -- quizzbot for eggdrop 1.6.9+ ## ### Author: Moxon <[email protected]> (AKA Sascha Lüdecke) ## ### Credits: ## - Artwork was done with heavy support of Michee <[email protected]> ## - Julika loved to discuss and suggested many things. ## - Imran Ghory provided more than 600 english questions. ## - Questions have been edited by Michee, Julika, Tobac, Imran and ## Klinikai_Eset ## - ManInBlack for supplemental scripting ## - numerous others, see the README for a more complete list. ## If you are missing, please tell me! ## ### Copyright (C) 2000 Moxon AKA Sascha Lüdecke ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ## ### ## $Id: moxquizz.tcl,v 1.175 2002/07/05 19:21:26 chat Exp $ ########################################################################### ########################################################################### ########################################################################### ######################## ### typ's mod config ### ######################## #Wieviel Sekunden sollen Schätzfragen offen sein? set schaetztime 15 #Soll !vok erlaubt sein? (1=ja,2=nein) set allow_vok 1 #Soll !halt erlaubt sein? (1=ja,2=nein) set allow_halt 1 #Soll das Anti-Highlighting aktiviert sein? (1=ja,2=nein) set allow_antihl 1 #Soll das gelbe Design aktiviert sein? (1=ja,2=nein) set go_yellow 0 #Sollen statistische Daten im Web veröffentlicht werden? (1=ja,2=nein) set allow_web 1 #Sollen Zeitrekorde gespeichert werden? (1=ja,2=nein) set allow_rec 1 #Soll der Bot jeden Tag einmal neu starten? (1=ja,2=nein) set daily_restart 0 ######################## ### typ's mod info ### ######################## # 1. Schätzfragen # Schätzfragen müssen als Kategorie "Category: Schätzfragen" haben, ansonsten werden sie wie normale Quizfragen behandelt. # Die Antworten dürfen lediglich aus arabischen Zahlen (ohne Trennpunkte) sein. # 2. Ratefragen # Ratefragen müssen als Kategorie "Category: Ratefragen" haben, ansonsten werden sie wie normale Quizfragen behandelt. # Die Antworten müssen folgendes Format haben: Antwort1*Antwort2*Antwort3 # Das Ratefragen-Script basiert auf dem KAOS-Script von Mark A. Day. # 3. A/M # A/M steht für Anschläge pro Minute # 4. Web-Statistiken # Soweit von Dir erlaubt, sendet der QuizBot informationen an http://moxquiz.bplaced.net/homepage/ # 5. Support # Support gibt es im MoxQuizz-Forum unter http://www.moxquizz.de/forum oder im #quiz.de @ irc.gamesurge.net ######################## ### new commands ### ######################## #!vok - Zeigt die Antwort ohne Vokale #!halt - Hält den Bot an #!alltimes - Zeigt die ewige Rangliste an #!server - Zeigt den Server, zu dem der Bot verbunden ist #!time - Zeigt Deine Spieldauer #!rehash - OPs only #!restart - OPs only ########################################################################### ########################################################################### ########################################################################### ## Version: set version_moxquizz "0.8.1 {type:mod von http://moxquiz.bplaced.net/homepage/}" package require msgcat package require http namespace import -force msgcat::* ########################################################################### ## ## ATTENTION: ## ## Defaults for bot configuration. Don't edit here, edit the file ## moxquizz.rc instead! ## ########################################################################### # system stuff variable quizbasedir moxquizz variable datadir $quizbasedir/quizdata variable configfile $quizbasedir/moxquizz.rc variable intldir $quizbasedir/intl variable rankfile $datadir/rank.data variable allstarsfile $datadir/rankallstars.data variable statsfile $datadir/stats.data variable userqfile $datadir/questions.user.new variable commentsfile $datadir/comments.txt variable quizhelp # these will be searched in $intldir/$quizconf(language) variable channeltipfile channeltips.txt variable channelrulesfile channelrules.txt variable pricesfile prices.txt variable helpfile help.txt # # Configuration map # variable quizconf set quizconf(quizchannel) "#quiz" set quizconf(quizloglevel) 1 # several global numbers set quizconf(maxranklines) 100 set quizconf(tipcycle) 5 set quizconf(useractivetime) 240 set quizconf(userqbufferlength) 20 set quizconf(winscore) 30 set quizconf(overrunlimit) 29 # timer delays in seconds set quizconf(askdelay) 12 set quizconf(tipdelay) 14 # safety features and other configs set quizconf(lastwinner_restriction) no set quizconf(lastwinner_max_games) 4 set quizconf(overrun_protection) no set quizconf(colorize) yes set quizconf(monthly_allstars) no set quizconf(channeltips) yes set quizconf(pausemoderated) no set quizconf(userquestions) yes set quizconf(msgwhisper) no set quizconf(channelrules) yes set quizconf(prices) yes set quizconf(stripumlauts) no set quizconf(statslog) no set quizconf(aftergameaction) newgame set quizconf(language) de ## ########################################################################### ## ## stuff for the game state ## #typ set ctcp-version "MoxQuizz für #Quiz.de @ irc.GameSurge.net" variable answerarray variable schaetzarray variable schaetzend "" variable schaetzwert "" variable timetypasked [clock clicks -milliseconds] variable subexp "" variable bestscore 0 # values = stopped, paused, asked, waittoask, halted variable quizstate "halted" variable statepaused "" variable statemoderated "" variable usergame 0 variable timeasked [unixtime] variable revoltmax 0 # values = newgame, stop, halt, exit variable aftergame $quizconf(aftergameaction) variable channeltips "" variable channelrules "" variable prices "" # # variables for the ranks and user handling # variable timerankreset [unixtime] variable userlist variable allstarsarray variable revoltlist "" variable lastsolver "" variable lastsolvercount 0 variable lastwinner "" variable lastwinnercount 0 variable allstars_starttime 0 variable ignore_for_userquest "" # # stuff for the question # variable tiplist "" variable theq variable qnumber 0 variable qnum_thisgame 0 variable userqnumber 0 variable tipno 0 variable qlist "" variable qlistorder "" variable userqlist "" # # doesn't fit elsewhere # variable whisperprefix "NOTICE" variable statsfilefd "closed" ################################################## ## bindings # bot running status bind dcc P !init moxquiz_init bind dcc P !stop moxquiz_stop bind dcc P !halt moxquiz_halt bind dcc P !pause moxquiz_pause bind dcc P !cont moxquiz_cont bind dcc P !reset moxquiz_reset bind dcc m !exit moxquiz_exit bind dcc m !aftergame moxquiz_aftergame # bot speaking and hopping stuff bind dcc P !say moxquiz_say bind dcc P !act moxquiz_action bind dcc m !allsay moxquiz_say_everywhere bind dcc m !allact moxquiz_action_everywhere bind dcc Q !join moxquiz_join bind dcc Q !part moxquiz_part bind dcc Q !quizto moxquiz_quizto bind dcc Q !quizleave moxquiz_quizleave # commands for the questions bind dcc P !solve moxquiz_solve bind dcc P !tip moxquiz_tip bind dcc P !skipuserquest moxquiz_skipuserquest bind dcc Q !setscore moxquiz_set_score bind dcc m !qsave moxquiz_saveuserquests bind dcc Q !reload moxquiz_reload # status and configuration bind dcc P !status moxquiz_status bind dcc m !load moxquiz_config_load bind dcc m !save moxquiz_config_save bind dcc m !set moxquiz_config_set # userquest and other user (public) commands bind pubm - * moxquiz_pubm bind pub - !ask moxquiz_ask bind pub - .ask moxquiz_ask bind pub - !quiz moxquiz_ask bind pub - .quiz moxquiz_ask bind pub - !start moxquiz_ask bind pub - .start moxquiz_ask bind pub - !revolt moxquiz_user_revolt bind pub - !end moxquiz_user_revolt bind msg - !userquest moxquiz_userquest bind msg - !usercancel moxquiz_usercancel bind msg - !usertip moxquiz_usertip bind msg - !usersolve moxquiz_usersolve bind pub P !nuq moxquiz_userquest_ignore bind pub P !uq moxquiz_userquest_unignore bind pub P !listnuq moxquiz_userquest_listignores bind pub P !clearnuq moxquiz_userquest_clearignores bind msg - !qhelp moxquiz_help bind pub - !qhelp moxquiz_pub_help bind pub - !score moxquiz_pub_score bind pub - !rank moxquiz_pub_rank bind pub - !allstars moxquiz_pub_allstars bind pub - !comment moxquiz_pub_comment bind pub - !fehler moxquiz_pub_comment bind dcc - !comment moxquiz_dcc_comment bind msg - !rules moxquiz_rules bind pub - !rules moxquiz_pub_rules bind msg - !version moxquiz_version bind pub - !version moxquiz_pub_version # mini funstuff bind pub - !hi moxquiz_pub_hi #bind ctcp - action moxquiz_purr # commands to manage players and rank bind dcc P !allstars moxquiz_allstars bind dcc m !allstarssend moxquiz_allstars_send bind dcc m !allstarsload moxquiz_allstars_load bind dcc P !rank moxquiz_rank bind dcc Q !rankdelete moxquiz_rank_delete bind dcc m !rankload moxquiz_rank_load bind dcc m !ranksave moxquiz_rank_save bind dcc Q !rankreset moxquiz_rank_reset bind dcc Q !rankset moxquiz_rank_set # Some events the bot reacts on bind nick - * moxquiz_on_nickchanged bind join - * moxquiz_on_joined bind mode - "*m" moxquiz_on_moderated bind evnt - prerehash mx_event bind evnt - rehash mx_event ## DEBUG bind dcc n !colors moxquiz_colors ########################################################################### # # bot running commands # ########################################################################### ## reset game proc moxquiz_reset {handle idx arg} { global quizstate moxquiz_stop $handle $idx $arg moxquiz_rank_reset $handle $idx $arg moxquiz_init $handle $idx $arg } ## initialize proc moxquiz_init {handle idx arg} { global qlist version_moxquizz banner bannerspace quizstate global quizconf aftergame set quizstate "halted" set aftergame $quizconf(aftergameaction) if {$quizconf(quizchannel) != ""} { mxirc_say $quizconf(quizchannel) [mc "%sHello! I am a MoxQuizz version %s and ready to squeeze your brain!" "[banner] [botcolor txt]" "[col bold]$version_moxquizz[col bold][botcolor txt]"] mxirc_say $quizconf(quizchannel) [mc "%s%d questions in database, just %s!ask%s. Report bugs and suggestions to [email protected]" "[bannerspace] [botcolor txt]" [llength $qlist] [col bold] "[col bold][botcolor txt]"] mx_log "--- Game initialized" } else { mxirc_dcc $idx "ERROR: quizchannel is set to an empty string, use .!quizto to set one." } return 1 } ## stop ## stop everything and kill all timers proc moxquiz_stop {handle idx arg} { global quizstate banner bannerspace global quizconf variable t variable prefix [banner] ## called directly? if {[info level] != 1} { set prefix [bannerspace] } else { set prefix [banner] } set quizstate "stopped" ## kill timers foreach t [utimers] { if {[lindex $t 1] == "mx_timer_ask" || [lindex $t 1] == "mx_timer_tip"} { killutimer [lindex $t 2] } } mx_log "--- Game stopped." mxirc_say $quizconf(quizchannel) [mc "%s %sQuiz stopped." $prefix [botcolor boldtxt]] return 1 } ## halt ## halt everything and kill all timers proc moxquiz_halt {handle idx arg} { global quizstate banner bannerspace global quizconf variable t variable prefix [banner] ## called directly? if {[info level] != 1} { set prefix [bannerspace] } else { set prefix [banner] } set quizstate "halted" ## kill timers foreach t [utimers] { if {[lindex $t 1] == "mx_timer_ask" || [lindex $t 1] == "mx_timer_tip"} { killutimer [lindex $t 2] } } mx_log "--- Game halted." mxirc_say $quizconf(quizchannel) [mc "%s %sQuiz halted. Say !ask for new questions." $prefix [botcolor boldtxt]] utimer 5 mx_restart return 1 } ## reload questions proc moxquiz_reload {handle idx arg} { global qlist quizconf global datadir variable alist "" variable banks variable suffix set arg [string trim $arg] if {$arg == ""} { # get question files set alist [glob -nocomplain "$datadir/questions.*"] # get suffixes foreach file $alist { regexp "^.*\\.(\[^\\.\]+)$" $file foo suffix set banks($suffix) 1 } # report them mxirc_dcc $idx "There are the following question banks available (current: $quizconf(questionset)): [lsort [array names banks]]" } else { if {[mx_read_questions $arg] != 0} { mxirc_dcc $idx "There was an error reading files for $arg." mxirc_dcc $idx "There are [llength $qlist] questions available." } else { mxirc_dcc $idx "Reloaded database, [llength $qlist] questions." set quizconf(questionset) $arg } } return 1 } ## pause proc moxquiz_pause {handle idx arg} { global quizstate statepaused banner timeasked global quizconf variable qwasopen "." if {[regexp "(halted|paused)" $quizstate]} { mxirc_dcc $idx "Quiz state is $quizstate. Command ignored." } else { if {$quizstate == "asked"} { foreach t [utimers] { if {[lindex $t 1] == "mx_timer_tip"} { killutimer [lindex $t 2] } } set qwasopen [mc " after %s." [mx_duration $timeasked]] } elseif {$quizstate == "waittoask"} { foreach t [utimers] { if {[lindex $t 1] == "mx_timer_ask"} { killutimer [lindex $t 2] } } } set statepaused $quizstate set quizstate "paused" mx_log "--- Game paused$qwasopen Quiz state was: $statepaused" mxirc_say $quizconf(quizchannel) [mc "%sQuiz paused%s" "[banner] [botcolor boldtxt]" $qwasopen] } return 1 } ## continue proc moxquiz_cont {handle idx arg} { global quizstate banner bannerspace timeasked global theq statepaused usergame statemoderated global quizconf if {$quizstate != "paused"} { mxirc_dcc $idx "Game not paused, command ignored." } else { if {$statepaused == "asked"} { if {$usergame == 1} { set txt [mc "%sQuiz continued. The user question open since %s, worth %d point(s):" "[banner] [botcolor boldtxt]" [mx_duration $timeasked] $theq(Score)] } else { set txt [mc "%sQuiz continued. The question open since %s, worth %d point(s):" "[banner] [botcolor boldtxt]" [mx_duration $timeasked] $theq(Score)] } mxirc_say $quizconf(quizchannel) $txt mxirc_say $quizconf(quizchannel) "[bannerspace] [botcolor question]$theq(Question)" utimer $quizconf(tipdelay) mx_timer_tip } else { mxirc_say $quizconf(quizchannel) [mc "%sQuiz continued. Since there is no open question, a new one will be asked." "[banner] [botcolor boldtxt]"] utimer 3 mx_timer_ask } set quizstate $statepaused set statepaused "" set statemoderated "" mx_log "--- Game continued." } return 1 } ## show module status proc moxquiz_status {handle idx arg} { global quizstate statepaused qlist banner version_moxquizz userlist global timeasked uptime global usergame userqlist theq qnumber global qnum_thisgame aftergame global quizconf variable askleft 0 rankleft 0 tipleft 0 variable txt variable chansjoined "" ## banner and where I am set txt "I am [mx_strip_colors [banner]] version $version_moxquizz, up for [mx_duration $uptime]" if {$quizconf(quizchannel) == ""} { set txt "$txt, not quizzing on any channel." } else { set txt "$txt, quizzing on channel \"$quizconf(quizchannel)\"." } mxirc_dcc $idx $txt mxirc_dcc $idx "I know the channels [channels]." foreach chan [channels] { if {[botonchan $chan]} { set chansjoined "$chansjoined $chan" } } if {$chansjoined == ""} { set chansjoined " none" } mxirc_dcc $idx "I currently joined:$chansjoined." if {$quizstate == "asked" || $statepaused == "asked"} { ## Game running? User game? set txt "There is a" if {$usergame == 1} { set txt "$txt user" } set txt "$txt game running." if {[mx_userquests_available]} { set txt "$txt [mx_userquests_available] user quests scheduled." } else { set txt "$txt No user quest is scheduled." } set txt "$txt Quiz state is: $quizstate." mxirc_dcc $idx $txt ## Open question? Quiz state? set txt "The" if {[info exists theq(Level)]} { set txt "$txt level $theq(Level)" } set txt "$txt question no. $qnum_thisgame is:" if {[info exists theq(Category)]} { set txt "$txt ($theq(Category))" } mxirc_dcc $idx "$txt \"$theq(Question)\" open for [mx_duration $timeasked], worth $theq(Score) points." } else { ## no open question, no game running set txt "There is no question open." set txt "$txt Quiz state is: $quizstate." if {[mx_userquests_available]} { set txt "$txt [mx_userquests_available] user quests scheduled." } else { set txt "$txt No user quest is scheduled." } mxirc_dcc $idx $txt } mxirc_dcc $idx "Action after game won: $aftergame" foreach t [utimers] { if {[lindex $t 1] == "mx_timer_ask"} { set askleft [lindex $t 0] } if {[lindex $t 1] == "mx_timer_tip"} { set tipleft [lindex $t 0] } } mxirc_dcc $idx "Tipdelay: $quizconf(tipdelay) ($tipleft) Askdelay: $quizconf(askdelay) ($askleft) Tipcycle: $quizconf(tipcycle)" mxirc_dcc $idx "I know about [llength $qlist] normal and [llength $userqlist] user questions. Question number is $qnumber." mxirc_dcc $idx "There are [llength [array names userlist]] known people, winscore is $quizconf(winscore)." mxirc_dcc $idx "Game row restriction: $quizconf(lastwinner_restriction), row length: $quizconf(lastwinner_max_games)" return 1 } ## exit -- finish da thing and logoff proc moxquiz_exit {handle idx arg} { global rankfile uptime botnick statsfilefd global quizconf mx_log "--- EXIT requested." mxirc_say $quizconf(quizchannel) [mc "%sI am leaving now, after running for %s." "[banner] [botcolor boldtxt]" [mx_duration $uptime]] if {$arg != ""} { mxirc_say $quizconf(quizchannel) "[bannerspace] $arg" } # moxquiz_quizleave $handle $idx $arg moxquiz_rank_save $handle $idx {} moxquiz_saveuserquests $handle $idx "all" moxquiz_config_save $handle $idx {} if {$statsfilefd != "closed"} { close $statsfilefd } mxirc_dcc $idx "$botnick now exits." mx_log "--- $botnick exited" mx_log "**********************************************************************" utimer 10 die } ## aftergame -- what to do if the game is over (won or desert detection) proc moxquiz_aftergame {handle idx arg} { global aftergame quizstate variable thisnext "this" if {$quizstate == "stopped" || $quizstate == "halted"} { set thisnext "next" } if {$arg == ""} { mxirc_dcc $idx "After $thisnext game I am planning to: \"$aftergame\"." mxirc_dcc $idx "Possible values are: exit, halt, stop, newgame." } else { switch -regexp $arg { "(exit|halt|stop|newgame)" { set aftergame $arg mxirc_dcc $idx "After $thisnext game I now will: \"$aftergame\"." } default { mxirc_dcc $idx "Invalid action. Chosse from: exit, halt, stop and newgame." } } } return 1 } #################### # bot control stuff #################### ## echo a text send by /msg proc moxquiz_say {handle idx arg} { global funstuff_enabled botnick global quizconf variable channel set arg [string trim $arg] if {[regexp -nocase "^(#\[^ \]+)( +.*)?" $arg foo channel arg]} { ## check if on channel $channel if {[validchan $channel] && ![botonchan $channel]} { mxirc_dcc $idx "Sorry, I'm not on channel \"$channel\"." return } } else { set channel $quizconf(quizchannel) } set arg [string trim $arg] mxirc_say $channel "$arg" variable unused "" cmd "" rest "" # if it was a fun command, execute it with some delay if {$funstuff_enabled && [regexp "^(!\[^ \]+)(( *)(.*))?" $arg unused cmd waste spaces rest] && [llength [bind pub - $cmd]] != 0} { if {$rest == ""} { set rest "{}" } else { set rest "{$rest}" } eval "[bind pub - $cmd] {$botnick} {} {} {$channel} $rest" } } ## say something on al channels proc moxquiz_say_everywhere {handle idx arg} { if {$arg != ""} { mxirc_say_everywhere $arg } else { mxirc_dcc $idx "What shall I say on every channel?" } } ## act as sent by /msg proc moxquiz_action {handle idx arg} { global quizconf variable channel set arg [string trim $arg] if {[regexp -nocase "^(#\[^ \]+)( +.*)?" $arg foo channel arg]} { ## check if on channel $channel if {[validchan $channel] && ![botonchan $channel]} { mxirc_dc $idx "Sorry, I'm not on channel \"$channel\"." return } } else { set channel $quizconf(quizchannel) } set arg [string trim $arg] mxirc_action $channel "$arg" } ## say something on al channels proc moxquiz_action_everywhere {handle idx arg} { if {$arg != ""} { mxirc_action_everywhere $arg } else { mxirc_dcc $idx "What shall act like on every channel?" } } ## hop to another channel proc moxquiz_join {handle idx arg} { global quizconf if {[regexp -nocase "^(#\[^ \]+)( +.*)?" $arg foo channel arg]} { set channel [string tolower $channel] if {[validchan $channel] && [botonchan $channel]} { set txt "I am already on $channel." if {$channel == $quizconf(quizchannel)} { set txt "$txt It's the quizchannel." } mxirc_dcc $idx $txt } else { channel add $channel channel set $channel -inactive mxirc_dcc $idx "Joined channel $channel." } } else { mxirc_dcc $idx "Please specify channel I shall join. \"$arg\" not recognized." } } ## part an channel proc moxquiz_part {handle idx arg} { global quizconf if {[regexp -nocase "^(#\[^ \]+)( +.*)?" $arg foo channel arg]} { set channel [string tolower $channel] if {[validchan $channel]} { if {$channel == $quizconf(quizchannel)} { mxirc_dcc $idx "Cannot leave quizchannel via part. User !quizleave or !quizto to do this." } else { channel set $channel +inactive mxirc_dcc $idx "Left channel $channel." } } else { mxirc_dcc $idx "I am not on $channel." } } else { mxirc_dcc $idx "Please specify channel I shall part. \"$arg\" not recognized." } } ## quiz to another channel proc moxquiz_quizto {handle idx arg} { global quizconf if {[regexp "^#.*" $arg] == 0} { mxirc_dcc $idx "$arg not a valid channel." } else { if {$quizconf(quizchannel) != ""} { # channel set $quizconf(quizchannel) +inactive mxirc_say $quizconf(quizchannel) [mc "Quiz is leaving to %s. Goodbye!" $arg] } set quizconf(quizchannel) [string tolower $arg] channel add $quizconf(quizchannel) channel set $quizconf(quizchannel) -inactive mxirc_say $quizconf(quizchannel) [mc "Quiz is now on this channel. Hello!"] mxirc_dcc $idx "quiz to channel $quizconf(quizchannel)." mx_log "--- quizto channel $quizconf(quizchannel)" } return 1 } ## quiz leave a channel proc moxquiz_quizleave {handle idx arg} { global quizconf banner if {$arg == ""} { mxirc_say $quizconf(quizchannel) [mc "%s Goodbye." [banner]] } else { mxirc_say $quizconf(quizchannel) "[banner] $arg" } if {$quizconf(quizchannel) != ""} { channel set $quizconf(quizchannel) +inactive mx_log "--- quizleave channel $quizconf(quizchannel)" mxirc_dcc $idx "quiz left channel $quizconf(quizchannel)" set quizconf(quizchannel) "" } else { mxirc_dcc $idx "I'm not quizzing on any channel." } return 1 } ########################################################################### # # commands for the questions # ########################################################################### ## something was said. Solution? proc moxquiz_pubm {nick host handle channel text} { global quizstate banner bannerspace global timeasked theq aftergame global usergame revoltlist global lastsolver lastsolvercount global lastwinner lastwinnercount global botnick bestscore global userlist channeltips prices global quizconf variable bestscore 0 lastbestscore 0 lastbest "" variable userarray variable authorsolved 0 waitforrank 0 gameend 0 ## only accept chatter on quizchannel if {![mx_str_ieq $channel $quizconf(quizchannel)]} { return } ## record that the $nick spoke and create entries for unknown people mx_getcreate_userentry $nick $host array set userarray $userlist($nick) set hostmask $userarray(mask) ## not in asking state? if {$quizstate != "asked"} { return } # nick has revolted #if {[lsearch -exact $revoltlist $hostmask] != -1} { # return #} # tweak umlauts in input set text [mx_tweak_umlauts $text] global answerarray set regohneleerzeichen $theq(Regexp) regsub -all " " $regohneleerzeichen "" regohneleerzeichen if {[regexp -nocase -- $theq(Regexp) $text] || [regexp -nocase -- $regohneleerzeichen $text]} { foreach name [array names answerarray] { unset answerarray($name) } ## ignore games_max in a row winner if {[mx_str_ieq [maskhost $host] $lastwinner] && $lastwinnercount >= $quizconf(lastwinner_max_games) && $quizconf(lastwinner_restriction) == "yes"} { mxirc_notc $nick [mc "No, you've won the last %d games." $quizconf(lastwinner_max_games)] return } # nick is author of userquest #if {([info exists theq(Author)] && [mx_str_ieq $nick $theq(Author)]) #|| ([info exists theq(Hostmask)] && [mx_str_ieq [maskhost $host] $theq(Hostmask)])} { # set authorsolved 1 #} ## return if overrunprotection set and limit reached #if {$quizconf(overrun_protection) == "yes" # && $userarray(score) == 0 # && [mx_users_in_rank] > 2 # && [mx_overrun_limit_reached]} { # # [pending] TRANSLATE! # mxirc_notc $nick [mc "Sorry, overrun protection enabled. Wait till end of game."] # return #} ## reset quiz state related stuff (and save userquestions) mx_answered set duration [mx_duration $timeasked] set recdiff "" global timetypasked schaetzend allow_rec if {$schaetzend != "" && $schaetzend > 0} { set typdur $schaetzend set schaetzend "" } else { set typdur [expr ([clock clicks -milliseconds] - $timetypasked) * 0.001] if {$typdur < "10.000" &&$allow_rec} { set record [mx_read_record $text] if {$record == ""} { mx_save_record $nick $typdur $text } else { set recholder [lindex [split $record] 0] set rectime [lindex [split $record] 1] if {$rectime > $typdur} { mx_save_record $nick $typdur $text } set recdiff [expr $typdur - $rectime] if {$recdiff > 0} {set recdiff "+${recdiff}"} else {set recdiff "\002$recdiff\002"} set recdiff "\(${recdiff} Sek. zu [mx_nickobf $recholder]\) " } } } # if it wasn't the author if {!$authorsolved} { ## save last top score for the test if reset is near (later below) set lastbest [lindex [lsort -command mx_sortrank [array names userlist]] 0] if {$lastbest == ""} { set lastbestscore 0 } else { array set aa $userlist($lastbest) set lastbestscore $aa(score) } ## record nick for bonus points if {[mx_str_ieq [maskhost $host] $lastsolver]} { incr lastsolvercount } else { set lastsolver [maskhost $host] set lastsolvercount 1 } ## save score (set started time to time of first point) incr userarray(score) $theq(Score) if {$userarray(score) == 1} { set userarray(started) [unixtime] } set userlist($nick) [array get userarray] ## tell channel, that the question is solved mx_log "--- solved after $duration by $nick with \"$text\", now $userarray(score) points" set daten [mx_incr_qnr] global vokspamvar hintmax hintlist set vokspamvar 0 set hintmax 0 set hintlist "" mx_statslog "solved" [list [unixtime] $nick $duration $userarray(score) $theq(Score)] #mxirc_say $channel [mc "%s solved after %s and now has %s<%d>%s points (+%d) on rank %d." "[banner] [botcolor nick]$nick[botcolor txt]" $duration [botcolor nick] $userarray(score) [botcolor txt] $theq(Score) [mx_get_rank_pos $nick]] set answrnr [mx_answ_user $nick 1] set total [regexp -all -nocase {[A-Z]|[0-9]|[ ]} $text] #bugfix: if {$typdur <= 0 || $typdur == ""} { set typdur $duration } set speed [expr $total / $typdur * 60] mxirc_rsay $channel [mc "%s löst nach %s Sek. ${recdiff}seine %d. Frage und hat %s<%d>%s Punkte (+%d), Platz 9,1~%d~1,11.%s %sA/M: %3.0f" "[banner] [botcolor nick]$nick[botcolor txt]" $typdur $answrnr [botcolor nick] $userarray(score) [botcolor txt] $theq(Score) [mx_get_rank_pos $nick] [botcolor norm] [botcolor question] $speed] # remove area of tip generation tags regsub -all "\#(\[^\#\]*\)\#" $theq(Answer) "\\1" answer global schaetzwert subexp if {$schaetzwert != ""} { set showanswer $answer set schaetzwert [commas $schaetzwert] set stotal [regexp -all -nocase {[A-Z]|[0-9]|[ ]} $subexp] if {$stotal > 4} { regsub -all $subexp $showanswer [commas $subexp] showanswer } set showanswer "$showanswer \(Abweichung: ${schaetzwert}\)" set schaetzwert "" } else { set showanswer $answer } mxirc_say $channel [mc "%sThe answer was:%s%s" "[bannerspace] [botcolor txt]" "[botcolor norm] [botcolor answer]" $showanswer] ## honor good games! if {$lastsolvercount == 3} { mxirc_say $channel [mc "%sThree in a row!" "[bannerspace] [botcolor txt]"] mx_log "--- $nick has three in a row." mx_statslog "tiar" [list [unixtime] $nick 3 0] } elseif {$lastsolvercount == 5} { mxirc_say $channel [mc "%sCongratulation, five in a row! You receive an extra point." "[bannerspace] [botcolor txt]"] mx_log "--- $nick has five in a row. score++" mx_statslog "tiar" [list [unixtime] $nick 5 1] moxquiz_rank_set $botnick 0 "$nick +1" } elseif {$lastsolvercount == 10} { mxirc_say $channel [mc "%sTen in a row! This is really rare, so you get 3 extra points." "[bannerspace] [botcolor txt]"] mx_log "--- $nick has ten in a row. score += 3" mx_statslog "tiar" [list [unixtime] $nick 10 3] moxquiz_rank_set $botnick 0 "$nick +3" } elseif {$lastsolvercount == 20} { mxirc_say $channel [mc "%sTwenty in a row! This is extremely rare, so you get 5 extra points." "[bannerspace] [botcolor txt]"] mx_log "--- $nick has twenty in a row. score += 5" mx_statslog "tiar" [list [unixtime] $nick 20 5] moxquiz_rank_set $botnick 0 "$nick +5" } ## rankreset, if above winscore # notify if this comes near set best [lindex [lsort -command mx_sortrank [array names userlist]] 0] if {$best == ""} { set bestscore 0 } else { array set aa $userlist($best) set bestscore $aa(score) } set waitforrank 0 if {[mx_str_ieq $best $nick] && $bestscore > $lastbestscore} { array set aa $userlist($best) # tell the end is near if {$bestscore >= $quizconf(winscore)} { mx_web $daten $nick set price "." if {$quizconf(prices) == "yes"} { set price " [lindex $prices [rand [llength $prices]]]" } mxirc_say $channel [mc "%s%s reaches %d points and wins%s" "[bannerspace] [botcolor txt]" $nick $quizconf(winscore) $price] set now [unixtime] if {[mx_str_ieq [maskhost $host] $lastwinner]} { incr lastwinnercount if {$lastwinnercount >= $quizconf(lastwinner_max_games) && $quizconf(lastwinner_restriction) == "yes"} { mxirc_say $channel [mc "%s: since you won %d games in a row, you will be ignored for the next game." $nick $quizconf(lastwinner_max_games)] } } else { set lastwinner [maskhost $host] set lastwinnercount 1 } # save $nick in allstars table mx_saveallstar $now [expr $now - $aa(started)] $bestscore $nick [maskhost $host] mx_statslog "gamewon" [list $now $nick $bestscore $quizconf(winscore) [expr $now - $aa(started)]] moxquiz_alltimestars_load $botnick 0 $nick #mxsave_alltimestars moxquiz_rank $botnick 0 {} moxquiz_rank_reset $botnick {} {} set gameend 1 set waitforrank 15 } elseif {$bestscore == [expr $quizconf(winscore) / 2]} { mxirc_say $channel [mc "%sHalftime. Game is won at %d points." \ "[bannerspace] [botcolor txt]" $quizconf(winscore)] } elseif {$bestscore == [expr $quizconf(winscore) - 10]} { mxirc_say $channel [mc "%s%s has 10 points to go." "[bannerspace] [botcolor txt]" $best] } elseif {$bestscore == [expr $quizconf(winscore) - 5]} { mxirc_say $channel [mc "%s%s has 5 points to go." "[bannerspace] [botcolor txt]" $best] } elseif {$bestscore >= [expr $quizconf(winscore) - 3]} { mxirc_say $channel [mc "%s%s has %d point(s) to go." \ "[bannerspace] [botcolor txt]" $best [expr $quizconf(winscore) - $bestscore]] } # show rank at 1/3, 2/3 of and 5 before winscore set spitrank 1 foreach third [list [expr $quizconf(winscore) / 3] [expr 2 * $quizconf(winscore) / 3] [expr $quizconf(winscore) - 5]] { if {$lastbestscore < $third && $bestscore >= $third && $spitrank} { moxquiz_rank $botnick 0 {} set spitrank 0 set waitforrank 15 } } } } else { ## tell channel, that the question is solved by author mx_log "--- solved after $duration by $nick with \"$text\" by author" mxirc_say $channel [mc "%s solved own question after %s and gets no points, keeping %s<%d>%s points on rank %d." \ "[banner] [botcolor nick]$nick[botcolor txt]" $duration [botcolor nick] $userarray(score) [botcolor txt] [mx_get_rank_pos $nick]] # remove area of tip generation tags regsub -all "\#(\[^\#\]*\)\#" $theq(Answer) "\\1" answer mxirc_say $channel [mc "%sThe answer was:%s%s" "[bannerspace] [botcolor txt]" "[botcolor norm] [botcolor answer]" $answer] } ## Give some occasional tips if {$quizconf(channeltips) == "yes" && [rand 30] == 0} { mxirc_say $channel [mc "%sHint: %s" "[bannerspace] [botcolor txt]" [lindex $channeltips [rand [llength $channeltips]]]] } ## check if game has ended and react if {!$gameend || $aftergame == "newgame"} { # set up ask timer utimer [expr $waitforrank + $quizconf(askdelay)] mx_timer_ask } else { mx_aftergameaction } } elseif {[info exists theq(Category)]} { if {$theq(Category) == "Schätzfragen"} { set text [lindex [split $text] 0] if {![regexp "\[0-9\]+" $text]} { return } if {[regexp "\[A-Z\]" $text]} { return } if {[regexp "\[a-z\]" $text]} { return } if {[regexp -all -nocase {[A-Z]|[0-9]|[ ]} $text] > 12} {} global schaetzarray timetypasked subexp regsub -all \[{',.!}] $subexp "" subexp set entry schaetzarray($nick) set text [expr $text - $subexp] if {$text < 0} { set text [expr $text * -1] } set typdur [expr ([clock clicks -milliseconds] - $timetypasked) * 0.001] set schaetzarray($nick) [list $text $typdur] } } else { if {$text==""||$text==" "} { return } if {[info exists answerarray($nick)]} { set textzwei [lindex $answerarray($nick) 1] if {$textzwei==$text||$textzwei=="$text "} { return } regsub "\{" $textzwei "" textzwei regsub "\}" $textzwei "" textzwei regsub " " $textzwei "" textzwei if {$textzwei==$text||$textzwei=="$text "} { return } set textzwei "$textzwei $text" regsub "\{" $textzwei "" textzwei regsub "\}" $textzwei "" textzwei regsub " " $textzwei "" textzwei set entry $answerarray($nick) set answerarray($nick) [list \ $nick \ $textzwei \ ] moxquiz_pubm $nick $host $handle $channel $textzwei } else { set answerarray($nick) [list \ $nick \ $text \ ] } } } ## Tool function to get the question introduction text proc mx_get_qtext {complete} { global theq qnum_thisgame timeasked usergame qlist set qtext [list "Die Frage Nr. %d (aus [commas [llength $qlist]] Fragen) ist" \ "The question no. %d is worth %d points" \ "The question no. %d by %s is" \ "The question no. %d by %s is worth %d points" \ "The user question no. %d is" \ "The user question no. %d is worth %d points" \ "The user question no. %d by %s is" \ "The user question no. %d by %s is worth %d points" \ "The level %s question no. %d is" \ "The level %s question no. %d is worth %d points" \ "The level %s question no. %d by %s is" \ "The level %s question no. %d by %s is worth %d points" \ "The level %s user question no. %d is" \ "The level %s user question no. %d is worth %d points" \ "The level %s user question no. %d by %s is" \ "The level %s user question no. %d by %s is worth %d points" ] ## game runs, tell user the question via msg set qtextnum 0 set txt [list $qnum_thisgame] if {[info exists theq(Level)]} { incr qtextnum 8 set txt [linsert $txt 0 $theq(Level)] } if {$usergame == 1} { incr qtextnum 4 } if {[info exists theq(Author)]} { incr qtextnum 2 lappend txt [mx_nickobf $theq(Author)] } if {$theq(Score) > 1} { incr qtextnum 1 lappend txt $theq(Score) } set txt [linsert $txt 0 mc [lindex $qtext $qtextnum]] set txt [eval $txt] if {$complete == "long"} { set txt [mc "%s, open for %s:" $txt [mx_duration $timeasked]] if {[info exists theq(Category)]} { set txt "$txt \($theq(Category)\)" } set txt "$txt $theq(Question)" } else { set txt "$txt:" } global datadir set fname "$datadir/qnr.data" if {[file exists $fname] && [file readable $fname]} { set fp [open $fname "r"] set daten [read -nonewline $fp] close $fp } else { set daten 0 global statsfile set fp [open $statsfile "r"] set data [read $fp] close $fp foreach line [split $data "\n"] { if {[lindex [split $line] 0] == "solved"} { incr daten } } set file [open $fname w] puts $file $daten close $file } #return [eval $txt] set pre "[banner] [botcolor boldtxt]" return "${pre}($daten.) $txt" } ## ask a question, start game proc moxquiz_ask {nick host handle channel arg} { global qlist quizstate botnick banner bannerspace global tipno tiplist global userqnumber usergame userqlist global timeasked qnumber theq global qnum_thisgame global userlist timerankreset global quizconf schaetztime subexp variable anum 0 variable txt ## only accept chatter on quizchannel if {![mx_str_ieq $channel $quizconf(quizchannel)]} { return } switch -exact $quizstate { "paused" { mxirc_notc $nick [mc "Game is paused."] return 1 } "stopped" { mxirc_notc $nick [mc "Game is stopped."] return 1 } } ## record that $nick spoke (prevents desert detection from stopping, ## when an user joins and starts the game with !ask) if {![mx_str_ieq $nick $botnick]} { mx_getcreate_userentry $nick $host } ## any questions available? if {[llength $qlist] == 0 && [mx_userquests_available] == 0} { mxirc_say $channel [mc "%sSorry, my database is empty." "[banner] [botcolor boldtxt]"] } elseif {$quizstate == "asked"} { mxirc_notc $nick [mx_get_qtext "long"] } elseif {$quizstate == "waittoask" && ![mx_str_ieq $nick $botnick]} { ## no, user has to be patient mxirc_notc $nick [mc "Please stand by, the next question comes in less than %d seconds." $quizconf(askdelay)] } else { ## ## ok, now lets see, which question to ask (normal or user) ## ## clear old question foreach k [array names theq] { unset theq($k) } if {[mx_userquests_available]} { ## select a user question array set theq [lindex $userqlist $userqnumber] set usergame 1 incr userqnumber mx_log "--- asking a user question: $theq(Question)" } else { variable ok 0 global bestscore while {!$ok} { array set theq [lindex $qlist [mx_next_qnumber]] set usergame 0 # skip question if author is about to win if {[info exists theq(Author)] && [info exists userlist($theq(Author))]} { array set auser $userlist($theq(Author)) if {$auser(score) >= [expr $quizconf(winscore) - 5]} { mx_log "--- skipping question number $qnumber, author is about to win" } else { mx_log "--- asking question number $qnumber: $theq(Question)" set ok 1 } } else { mx_log "--- asking question number $qnumber: $theq(Question)" set ok 1 } if {[info exists theq(Category)]} { if {$theq(Category) == "Ratefragen" && $bestscore > 24} { set ok 0 } elseif {$theq(Category) == "Schätzfragen"} { if {[mx_quizzer_count] < 3} { set ok 0 } } } if {!$ok} { foreach k [array names theq] { unset theq($k) } } incr qnumber } } incr qnum_thisgame if {$qnum_thisgame == 1} { set timerankreset [unixtime] mx_log "---- it's the no. $qnum_thisgame in this game, rank timer started at: [unixtime]" mx_statslog "gamestart" [list $timerankreset] } else { mx_log "---- it's the no. $qnum_thisgame in this game." } if {[info exists theq(Category)]} { if {$theq(Category) == "Schätzfragen"} { global schaetzarray foreach name [array names schaetzarray] { unset schaetzarray($name) } utimer $schaetztime mx_schaetz_end } elseif {$theq(Category) == "Ratefragen"} { Rate_Start $nick $host $handle $channel $arg return } } ## ## ok, set some minimal required fields like score, regexp and the tiplist. ## ## set regexp to match if {![info exists theq(Regexp)]} { ## mask all regexp special chars except "." set aexp [mx_tweak_umlauts $theq(Answer)] regsub -all "(\\+|\\?|\\*|\\^|\\$|\\(|\\)|\\\[|\\\]|\\||\\\\)" $aexp "\\\\\\1" aexp # get #...# area tags for tipgeneration as regexp regsub -all ".*\#(\[^\#\]*\)\#.*" $aexp "\\1" aexp set theq(Regexp) $aexp } else { set theq(Regexp) [mx_tweak_umlauts $theq(Regexp)] } set subexp $theq(Answer) # protect embedded numbers if {[regexp "\[0-9\]+" $theq(Regexp)]} { set newexp "" set oldexp $theq(Regexp) set theq(Oldexp) $oldexp while {[regexp -indices "(\[0-9\]+)" $oldexp pair]} { set subexp [string range $oldexp [lindex $pair 0] [lindex $pair 1]] set newexp "${newexp}[string range $oldexp -1 [expr [lindex $pair 0] - 1]]" if {[regexp -- $theq(Regexp) $subexp]} { set newexp "${newexp}(^|\[^0-9\])${subexp}(\$|\[^0-9\])" } else { set newexp "${newexp}${subexp}" } set oldexp "[string range $oldexp [expr [lindex $pair 1] + 1] [string length $oldexp]]" } set newexp "${newexp}${oldexp}" set theq(Regexp) $newexp #mx_log "---- replaced regexp '$theq(Oldexp)' with '$newexp' to protect numbers." } ## set score if {![info exists theq(Score)]} { set theq(Score) 1 } ## obfs question (answer script stopper) # [pending] done elsewhere ##set theq(Question) [mx_obfs $theq(Question)] ## set category ## set anum [lsearch -exact $alist "Category"] ## if {![info exists theq(Category)} { ## set theq(Category) "unknown" ##} ## initialize tiplist set anum 0 set tiplist "" while {[info exists theq(Tip$anum)]} { lappend tiplist $theq(Tip$anum) incr anum } # No tips found? construct standard list if {$anum == 0} { set add "·" # extract area of tip generation tags (side effect sets answer) if {![regsub -all ".*\#(\[^\#\]*\)\#.*" $theq(Answer) "\\1" answer]} { set answer $theq(Answer) } ## use tipcycle from questions or ## generate less tips if all words shorter than $tipcycle if {[info exists theq(Tipcycle)]} { set limit $theq(Tipcycle) } else { set limit $quizconf(tipcycle) ## check if at least one word long enough set tmplist [lsort -command mx_cmp_length -decreasing [split $answer " "]] # not a big word if {[string length [lindex $tmplist 0]] < $quizconf(tipcycle)} { set limit [string length [lindex $tmplist 0]] } } for {set anum 0} {$anum < $limit} {incr anum} { set tiptext "" set letterno 0 for {set i 0} {$i < [string length $answer]} {incr i} { if {([expr [expr $letterno - $anum] % $quizconf(tipcycle)] == 0) || ([regexp "\[- \.,`'\"\]" [string range $answer $i $i] foo])} { set tiptext "$tiptext[string range $answer $i $i]" if {[regexp "\[- \.,`'\"\]" [string range $answer $i $i] foo]} { set letterno -1 } } else { set tiptext "$tiptext$add" } incr letterno } lappend tiplist $tiptext } # reverse tips for numeric questions if {[regexp "^\[0-9\]+$" $answer]} { set foo "" for {set i [expr [llength $tiplist] - 1]} {$i >= 0} {set i [expr $i - 1]} { lappend foo [lindex $tiplist $i] } set tiplist $foo } } ## ## Now print question header and question ## mxirc_serv $channel [mx_get_qtext "short"] set txt "[bannerspace] [botcolor question]" if {[info exists theq(Category)]} { set txt "$txt\($theq(Category)\) $theq(Question)" if {[info exists theq(Category)]} { if {$theq(Category) == "Schätzfragen"} { set txt "$txt \[\00306Ihr habt\00310 $schaetztime \00306Sekunden, um eine Schätzung in arabischen Zahlen abzugeben.\]\003" } } } else { set txt "$txt$theq(Question)" } mxirc_serv $channel $txt set quizstate "asked" set tipno 0 set timeasked [unixtime] global timetypasked set timetypasked [clock clicks -milliseconds] ## set up tip timer utimer $quizconf(tipdelay) mx_timer_tip } } proc mx_quizzer_count {} { global quizconf userlist set qnow [unixtime] set usermax 0 foreach u [lsort -command mx_sortrank [array names userlist]] { array set aa $userlist($u) if {[expr $qnow - $aa(lastspoken)] <= $quizconf(useractivetime)} { incr usermax } } return $usermax } ## A user dislikes the question proc moxquiz_user_revolt {nick host handle channel text} { global revoltlist revoltmax tipno botnick quizstate global userlist RateRunning raterevolt global quizconf ## only accept revolts on the quizchannel if {![mx_str_ieq $channel $quizconf(quizchannel)]} { return } if {$quizstate == "asked" || $RateRunning == 1} { if {$tipno < 1&&$RateRunning!=1} { mxirc_action $channel [mc "does not react on revolts before at least one tip was given."] return } ## ensure that the revolting user has an entry if {![info exists userlist($nick)]} { mx_getcreate_userentry $nick $host } ## calculate people needed to make a revolution (50% of active users) mx_log "--- a game runs, !revolt. revoltmax = $revoltmax" if {$revoltmax == 0} { set now [unixtime] foreach u [array names userlist] { array set afoo $userlist($u) if {[expr $now - $afoo(lastspoken)] <= $quizconf(useractivetime)} { incr revoltmax } } mx_log "---- active people are $revoltmax" # one and two player shoud revolt "both" if {$revoltmax > 2} { set revoltmax [expr int(ceil(double($revoltmax) / 2))] } mx_log "---- people needed for a successful revolution: $revoltmax" } # records known users dislike if {[info exists userlist($nick)]} { array set anarray $userlist($nick) set hostmask $anarray(mask) if {[lsearch -exact $revoltlist $hostmask] == -1} { #mxirc_quick_notc $nick [mc "Since you are revolting, you will be ignored for this question."] if {[llength $revoltlist] < $revoltmax && $revoltmax > 0} { mxirc_quick_action $channel [mc "sees that %s and %d other dislike the question, you need %d people." \ $nick [llength $revoltlist] $revoltmax] } lappend revoltlist $hostmask set anarray(lastspoken) [unixtime] set userlist($nick) [array get anarray] mx_log "--- $nick is revolting, revoltmax is $revoltmax" mx_statslog "revolt" [list [unixtime] $nick [llength $revoltlist] $revoltmax] } } if {[llength $revoltlist] >= $revoltmax} { set revoltmax 0 mx_log "--- solution forced by revolting." mx_statslog "revoltsolve" [list [unixtime] $revoltmax] #mxirc_action $channel [mc "will solve the question immediately."] if {$RateRunning != 0} { foreach t [utimers] { set tname [lindex $t 1] if {[lindex $t 1] == "RateTimeUp"||[lindex $t 1] == "RateDisplayRemainingTime"||[lindex $t 1] == "Rate_ShowResults"||[regexp $tname "Rate"]} { killutimer [lindex $t 2] } } RateTimesUp set revoltlist "" set revoltmax 0 set vokspamvar 0 set raterevolt 1 } else { moxquiz_solve $botnick 0 {} } } } } ## solve question proc moxquiz_solve {handle idx arg} { global quizstate theq banner bannerspace global botnick lastsolvercount lastsolver timeasked global quizconf variable txt variable answer if {$quizstate != "asked"} { mxirc_dcc $idx "There is no open question." } else { mx_answered set lastsolver "" set lastsolvercount 0 if {[mx_str_ieq $botnick $handle]} { set txt [mc "%sAutomatically solved after %s." \ "[banner] [botcolor boldtxt]" [mx_duration $timeasked]] } else { set txt [mc "%sManually solved after %s by %s" \ "[banner] [botcolor boldtxt]" [mx_duration $timeasked] $handle] } mxirc_serv $quizconf(quizchannel) $txt # remove area of tip generation tags regsub -all "\#(\[^\#\]*\)\#" $theq(Answer) "\\1" answer mxirc_say $quizconf(quizchannel) [mc "%sThe answer is:%s%s" \ "[bannerspace] [botcolor txt]" "[botcolor norm] [botcolor answer]" $answer] # remove protection of numbers from regexp if {[info exists theq(Oldexp)]} { set theexp $theq(Oldexp) } else { set theexp $theq(Regexp) } #if {$answer != $theexp} { # mxirc_say $quizconf(quizchannel) [mc "%sAnd should match:%s%s" \ # "[bannerspace] [botcolor txt]" "[botcolor norm] [botcolor answer]" $theexp] #} mx_log "--- solved by $handle manually." # schedule ask utimer $quizconf(askdelay) mx_timer_ask } return 1 } ## show a tip proc moxquiz_tip {handle idx arg} { global tipno quizstate banner bannerspace global botnick tiplist global quizconf theq if {[info exists theq(Category)]} { if {$theq(Category) == "Schätzfragen"} { return } } if {$quizstate == "asked"} { if {$arg != ""} { mxirc_dcc $idx "Extra tip \'$arg\' will be given." set tiplist [linsert $tiplist $tipno $arg] } if {$tipno == [llength $tiplist]} { # enough tips, solve! set tipno 0 moxquiz_solve $botnick 0 {} } else { set tiptext [lindex $tiplist $tipno] mxirc_say $quizconf(quizchannel) [mc "%sHint %d:" "[banner] [botcolor boldtxt]" [expr $tipno + 1]] mxirc_say $quizconf(quizchannel) "[bannerspace] [botcolor tip]$tiptext" foreach j [utimers] { if {[lindex $j 1] == "mx_timer_tip"} { killutimer [lindex $j 2] } } mx_log "----- Tip number $tipno: $tiptext" # only short delay after last tip incr tipno if {$tipno == [llength $tiplist]} { utimer 15 mx_timer_tip } else { utimer $quizconf(tipdelay) mx_timer_tip } } } else { mxirc_dcc $idx "Sorry, no question is open." } return 1 } ## schedule a userquest proc moxquiz_userquest {nick host handle arg} { global userqlist ignore_for_userquest global quizconf usebadwords badwords variable uanswer "" uquestion "" umatch "" variable tmptext "" if {$quizconf(userquestions) == "no"} { mxirc_notc $nick [mc "Sorry, userquestions are disabled."] return } if {[lsearch $ignore_for_userquest [string tolower $nick]] != -1 || [lsearch $ignore_for_userquest [maskhost $host]] != -1} { mxirc_notc $nick "Sorry, you are not allowed to post userquestions at this time." return } if {![onchan $nick $quizconf(quizchannel)]} { mxirc_notc $nick [mc "Sorry, you MUST be in the quizchannel to ask questions."] } else { if {[mx_userquests_available] >= $quizconf(userqbufferlength)} { mxirc_notc $nick [mc "Sorry, there are already %d user questions scheduled. Try again later." $quizconf(userqbufferlength)] } elseif {[info exists usebadwords] && $usebadwords && [regexp -nocase "([join $badwords, "|"])" $arg]} { mxirc_notc $nick [mc "Sorry, your userquest would trigger the badwords detection and will not be asked."] } else { set arg [mx_strip_colors $arg] if {$quizconf(stripumlauts) == "yes"} { set arg [mx_tweak_umlauts $arg] } if {[regexp "^(.+)::(.+)::(.+)$" $arg foo uquestion uanswer umatch] || \ [regexp "(.+)::(.+)" $arg foo uquestion uanswer]} { set uquestion [string trim $uquestion] set uanswer [string trim $uanswer] set alist [list "Question" "$uquestion" "Answer" "$uanswer" "Author" "$nick" "Date" [ctime [unixtime]] "TipGiven" "no"] if {$umatch != ""} { set umatch [string trim $umatch] lappend alist "Regexp" "$umatch" set tmptext [mc " (regexp \"%s\")" $umatch] } lappend userqlist $alist mxirc_notc $nick [mc "Your quest \"%s\" is scheduled with answer \"%s\"%s and will be asked after %d questions." \ $uquestion $uanswer $tmptext [expr [mx_userquests_available] - 1]] mx_log "--- Userquest scheduled by $nick: \"$uquestion\"." } else { mxirc_notc $nick [mc "Wrong number of parameters. Use alike <question>::<answer>::<regexp>. The regexp is optional and used with care."] mxirc_notc $nick [mc "You said: \"%s\". I recognize this as: \"%s\" and \"%s\", regexp: \"%s\"." \ $arg $uquestion $uanswer $umatch] mx_log "--- userquest from $nick failed with: \"$arg\"" } } } return } ## usertip proc moxquiz_usertip {nick host handle arg} { global quizstate usergame theq global quizconf if {[onchan $nick $quizconf(quizchannel)]} { mx_log "--- Usertip requested by $nick: \"$arg\"." if {$quizstate == "asked" && $usergame == 1} { if {[info exists theq(Author)] && ![mx_str_ieq $nick $theq(Author)]} { mxirc_notc $nick [mc "No, only %s can give tips here!" $theq(Author)] } else { moxquiz_tip $nick 0 $arg if {$arg != ""} { set theq(TipGiven) "yes" } } } else { mxirc_notc $nick [mc "No usergame running."] } } else { mxirc_notc $nick [mc "Sorry, you MUST be in the quizchannel to give tips."] } return 1 } ## usersolve proc moxquiz_usersolve {nick host handle arg} { global quizstate usergame theq mx_log "--- Usersolve requested by $nick." if {$quizstate == "asked" && $usergame == 1} { if {[info exists theq(Author)] && ![mx_str_ieq $nick $theq(Author)]} { mxirc_notc $nick [mc "No, only %s can solve this question!" $theq(Author)] } else { moxquiz_solve $nick 0 {} } } else { mxirc_notc $nick [mc "No usergame running."] } return 1 } bind msg - !adver mx_adver ## advertisement proc mx_adver {nick host handle arg} { global botnick global quizconf mxirc_say $quizconf(quizchannel) "[bannerspace] and can be downloaded from http://meta-x.de/moxquizz" return 0 } ## usercancel proc moxquiz_usercancel {nick host handle arg} { global quizstate usergame theq userqnumber userqlist mx_log "--- Usercancel requested by $nick." if {$quizstate == "asked" && $usergame == 1} { if {[info exists theq(Author)] && ![mx_str_ieq $nick $theq(Author)]} { mxirc_notc $nick [mc "No, only %s can cancel this question!" $theq(Author)] } else { mxirc_notc $nick [mc "Your question is canceled and will be solved."] set theq(Comment) "canceled by user" moxquiz_solve "user canceling" 0 {} } } elseif {[mx_userquests_available]} { array set aq [lindex $userqlist $userqnumber] if {[mx_str_ieq $aq(Author) $nick]} { mxirc_notc $nick [mc "Your question \"%s\" will be skipped." $aq(Question)] set aq(Comment) "canceled by user" set userqlist [lreplace $userqlist $userqnumber $userqnumber [array get aq]] incr userqnumber } else { mxirc_notc $nick [mc "Sorry, the next question is by %s." $aq(Author)] } } else { mxirc_notc $nick [mc "No usergame running."] } return 1 } ## ignore nick!*@* and *!ident@*.subdomain.domain for userquests for 45 minutes proc moxquiz_userquest_ignore {nick host handle channel arg} { global quizconf ignore_for_userquest regsub -all " +" [string trim $arg] " " arg variable nicks [split $arg] variable n for {set pos 0} {$pos < [llength $nicks]} {incr pos} { set n [string tolower [lindex $nicks $pos]] mxirc_notc $nick "Ignoring userquestions from $n for 45 minutes." lappend ignore_for_userquest $n if {[onchan $n $quizconf(quizchannel)]} { lappend ignore_for_userquest [maskhost [getchanhost $n $quizconf(quizchannel)]] } else { lappend ignore_for_userquest "-!-@-" } } timer 45 mx_timer_userquest_ignore_expire return 1 } ## unignore nick!*@* and *!ident@*.subdomain.domain for userquests for 45 minutes proc moxquiz_userquest_unignore {nick host handle channel arg} { ## replace each [split $arg] and associated hostmask with some impossible values global quizconf ignore_for_userquest regsub -all " +" [string trim $arg] " " arg variable nicks [split $arg] variable n for {set pos 0} {$pos < [llength $nicks]} {incr pos} { set n [string tolower [lindex $nicks $pos]] set listpos [lsearch -exact $ignore_for_userquest $n] if {$listpos != -1} { set ignore_for_userquest [lreplace $ignore_for_userquest $listpos [expr $listpos + 1] "@" "-!-@-"] mxirc_notc $nick "User $n removed from ignore list for userquestions." } else { mxirc_notc $nick "User $n was not in the ignore list for userquestions." } } return 1 } ## lists current names on ignore for userquestions proc moxquiz_userquest_clearignores {nick host handle channel arg} { variable ignore_for_userquest for {set pos 0} {$pos < [llength $ignore_for_userquest]} {incr pos 2} { set ignore_for_userquest [lreplace $ignore_for_userquest $pos [expr $pos + 1] "@" "-!-@-"] } mxirc_notc $nick "Cleared ignore list for userquestions." return 1 } ## lists current names on ignore for userquestions proc moxquiz_userquest_listignores {nick host handle channel arg} { variable ignore_for_userquest variable nicks "" for {set pos 0} {$pos < [llength $ignore_for_userquest]} {incr pos 2} { if {[lindex $ignore_for_userquest $pos] != "@"} { lappend nicks [lindex $ignore_for_userquest $pos] } } if {$nicks != ""} { mxirc_notc $nick "Currently ignored for userquestions: $nicks" } else { mxirc_notc $nick "Currently ignoring nobody for userquestions." } return 1 } ## removes the first two elements from ignore_for_userquest (nick and mask) proc mx_timer_userquest_ignore_expire {} { global ignore_for_userquest set ignore_for_userquest [lreplace $ignore_for_userquest 0 1] } ## pubm !score to report scores proc moxquiz_pub_score {nick host handle channel arg} { global alltimestarsarray allstarsarray userlist global quizconf variable allstarspos variable pos 0 variable target variable self 0 if {![mx_str_ieq $channel $quizconf(quizchannel)]} { return 0 } else { set arg [string trim "$arg"] if {$arg != "" && $arg != $nick} { set target $arg } else { set target $nick set self 1 } # report rank entries if {[info exists userlist($targ