TriviaEngine-sqlite.tcl 33 KB

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