TriviaEngine-sqlite.tcl 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398
  1. # The trivia engine YAY
  2. # vim: foldmethod=marker:foldcolumn=2:foldmarker=<<<,>>>:sw=2:ts=2
  3. ### INIT <<<
  4. package require sqlite
  5. # the channel to play in
  6. set trivia_channel "#triviacow"
  7. # the time between hints (sec)
  8. set trivia_speed 20
  9. # the time between rounds (sec)
  10. set trivia_delay 30
  11. # hold the current question info <<<
  12. set trivia_q_id ""
  13. set trivia_q_cat ""
  14. set trivia_q_question ""
  15. set trivia_q_answer ""
  16. set trivia_q_hint ""
  17. set trivia_q_attempts 0
  18. set trivia_unanswered 0
  19. set trivia_run_last 0
  20. set trivia_run_qty 0
  21. set trivia_run_nick ""
  22. set trivia_guesser ""
  23. set trivia_guesser_count 0
  24. set trivia_last_qid 0
  25. if [info exists trivia_must_rehash] {
  26. if {$trivia_must_rehash == 1} {
  27. set trivia_must_rehash 2
  28. } else {
  29. set trivia_must_rehash 0
  30. }
  31. } else {
  32. set trivia_must_rehash 0
  33. }
  34. #>>>
  35. # 0 = off
  36. # 1 = on
  37. # -1 = disabled
  38. set trivia_status 0
  39. set trivia_timer ""
  40. set trivia_watchdog_timer ""
  41. set trivia_last_ts 0
  42. #colours <<<
  43. set trivia_c(off) "\003"
  44. set trivia_c(red) "\0034"
  45. set trivia_c(blue) "\0033"
  46. set trivia_c(purple) "\0036"
  47. set trivia_c(bold) "\002"
  48. #>>>
  49. bind pubm - * trivia_input
  50. bind msg - trivia trivia_msg
  51. # connect database <<<
  52. proc trivia_connect { } {
  53. global trivia_db_handle
  54. sqlite3 trivia_db_handle trivia.db
  55. }
  56. #>>>
  57. #>>>
  58. ### SETTINGS <<<
  59. set trivia_flag T
  60. set trivia_admin S
  61. # >>>
  62. # Handle a /msg
  63. proc trivia_msg { nick host handle cmd } {
  64. #<<<
  65. global trivia_db_handle trivia_last_qid
  66. global trivia_q_cat trivia_c
  67. regsub "(trivia )" $cmd "" cmd
  68. putlog "trivia: msg command $cmd from $nick"
  69. if {($nick == "Greeneyez") || ($nick == "JamesOff")} {
  70. #<<< set a question's category
  71. if [regexp -nocase "^setcat (.+)" $cmd matches category] {
  72. if {$trivia_last_qid == 0} {
  73. puthelp "PRIVMSG $nick :Can't fathom last question, unable to update category"
  74. return
  75. }
  76. set orig_cat $category
  77. set category [trivia_sqlite_escape $category]
  78. set sql "SELECT cat_id FROM categories WHERE cat_name='$category'"
  79. set cat_id 0
  80. set cat_id [trivia_db_handle eval $sql]
  81. if {$cat_id != 0} {
  82. puthelp "PRIVMSG $nick :Moving question $trivia_last_qid to category$trivia_c(purple) $category$trivia_c(off) ($cat_id)"
  83. set sql "UPDATE questions SET cat_id='$cat_id' WHERE question_id='$trivia_last_qid'"
  84. trivia_db_handle eval $sql
  85. set trivia_q_cat $orig_cat
  86. return
  87. } else {
  88. puthelp "PRIVMSG $nick :Creating new category$trivia_c(purple) $category"
  89. set sql "INSERT INTO categories VALUES (null, '$category', 1)"
  90. trivia_db_handle eval $sql
  91. set cat_id [trivia_db_handle last_insert_rowid]
  92. puthelp "PRIVMSG $nick :Moving question $trivia_last_qid to category$trivia_c(purple) $category$trivia_c(off) ($cat_id)"
  93. set sql "UPDATE questions SET cat_id='$cat_id' WHERE question_id='$trivia_last_qid'"
  94. trivia_db_handle eval $sql
  95. set trivia_q_cat $orig_cat
  96. return
  97. }
  98. }
  99. #>>>
  100. #<<< handle reports
  101. if [regexp -nocase {^report (help|list|fix|view|done)?( .+)?} $cmd matches func arg] {
  102. if {($func == "") || ($func == "help")} {
  103. puthelp "PRIVMSG $nick :Use: report (list|view|fix|done)"
  104. puthelp "PRIVMSG $nick :report list: see 10 reports"
  105. puthelp "PRIVMSG $nick :report view <id>: see the question and answer associated with a report"
  106. puthelp "PRIVMSG $nick :report fix <id> (question|answer) <new text>: update a question or answer"
  107. puthelp "PRIVMSG $nick :report done <id>: mark a report as done"
  108. return 0
  109. }
  110. if {$func == "list"} {
  111. putserv "PRIVMSG $nick :Gathering 10 trivia reports..."
  112. set sql "SELECT * FROM reports WHERE resolved = 'N' LIMIT 10"
  113. trivia_db_handle eval $sql result {
  114. putserv "PRIVMSG $nick :$result(report_id): [format %10s $result(who)] $result(message)"
  115. }
  116. return 0
  117. }
  118. if {$func == "view"} {
  119. if {$arg == ""} {
  120. puthelp "PRIVMSG $nick :Use: report view <id>"
  121. return 0
  122. }
  123. set arg [string trim $arg]
  124. set arg [trivia_sqlite_escape $arg]
  125. set sql "SELECT * FROM reports, questions WHERE report_id = '$arg' AND reports.question_id = questions.question_id"
  126. trivia_db_handle eval $sql result {
  127. putserv "PRIVMSG $nick :Report$trivia_c(purple) $result(report_id) $trivia_c(off)by$trivia_c(purple) $result(who) $trivia_c(off)on$trivia_c(blue) [clock format $result(when) -gmt 1]"
  128. putserv "PRIVMSG $nick :Question: $result(question)"
  129. putserv "PRIVMSG $nick : Answer: $result(answer)"
  130. putserv "PRIVMSG $nick : Report: $result(message)"
  131. }
  132. return 0
  133. }
  134. if {$func == "fix"} {
  135. set arg [string trim $arg]
  136. if [regexp -nocase {([0-9]+) (question|answer) (.+)} $arg matches report_id thing fix] {
  137. putserv "PRIVMSG $nick :Attempting to fix $trivia_c(purple)$thing$trivia_c(off) from report$trivia_c(purple) $report_id"
  138. #get question ID for this report
  139. set sql "SELECT question_id FROM reports WHERE report_id = '$report_id'"
  140. putloglev d * $sql
  141. set question_id 0
  142. trivia_db_handle eval $sql result {
  143. set question_id $result(question_id)
  144. }
  145. if {$question_id == 0} {
  146. putserv "PRIVMSG $nick :I can't seem to find that report, sorry :("
  147. return 0
  148. }
  149. set fix [trivia_sqlite_escape $fix]
  150. set sql "UPDATE questions SET $thing = '$fix' WHERE question_id = '$question_id'"
  151. putloglev d * $sql
  152. trivia_db_handle eval $sql
  153. putserv "PRIVMSG $nick :Updated!"
  154. return 0
  155. } else {
  156. puthelp "PRIVMSG $nick :Use: report fix <id> (question|answer) <new text>"
  157. return 0
  158. }
  159. }
  160. if {$func == "done"} {
  161. set arg [string trim $arg]
  162. set arg [trivia_sqlite_escape $arg]
  163. putserv "PRIVMSG $nick :Marking report$trivia_c(purple) $arg $trivia_c(off)as done."
  164. set sql "UPDATE reports SET resolved = 'Y' WHERE report_id = '$arg'"
  165. putloglev d * $sql
  166. trivia_db_handle eval $sql
  167. return 0
  168. }
  169. if {$func == "delete"} {
  170. set arg [string trim $arg]
  171. set arg [trivia_sqlite_escape $arg]
  172. putserv "PRIVMSG $nick :Deleting question from report$trivia_c(purple) $arg $trivia_c(off) and marking report as done."
  173. set sql "DELETE FROM questions WHERE question_id IN (SELECT question_id FROM reports WHERE report_id = '$arg')"
  174. putloglev d * $sql
  175. trivia_db_handle eval $sql
  176. set sql "UPDATE reports SET resoved = 'Y' WHERE report_id = '$arg'"
  177. putloglev d * $sql
  178. trivia_db_handle eval $sql
  179. return 0
  180. }
  181. #>>>
  182. }
  183. }
  184. #>>>
  185. # Handle input coming from a channel
  186. proc trivia_input { nick host handle channel arg } {
  187. #<<<
  188. global trivia_channel trivia_status trivia_q_answer
  189. global trivia_guesser_count trivia_guesser trivia_c
  190. if {[string tolower $trivia_channel] != [string tolower $channel]} {
  191. return 0
  192. }
  193. if [regexp -nocase "^!t(rivia)? (.+)" $arg matches cmd param] {
  194. trivia_command $nick $host $handle $channel $param
  195. return 0
  196. }
  197. if [regexp -nocase "^!t(rivia)?$" $arg] {
  198. if {$trivia_status == 1} {
  199. puthelp "PRIVMSG $trivia_channel :!trivia ... ?"
  200. return 0
  201. } else {
  202. puthelp "PRIGMSG $trivia_channel :Perhaps you want $trivia_c(purple)!trivia start"
  203. return 0
  204. }
  205. }
  206. # need to be running below here
  207. if {$trivia_status == -1} {
  208. return 0
  209. }
  210. if {$trivia_q_answer == ""} {
  211. return 0
  212. }
  213. #see if someone else is playing
  214. if {($nick == $trivia_guesser) && ($nick != "NoTopic")} {
  215. incr trivia_guesser_count
  216. putloglev d * "$nick has talked $trivia_guesser_count times in a row..."
  217. } else {
  218. set trivia_guesser_count 0
  219. set trivia_guesser $nick
  220. }
  221. #tidy the string up
  222. set arg [string tolower $arg]
  223. set arg [string trim $arg]
  224. if {$arg == [string tolower $trivia_q_answer]} {
  225. # try to stop any other output
  226. clearqueue server
  227. trivia_correct $nick
  228. return 0
  229. }
  230. #if they didn't get it right, and it's been more than 20 lines, taunt!
  231. if {($trivia_guesser_count > 0) && (($trivia_guesser_count % 20)) == 0} {
  232. putserv "PRIVMSG $trivia_channel :Playing with yourself, $nick? ;)"
  233. putlog "Is $nick playing with themselves?"
  234. }
  235. }
  236. #>>>
  237. # Someone got it right!
  238. proc trivia_correct { nick } {
  239. #<<<
  240. global trivia_q_id trivia_q_cat trivia_q_question trivia_q_answer trivia_q_hint trivia_q_attempts trivia_channel trivia_status
  241. global trivia_timer trivia_delay trivia_db_handle trivia_unanswered trivia_run_qty trivia_run_last trivia_run_nick trivia_c
  242. if {$trivia_status != 1} {
  243. #something strange going on
  244. return 0
  245. }
  246. trivia_killtimer
  247. set answer $trivia_q_answer
  248. set trivia_q_answer ""
  249. set newuser 0
  250. set uid [trivia_get_uid $nick]
  251. if {$uid == 0} {
  252. putlog "$nick does not have entry in database... creating"
  253. set uid [trivia_create_user $nick]
  254. set newuser 1
  255. }
  256. putlog "$nick has uid $uid"
  257. trivia_incr_score $uid
  258. putquick "PRIVMSG $trivia_channel :Congratulations $trivia_c(purple)$nick$trivia_c(off)! The answer was$trivia_c(purple) $answer$trivia_c(off)."
  259. if {$newuser == 1} {
  260. putquick "PRIVMSG $trivia_channel :Welcome to our newest player, $trivia_c(purple)$nick$trivia_c(off) :)"
  261. }
  262. putquick "PRIVMSG $trivia_channel :rank0rs: [trivia_near_five2 $uid]"
  263. #set score [trivia_get_score $uid]
  264. #putserv "PRIVMSG $trivia_channel :$nick now has $score points."
  265. set trivia_timer [utimer $trivia_delay trivia_start_round]
  266. set trivia_unanswered 0
  267. if {$trivia_run_last == $uid} {
  268. incr trivia_run_qty
  269. if {$trivia_run_qty > 2} {
  270. putquick "PRIVMSG $trivia_channel :$nick [trivia_get_run $trivia_run_qty] $trivia_run_qty in a row!"
  271. }
  272. } else {
  273. #end of streak
  274. if {$trivia_run_qty > 2} {
  275. putquick "PRIVMSG $trivia_channel :$nick ended $trivia_run_nick's winning spree."
  276. }
  277. set trivia_run_qty 1
  278. set trivia_run_last $uid
  279. set trivia_run_nick $nick
  280. }
  281. if {[rand 100] > 95} {
  282. putserv "PRIVMSG $trivia_channel :Remember, to report a problem with a question or answer, type $trivia_c(purple)!trivia report <description of problem>"
  283. }
  284. trivia_check_rehash
  285. }
  286. #>>>
  287. #See if we need to rehash
  288. proc trivia_check_rehash { } {
  289. #<<<
  290. global trivia_must_rehash trivia_channel trivia_c
  291. if {$trivia_must_rehash == 1} {
  292. putquick "PRIVMSG $trivia_channel :$trivia_c(red)### Please wait, reloading trivia script ###"
  293. trivia_killtimer
  294. rehash
  295. }
  296. }
  297. #>>>
  298. # Turn a winning spree into text
  299. proc trivia_get_run { row } {
  300. #<<<
  301. switch $row {
  302. 3 {
  303. return "is on a winning spree!"
  304. }
  305. 5 {
  306. return "is on a rampage!"
  307. }
  308. 6 {
  309. return "is unstoppable!"
  310. }
  311. 8 {
  312. return "is on a Google spree!"
  313. }
  314. 10 {
  315. return "is GODLIKE!"
  316. }
  317. 12 {
  318. return "needs to get out more."
  319. }
  320. }
  321. return "is on a roll ..."
  322. }
  323. #>>>
  324. # Escape stuff for SQL
  325. proc trivia_sqlite_escape { text } {
  326. return [string map {' ''} $text]
  327. }
  328. # Get someone's user ID from their nick
  329. proc trivia_get_uid { nick } {
  330. #<<<
  331. global trivia_db_handle
  332. putloglev 4 * "trivia_get_uid ($nick)"
  333. set nick [trivia_sqlite_escape $nick]
  334. set sql "SELECT user_id FROM users WHERE user_name = '$nick'"
  335. trivia_db_handle eval $sql {
  336. return $user_id
  337. }
  338. return 0
  339. }
  340. #>>>
  341. # Get a period
  342. proc trivia_get_period { } {
  343. #<<<
  344. return [expr [clock scan "last friday 23:59" -gmt true] + 60]
  345. }
  346. #>>>
  347. # Get a score from a UID
  348. proc trivia_get_score { user_id } {
  349. #<<<
  350. global trivia_db_handle
  351. putloglev 4 * "trivia_get_score ($user_id)"
  352. set dt [trivia_get_period]
  353. set sql "SELECT COUNT(*) AS yarr FROM scores WHERE dt > '$dt' AND user_id='$user_id'"
  354. trivia_db_handle eval $sql {
  355. return $yarr
  356. }
  357. return 0
  358. }
  359. #>>>
  360. # Turn a timestamp into a date
  361. proc trivia_ts_to_date { ts } {
  362. #<<<
  363. return [clock format $ts -format "%Y/%m/%d %H:%M"]
  364. }
  365. #>>>
  366. # Get someone's userinfo from their UID
  367. proc trivia_get_userinfo { user_id } {
  368. #<<<
  369. global trivia_db_handle
  370. putloglev 4 * "trivia_get_userinfo ($user_id)"
  371. set sql "SELECT user_score, user_last, user_reg FROM users WHERE user_id = '$user_id'"
  372. trivia_db_handle eval $sql {
  373. if {$user_last == ""} {
  374. set last "Unknown"
  375. } else {
  376. set last [trivia_ts_to_date $user_last]
  377. }
  378. if {$user_reg == ""} {
  379. set reg "Unkown"
  380. } else {
  381. set reg [trivia_ts_to_date $user_reg]
  382. }
  383. return "$user_score|$last|$reg"
  384. }
  385. return "No stats"
  386. }
  387. #>>>
  388. # Get someone's stats from their username
  389. proc trivia_user_stats { user_name } {
  390. #<<<
  391. global trivia_channel
  392. set uid [trivia_get_uid $user_name]
  393. if {$uid == 0} {
  394. putserv "PRIVMSG $trivia_channel :Unknown user '$user_name'"
  395. return
  396. }
  397. set stats [trivia_get_userinfo $uid]
  398. if {$stats == "No stats"} {
  399. putserv "PRIVMSG $trivia_channel :No stats available."
  400. return
  401. }
  402. set stats2 [split $stats "|"]
  403. putserv "PRIVMSG $trivia_channel :Trivia stats for $user_name:"
  404. putserv "PRIVMSG $trivia_channel : Current score: [lindex $stats2 0]"
  405. putserv "PRIVMSG $trivia_channel : Ranking: [trivia_get_rank $uid]"
  406. putserv "PRIVMSG $trivia_channel : First seen: [lindex $stats2 2]"
  407. putserv "PRIVMSG $trivia_channel : Last scored: [lindex $stats2 1]"
  408. }
  409. #>>>
  410. # Increase a UID's score
  411. proc trivia_incr_score { id { howmuch 1 } } {
  412. #<<<
  413. global trivia_db_handle
  414. putloglev 4 * "trivia_incr_score ($id, $howmuch)"
  415. set sql "UPDATE users SET user_last = [clock seconds] WHERE user_id = '$id'"
  416. trivia_db_handle eval $sql
  417. set sql "INSERT INTO scores VALUES ('$id', '[clock seconds]')"
  418. trivia_db_handle eval $sql
  419. }
  420. #>>>
  421. # Create a new user
  422. proc trivia_create_user { nick } {
  423. #<<<
  424. global trivia_db_handle
  425. putloglev 4 * "trivia_create_user ($nick)"
  426. set nick [trivia_sqlite_escape $nick]
  427. set sql "INSERT INTO users VALUES (null, '$nick', '', 0, [clock seconds], [clock seconds])"
  428. trivia_db_handle eval $sql
  429. set uid [trivia_db_handle last_insert_rowid]
  430. return $uid
  431. }
  432. #>>>
  433. # Handle a !trivia command
  434. proc trivia_command { nick host handle channel param } {
  435. #<<<
  436. global trivia_channel trivia_status trivia_flag trivia_admin trivia_c
  437. set arg ""
  438. regexp {^([^ ]+)( .+)?$} $param matches cmd arg
  439. set param [string tolower $cmd]
  440. set arg [string trim $arg]
  441. putloglev d * "trivia command: $param from: $nick ($arg)"
  442. if {[matchattr $handle |$trivia_admin $trivia_channel] && ($param != "enable") && ($trivia_status == -1)} {
  443. return 0
  444. }
  445. if [regexp -nocase "^(score|place)( .+)?" $param] {
  446. putserv "PRIVMSG $trivia_channel :[trivia_score $arg $nick]"
  447. if [string match -nocase $nick $arg] {
  448. putserv "PRIVMSG $trivia_channel :(You know putting your own nick is optional, right? :)"
  449. }
  450. return 0
  451. }
  452. if {$param == "top10"} {
  453. putserv "PRIVMSG $trivia_channel :[trivia_get_top10]"
  454. return 0
  455. }
  456. if {$param == "info"} {
  457. trivia_user_stats $arg
  458. return 0
  459. }
  460. if {$param == "start"} {
  461. trivia_start
  462. return 0
  463. }
  464. if {$param == "report"} {
  465. trivia_report $nick $arg
  466. return 0
  467. }
  468. if {![matchattr $handle |$trivia_flag $channel]} {
  469. putserv "PRIVMSG $nick :use: !trivia \[score|top10|start\]"
  470. return 0
  471. }
  472. if {$param == "stop"} {
  473. trivia_stop
  474. return 0
  475. }
  476. if {$param == "skip"} {
  477. trivia_skip $nick
  478. return 0
  479. }
  480. if {$param == "stats"} {
  481. trivia_stats
  482. return 0
  483. }
  484. if {![matchattr $handle |$trivia_admin $channel]} {
  485. putserv "PRIVMSG $nick :use: !trivia \[score|top10|start|stop|skip|stats\]"
  486. return 0
  487. }
  488. if {$param == "disable"} {
  489. trivia_disable
  490. return 0
  491. }
  492. if {$param == "enable"} {
  493. trivia_enable
  494. return 0
  495. }
  496. if {$param == "merge"} {
  497. trivia_merge $nick $arg
  498. #puthelp "PRIGMSG $trivia_channel :Score merging is disabled"
  499. return 0
  500. }
  501. if {$param == "rehash"} {
  502. trivia_rehash
  503. return 0
  504. }
  505. putserv "PRIVMSG $nick :use: !trivia \[start|stop|score|top10|skip|stats|enable|disable|merge\]"
  506. return 0
  507. }
  508. #>>>
  509. # Rehash
  510. proc trivia_rehash { } {
  511. #<<<
  512. global trivia_status trivia_channel trivia_must_rehash
  513. if {$trivia_must_rehash == 1} {
  514. putserv "PRIVMSG $trivia_channel :! Reloading trivia now..."
  515. rehash
  516. return 0
  517. }
  518. if {$trivia_status != 1} {
  519. putserv "PRIVMSG $trivia_channel :! Reloading trivia now..."
  520. rehash
  521. return 0
  522. }
  523. set trivia_must_rehash 1
  524. putserv "PRIVMSG $trivia_channel :Trivia will reload after current round"
  525. }
  526. #>>>
  527. # Disable the script
  528. proc trivia_disable { } {
  529. #<<<
  530. global trivia_status trivia_channel
  531. if {$trivia_status == 1} {
  532. #stop the current game
  533. trivia_stop
  534. }
  535. set trivia_status -1
  536. putserv "PRIVMSG $trivia_channel :Trivia disabled."
  537. return 0
  538. }
  539. #>>>
  540. proc trivia_ping { } {
  541. return
  542. }
  543. # Enable the script
  544. proc trivia_enable {} {
  545. #<<<
  546. global trivia_status trivia_channel trivia_db_handle
  547. set trivia_status 0
  548. putserv "PRIVMSG $trivia_channel :Trivia enabled."
  549. trivia_ping
  550. return 0
  551. }
  552. #>>>
  553. #Make a hint
  554. proc trivia_make_hint { hint answer } {
  555. #<<<
  556. set hint [string toupper $hint]
  557. set answer [string toupper $answer]
  558. set answer_words [split $answer { }]
  559. set final_hint ""
  560. #are we making the very first hint?
  561. if {$hint == ""} {
  562. foreach word $answer_words {
  563. append final_hint [string repeat "_" [string length $word]]
  564. append final_hint " "
  565. }
  566. set final_hint [string trim $final_hint]
  567. #now put the punctuation in
  568. set letters [split $answer {}]
  569. set i 0
  570. foreach letter $letters {
  571. if {![regexp -nocase {[A-Z0-9 ]} $letter]} {
  572. set final_hint [string replace $final_hint $i $i $letter]
  573. }
  574. incr i
  575. }
  576. return [string trim $final_hint]
  577. }
  578. # explode the into words
  579. set hint_words [split $hint { }]
  580. set i 0
  581. foreach word $hint_words {
  582. set answer_word [lindex $answer_words $i]
  583. putloglev 1 * "considering $answer_word ($word)"
  584. #are we on the first iteration?
  585. if [regexp "^_+$" $word] {
  586. #use the first letter
  587. set letters [string length $word]
  588. #don't hint for single-letter words
  589. if {$letters > 1} {
  590. set word [string index $answer_word 0]
  591. append word [string repeat "_" [expr $letters - 1]]
  592. } else {
  593. set word "_"
  594. }
  595. append final_hint "$word "
  596. } else {
  597. #not the first iteration so figure out where the gaps are
  598. set gaps [list]
  599. set letters [split $word {}]
  600. set j 0
  601. foreach letter $letters {
  602. if {$letter == "_"} {
  603. lappend gaps $j
  604. }
  605. incr j
  606. }
  607. if {[llength $gaps] <= 1} {
  608. #eek no letters to replace, or only one gap
  609. putloglev 1 * " insufficient gaps, using $word"
  610. append final_hint "$word "
  611. } else {
  612. #now we pick a random letter position
  613. set pos [trivia_random_element $gaps]
  614. putloglev 1 * " filling in $pos"
  615. set word [string replace $word $pos $pos [string index $answer_word $pos]]
  616. putloglev 1 * " --> $word"
  617. append final_hint "$word "
  618. }
  619. }
  620. incr i
  621. }
  622. set final_hint [string trim $final_hint]
  623. return $final_hint
  624. }
  625. #>>>
  626. # Fetch a question
  627. proc trivia_get_question { } {
  628. #<<<
  629. global trivia_db_handle trivia_q_id trivia_q_cat trivia_q_question trivia_q_answer trivia_q_hint trivia_channel
  630. set trivia_q_id ""
  631. set sql "SELECT q.question, q.question_id, q.answer, c.cat_name FROM questions q LEFT JOIN categories c USING (cat_id) WHERE c.cat_enabled=1 ORDER BY count ASC, random() LIMIT 1"
  632. trivia_db_handle eval $sql {
  633. set trivia_q_id $question_id
  634. set trivia_q_cat $cat_name
  635. set trivia_q_question $question
  636. set trivia_q_answer [string toupper $answer]
  637. set trivia_q_hint ""
  638. #tidy up question and answer
  639. regsub -all " +" $trivia_q_question " " trivia_q_question
  640. regsub -all " +" $trivia_q_answer " " trivia_q_answer
  641. set trivia_q_question [string trim $trivia_q_question]
  642. set trivia_q_answer [string trim $trivia_q_answer]
  643. }
  644. if {$trivia_q_id == ""} {
  645. return
  646. }
  647. #update the times used
  648. set sql "UPDATE questions SET count = count + 1 WHERE question_id = '$trivia_q_id'"
  649. trivia_db_handle eval $sql
  650. }
  651. #>>>
  652. # Start a round
  653. proc trivia_start_round { } {
  654. #<<<
  655. global trivia_q_id trivia_q_cat trivia_q_question trivia_q_answer trivia_q_hint trivia_q_attempts trivia_channel trivia_status trivia_last_qid
  656. if {$trivia_status != 1} {
  657. #we're switched off, abort
  658. return 0
  659. }
  660. #init variables
  661. set trivia_q_id ""
  662. set trivia_q_cat ""
  663. set trivia_q_question ""
  664. set trivia_q_answer ""
  665. set trivia_q_hint ""
  666. putlog "Fetching next question..."
  667. trivia_get_question
  668. if {$trivia_q_id == ""} {
  669. putlog "Couldn't init trivia round, aborting."
  670. return
  671. }
  672. putlog "Successfully fetched question $trivia_q_id from database"
  673. putloglev 4 * "question = $trivia_q_question"
  674. putloglev 4 * "answer = $trivia_q_answer"
  675. set trivia_q_attempts 1
  676. set trivia_last_qid $trivia_q_id
  677. trivia_round
  678. }
  679. #>>>
  680. # Run a round
  681. proc trivia_round { } {
  682. #<<<
  683. global trivia_q_id trivia_q_cat trivia_q_question trivia_q_answer trivia_q_hint trivia_q_attempts trivia_channel trivia_status
  684. global trivia_timer trivia_speed trivia_c trivia_last_ts
  685. if {$trivia_status != 1} {
  686. #we're switched off, abort
  687. return 0
  688. }
  689. if {$trivia_q_attempts == 5} {
  690. trivia_end_round
  691. return 0
  692. }
  693. if {$trivia_q_answer == ""} {
  694. return 0
  695. }
  696. #update the hint
  697. set trivia_q_hint [trivia_make_hint $trivia_q_hint $trivia_q_answer]
  698. #say our stuff
  699. if {$trivia_q_attempts > 1} {
  700. set hint " \[[expr $trivia_q_attempts - 1] of 3\]"
  701. } else {
  702. set hint ""
  703. }
  704. putserv "PRIVMSG $trivia_channel :$trivia_c(red)--== Trivia ==--$trivia_c(off) \[category: \002$trivia_q_cat\002\]"
  705. #\[question id: \002$trivia_q_id\002\]"
  706. set split_question [trivia_question_split $trivia_q_question]
  707. foreach q $split_question {
  708. if {$q != ""} {
  709. putserv "PRIVMSG $trivia_channel :$trivia_c(blue) [trivia_question_inject $q]"
  710. }
  711. }
  712. #set new_question [trivia_question_inject $trivia_q_question]
  713. #putserv "PRIVMSG $trivia_channel :$trivia_c(blue) $new_question"
  714. putserv "PRIVMSG $trivia_channel :Hint$hint: [trivia_explode $trivia_q_hint]"
  715. incr trivia_q_attempts
  716. set trivia_last_ts [clock seconds]
  717. global trivia_must_rehash
  718. if {$trivia_must_rehash != 2} {
  719. set trivia_timer [utimer $trivia_speed trivia_round]
  720. }
  721. }
  722. #>>>
  723. # Make it harder for things to break questions (inject bold codes)
  724. proc trivia_question_inject { question } {
  725. #<<<
  726. putlog "trivia_question_inject $question"
  727. #inject random bold/underline/colour codes into question
  728. global trivia_c
  729. set l [string length $question]
  730. putlog "length: $l"
  731. if {$l < 1} {
  732. return $question
  733. }
  734. set pos [rand $l]
  735. set first [string range $question 0 $pos]
  736. incr pos
  737. set second [string range $question $pos end]
  738. switch [rand 1] {
  739. 0 {
  740. putlog "question_inject: using bold at pos $pos"
  741. return $first$trivia_c(bold)$trivia_c(bold)$second
  742. }
  743. 1 {
  744. putlog "question_inject: using purple at pos $pos"
  745. return $first$trivia_c(purple)$trivia_c(off)$second
  746. }
  747. }
  748. return $question
  749. }
  750. #>>>
  751. # Make it harder for things to break questions (inject line breaks)
  752. proc trivia_question_split { question } {
  753. #<<<
  754. putlog "trivia_question_split $question"
  755. #explodes a question into two lines at word boundaries, if it's long enough
  756. #don't split unscrambles incorrectly
  757. if [regexp -nocase "(unscramble .+:) (\[A-Z \]+)" $question matches first second] {
  758. return [list $first $second]
  759. }
  760. set words [split $question " "]
  761. set wordcount [llength $words]
  762. if {$wordcount < 4} {
  763. putlog "aborting, too short"
  764. return [list $question]
  765. }
  766. #enough words to split
  767. #we want at least two on the first line
  768. putlog "wordcount: $wordcount"
  769. incr wordcount -2
  770. if {$wordcount < 0} {
  771. return [list $question]
  772. }
  773. set pos [rand $wordcount]
  774. incr pos 2
  775. putlog "picked pos $pos"
  776. set wordlist [list]
  777. set i 0
  778. set line ""
  779. foreach word $words {
  780. #putlog "word = $word, i = $i"
  781. append line "$word "
  782. if {$i == $pos} {
  783. #putlog "splitting here, line = $line"
  784. lappend wordlist [string trim $line]
  785. set line ""
  786. }
  787. incr i
  788. }
  789. #putlog "done, appending $line to list"
  790. if {$line != ""} {
  791. lappend wordlist [string trim $line]
  792. }
  793. #putlog "split question list is: $wordlist"
  794. return $wordlist
  795. }
  796. #>>>
  797. # Finish a round (without a winner)
  798. proc trivia_end_round { } {
  799. #<<<
  800. global trivia_q_id trivia_q_cat trivia_q_question trivia_q_answer trivia_q_hint trivia_q_attempts trivia_channel trivia_status
  801. global trivia_timer trivia_delay trivia_db_handle trivia_unanswered
  802. global trivia_run_last trivia_run_nick trivia_run_qty trivia_c
  803. if {$trivia_status != 1} {
  804. #we're switched off, abort
  805. return 0
  806. }
  807. set trivia_q_answer [string toupper $trivia_q_answer]
  808. putquick "PRIVMSG $trivia_channel :Time's up! Nobody got it right. The answer was$trivia_c(purple) $trivia_q_answer"
  809. set trivia_q_answer ""
  810. incr trivia_unanswered
  811. if {$trivia_run_qty > 2} {
  812. putserv "PRIVMSG $trivia_channel :So much for $trivia_run_nick's winning spree."
  813. }
  814. set trivia_run_last 0
  815. set trivia_run_qty 0
  816. set trivia_run_nick ""
  817. if {[rand 100] > 90} {
  818. putserv "PRIVMSG $trivia_channel :Remember, to report a problem with a question or answer, type $trivia_c(purple)!trivia report <description of problem>"
  819. }
  820. if {$trivia_unanswered > 3} {
  821. putserv "PRIVMSG $trivia_channel :Three unanswered in a row, stopping the game."
  822. set trivia_status 0
  823. } else {
  824. set trivia_timer [utimer $trivia_delay trivia_start_round]
  825. trivia_check_rehash
  826. }
  827. }
  828. #>>>
  829. # Skip the rest of this question
  830. proc trivia_skip { nick } {
  831. #<<<
  832. global trivia_q_id trivia_q_cat trivia_q_question trivia_q_answer trivia_q_hint trivia_q_attempts trivia_channel trivia_status
  833. global trivia_timer trivia_delay trivia_db_handle trivia_unanswered
  834. if {$trivia_status != 1} {
  835. #we're switched off, abort
  836. return 0
  837. }
  838. if {$trivia_q_answer == ""} {
  839. #no round in progress
  840. return 0
  841. }
  842. set trivia_q_question ""
  843. set trivia_q_answer ""
  844. trivia_killtimer
  845. putserv "PRIVMSG $trivia_channel :Skipping this question by $nick's request."
  846. set trivia_timer [utimer $trivia_delay trivia_start_round]
  847. }
  848. #>>>
  849. # Utility function to fetch a random item from a list
  850. proc trivia_random_element { l } {
  851. #<<<
  852. return [lindex $l [rand [llength $l]]]
  853. }
  854. #>>>
  855. # Start the game
  856. proc trivia_start { } {
  857. #<<<
  858. global trivia_status trivia_channel trivia_unanswered trivia_run_last trivia_run_qty trivia_c trivia_must_rehash trivia_db_handle
  859. if {$trivia_status == 1} {
  860. putserv "PRIVMSG $trivia_channel :Trivia is already running."
  861. return 0
  862. }
  863. if {$trivia_status == -1} {
  864. putserv "PRIVMSG $trivia_channel :Trivia is currently disabled."
  865. return 0
  866. }
  867. trivia_ping
  868. # go go go
  869. set trivia_status 1
  870. if {$trivia_must_rehash == 2 } {
  871. putquick "PRIVMSG $trivia_channel :$trivia_c(blue)### Resuming trivia game ###" -next
  872. } else {
  873. putquick "PRIVMSG $trivia_channel :Trivia game started!" -next
  874. }
  875. #trivia_stats
  876. set trivia_unanswered 0
  877. set trivia_run_last 0
  878. set trivia_run_qty 0
  879. trivia_start_round
  880. return 0
  881. }
  882. #>>>
  883. # Stop the game
  884. proc trivia_stop { } {
  885. #<<<
  886. global trivia_channel trivia_status
  887. if {$trivia_status == 1} {
  888. putserv "PRIVMSG $trivia_channel :Trivia game stopped."
  889. set trivia_status 0
  890. trivia_killtimer
  891. }
  892. return 0
  893. }
  894. #>>>
  895. # Kill our timer
  896. proc trivia_killtimer { } {
  897. #<<<
  898. global trivia_timer
  899. if {$trivia_timer != ""} {
  900. killutimer $trivia_timer
  901. }
  902. }
  903. #>>>
  904. # Utility function to explode line into letters
  905. proc trivia_explode { line } {
  906. #<<<
  907. set letters [split $line {}]
  908. set newline ""
  909. foreach letter $letters {
  910. append newline "$letter "
  911. }
  912. return [string trim $newline]
  913. }
  914. #>>>
  915. # Get a UID's ranking
  916. proc trivia_get_rank { uid } {
  917. #<<<
  918. global trivia_db_handle
  919. putloglev 4 * "trivia_get_rank ($uid)"
  920. set sql "SELECT user_id FROM users ORDER by user_score DESC"
  921. set dt [trivia_get_period]
  922. set sql "select user_id, count(dt) as d from scores where dt > $dt group by user_id order by d desc"
  923. set pos 0
  924. trivia_db_handle eval $sql {
  925. incr pos
  926. putloglev d * "considering user_id $user_id, score $d"
  927. if {$user_id == $uid} {
  928. return $pos
  929. }
  930. }
  931. return 0
  932. }
  933. #>>>
  934. # Get the top 10 users
  935. proc trivia_get_top10 { } {
  936. #<<<
  937. global trivia_db_handle
  938. set dt [trivia_get_period]
  939. set sql "select users.user_name as u, count(dt) as d from scores left join users using (user_id) where dt > $dt group by scores.user_id order by d desc limit 10"
  940. set output ""
  941. set index 0
  942. trivia_db_handle eval $sql {
  943. incr index
  944. append output "\002$index:\002 "
  945. append output $u
  946. append output " ("
  947. append output $d
  948. append output ") "
  949. }
  950. set output "The top $index players are... $output"
  951. return $output
  952. }
  953. #>>>
  954. # Fix a number into text
  955. proc trivia_ordinal { number } {
  956. #<<<
  957. if [regexp {1[0-9]$} $number] {
  958. return "th"
  959. }
  960. set last [string range $number end end]
  961. if {$last == "1"} {
  962. return "st"
  963. }
  964. if {$last == "2"} {
  965. return "nd"
  966. }
  967. if {$last == "3"} {
  968. return "rd"
  969. }
  970. return "th"
  971. }
  972. #>>>
  973. # Get a score
  974. proc trivia_score { n { nick "" } } {
  975. #<<<
  976. set n [string trim $n]
  977. putloglev 4 * "trivia_score($n, $nick)"
  978. if {$n == ""} {
  979. set ni $nick
  980. set o "You are"
  981. } else {
  982. set ni $n
  983. set o "$n is"
  984. }
  985. set uid [trivia_get_uid $ni]
  986. set score [trivia_get_score $uid]
  987. set pos [trivia_get_rank $uid]
  988. if {$score == 0} {
  989. return "No score found for $n."
  990. }
  991. return "$o ranked $pos[trivia_ordinal $pos] with $score points."
  992. }
  993. #>>>
  994. # Turn a list into a stats list
  995. proc trivia_list_to_stats { pos user_id l } {
  996. #<<<
  997. putloglev 4 * "trivia_list_to_stats ($pos, $user_id, $l)"
  998. global trivia_c
  999. set uid [lindex $l 0]
  1000. set nick [lindex $l 1]
  1001. set score [lindex $l 2]
  1002. incr pos
  1003. set result ""
  1004. if {$user_id == $uid} {
  1005. set result "$trivia_c(purple)$trivia_c(bold)"
  1006. }
  1007. append result "$pos[trivia_ordinal $pos]: $nick ($score) "
  1008. if {$user_id == $uid} {
  1009. append result "$trivia_c(off)$trivia_c(bold)"
  1010. }
  1011. return $result
  1012. }
  1013. #>>>
  1014. # Another function to get the nearest users to your score
  1015. proc trivia_near_five2 { uid } {
  1016. #<<<
  1017. global trivia_db_handle trivia_c
  1018. set sql "SELECT user_id, user_name, user_score FROM users ORDER BY user_score DESC"
  1019. set dt [trivia_get_period]
  1020. set sql "select users.user_id as user_id, users.user_name as user_name, count(dt) as user_score from scores left join users using (user_id) where dt > $dt group by scores.user_id order by count(dt) desc"
  1021. putlog $sql
  1022. set result [list]
  1023. trivia_db_handle eval $sql {
  1024. set line [list]
  1025. lappend line $user_id
  1026. lappend line $user_name
  1027. lappend line $user_score
  1028. putlog "adding line $line"
  1029. lappend result $line
  1030. }
  1031. putlog "results list: $result"
  1032. set position 0
  1033. foreach item $result {
  1034. if {[lindex $item 0] == $uid} {
  1035. putlog "found at position $position"
  1036. break
  1037. }
  1038. incr position
  1039. }
  1040. set line ""
  1041. if {$position > 2} {
  1042. append line [trivia_list_to_stats [expr $position - 2] $uid [lindex $result [expr $position - 2]]]
  1043. }
  1044. if {$position > 1} {
  1045. append line [trivia_list_to_stats [expr $position - 1] $uid [lindex $result [expr $position - 1]]]
  1046. }
  1047. append line [trivia_list_to_stats $position $uid [lindex $result $position]]
  1048. if {$position < [expr [llength $result] - 1]} {
  1049. append line [trivia_list_to_stats [expr $position + 1] $uid [lindex $result [expr $position + 1]]]
  1050. }
  1051. if {$position < [expr [llength $result] - 2]} {
  1052. append line [trivia_list_to_stats [expr $position + 2] $uid [lindex $result [expr $position + 2]]]
  1053. }
  1054. return $line
  1055. }
  1056. #>>>
  1057. # Get some stats from the DB
  1058. proc trivia_stats { } {
  1059. #<<<
  1060. global trivia_db_handle trivia_channel
  1061. set sql "SELECT COUNT(*) AS total FROM questions LEFT JOIN categories USING (cat_id) WHERE categories.cat_enabled = 1;"
  1062. set stat_total_questions [trivia_db_handle eval $sql]
  1063. set sql "SELECT COUNT(*) AS total FROM categories WHERE cat_enabled = 1"
  1064. set stat_total_cats [trivia_db_handle eval $sql]
  1065. putserv "PRIVMSG $trivia_channel :Using\002 $stat_total_questions\002 questions in\002 $stat_total_cats\002 categories."
  1066. }
  1067. #>>>
  1068. # Merge two users
  1069. proc trivia_merge { nick param } {
  1070. #<<<
  1071. global trivia_db_handle
  1072. putloglev 4 * "trivia_merge ($nick, $param)"
  1073. if [regexp {^([^ ]+) (.+)$} $param matches nick1 nick2] {
  1074. set olduid [trivia_get_uid [trivia_sqlite_escape $nick1]]
  1075. set newuid [trivia_get_uid [trivia_sqlite_escape $nick2]]
  1076. if {$olduid == 0} {
  1077. puthelp "PRIVMSG $nick :Can't find user '$nick1'"
  1078. return 0
  1079. }
  1080. if {$newuid == 0} {
  1081. puthelp "PRIVMSG $nick :Can't find user '$nick2'"
  1082. return 0
  1083. }
  1084. puthelp "PRIVMSG $nick :Meging score for $nick1 into score for $nick2"
  1085. set sql "UPDATE scores SET user_id=$newuid WHERE user_id=$olduid"
  1086. trivia_db_handle eval $sql
  1087. set newscore [trivia_get_score $newuid]
  1088. puthelp "PRIVMSG $nick :$nick2 now has $newscore points."
  1089. set sql "DELETE FROM users WHERE user_id = $olduid"
  1090. trivia_db_handle eval $sql
  1091. puthelp "PRIVMSG $nick :User $nick1 has been deleted."
  1092. return 0
  1093. } else {
  1094. puthelp "PRIVMSG $nick :Use: !trivia merge <olduser> <newuser>"
  1095. puthelp "PRIVMSG $nick : olduser's score is merged with newuser's and olduser is deleted."
  1096. }
  1097. }
  1098. #>>>
  1099. # Report a broken question
  1100. proc trivia_report { nick msg } {
  1101. #<<<
  1102. global trivia_channel trivia_db_handle trivia_last_qid trivia_c
  1103. if {$trivia_last_qid == 0} {
  1104. puthelp "PRIVMSG $trivia_channel :Sorry, unable to work out which question to report on :("
  1105. return 0
  1106. }
  1107. set nick [trivia_sqlite_escape $nick]
  1108. set msg [trivia_sqlite_escape $msg]
  1109. set sql "INSERT INTO reports VALUES (null, [clock seconds], '$nick', '$trivia_last_qid', '$msg', 'N')"
  1110. trivia_db_handle eval $sql
  1111. puthelp "PRIVMSG $trivia_channel :Added a report against question ID$trivia_c(purple) $trivia_last_qid$trivia_c(off) from $trivia_c(purple)$nick$trivia_c(off)."
  1112. set trivia_last_qid 0
  1113. }
  1114. #>>>
  1115. ### WATCHDOG STUFF <<<
  1116. # Watchdog timer to make sure we're not ruined
  1117. proc trivia_watchdog { } {
  1118. #<<<
  1119. global trivia_last_ts trivia_watchdog_timer trivia_status trivia_channel
  1120. putloglev d * "trivia watchdog: tick"
  1121. if {$trivia_last_ts == 0} {
  1122. #never asked a question
  1123. set trivia_watchdog_timer [utimer 45 trivia_watchdog]
  1124. return 0
  1125. }
  1126. set current_ts [clock seconds]
  1127. set difference [expr $current_ts - $trivia_last_ts]
  1128. if {$difference > 0} {
  1129. if {$trivia_status == 1} {
  1130. putlog "watchdog: trivia is broken"
  1131. #putserv "PRIVMSG $trivia_channel :Oops, I think I'm broken. Attempting to recover..."
  1132. #set trivia_status 0
  1133. #trivia_start
  1134. putlog "trivia watchdog: current: $current_ts, last: $trivia_last_ts, difference: $difference"
  1135. }
  1136. }
  1137. set trivia_watchdog_timer [utimer 10 trivia_watchdog]
  1138. return 0
  1139. }
  1140. #>>>
  1141. # Kill the watchdog timeer
  1142. proc trivia_killwatchdog { } {
  1143. #<<<
  1144. global trivia_watchdog_timer
  1145. if {$trivia_watchdog_timer != ""} {
  1146. killutimer $trivia_watchdog_timer
  1147. }
  1148. }
  1149. #>>>
  1150. trivia_killwatchdog
  1151. set trivia_watchdog_timer [utimer 45 trivia_watchdog]
  1152. #>>>
  1153. trivia_connect
  1154. putlog {TriviaEngine ENGAGED(*$£&($}
  1155. if {$trivia_must_rehash == 2} {
  1156. putlog "Auto-restarting trivia..."
  1157. trivia_start
  1158. set trivia_must_rehash 0
  1159. }