TriviaEngine-sqlite.tcl 35 KB

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