rbot 0.9.14 → 0.9.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (368) hide show
  1. data/AUTHORS +6 -2
  2. data/REQUIREMENTS +7 -1
  3. data/Rakefile +10 -32
  4. data/bin/rbot +6 -1
  5. data/bin/svnwatch-postcommit-hook +68 -0
  6. data/data/rbot/contrib/plugins/stats.rb +3 -3
  7. data/data/rbot/contrib/plugins/vandale.rb +1 -1
  8. data/data/rbot/filters/rss.rb +72 -0
  9. data/data/rbot/languages/finnish.lang +50 -0
  10. data/data/rbot/plugins/alias.rb +6 -6
  11. data/data/rbot/plugins/autorejoin.rb +41 -2
  12. data/data/rbot/plugins/bans.rb +100 -6
  13. data/data/rbot/plugins/bash.rb +9 -4
  14. data/data/rbot/plugins/cal.rb +1 -1
  15. data/data/rbot/plugins/chucknorris.rb +6 -6
  16. data/data/rbot/plugins/debugger.rb +7 -3
  17. data/data/rbot/plugins/deepthoughts.rb +1 -1
  18. data/data/rbot/plugins/delicious.rb +6 -2
  19. data/data/rbot/plugins/dice.rb +7 -7
  20. data/data/rbot/plugins/dict.rb +4 -3
  21. data/data/rbot/plugins/dictclient.rb +17 -13
  22. data/data/rbot/plugins/digg.rb +3 -3
  23. data/data/rbot/plugins/eightball.rb +1 -1
  24. data/data/rbot/plugins/factoids.rb +13 -4
  25. data/data/rbot/plugins/figlet.rb +4 -4
  26. data/data/rbot/plugins/forecast.rb +3 -3
  27. data/data/rbot/plugins/fortune.rb +14 -8
  28. data/data/rbot/plugins/freshmeat.rb +2 -2
  29. data/data/rbot/plugins/games/azgame.rb +72 -19
  30. data/data/rbot/plugins/games/hangman.rb +499 -0
  31. data/data/rbot/plugins/games/quiz.rb +15 -13
  32. data/data/rbot/plugins/games/roshambo.rb +1 -1
  33. data/data/rbot/plugins/games/roulette.rb +4 -4
  34. data/data/rbot/plugins/games/shiritori.rb +31 -31
  35. data/data/rbot/plugins/games/uno.rb +28 -6
  36. data/data/rbot/plugins/games/wheelfortune.rb +1 -3
  37. data/data/rbot/plugins/geoip.rb +83 -28
  38. data/data/rbot/plugins/googlefight.rb +64 -0
  39. data/data/rbot/plugins/greet.rb +45 -0
  40. data/data/rbot/plugins/grouphug.rb +40 -12
  41. data/data/rbot/plugins/imdb.rb +4 -4
  42. data/data/rbot/plugins/insult.rb +2 -2
  43. data/data/rbot/plugins/karma.rb +6 -5
  44. data/data/rbot/plugins/keywords.rb +26 -22
  45. data/data/rbot/plugins/lart.rb +5 -6
  46. data/data/rbot/plugins/lastfm.rb +488 -125
  47. data/data/rbot/plugins/lib_spotify.rb +84 -0
  48. data/data/rbot/plugins/linkbot.rb +1 -1
  49. data/data/rbot/plugins/markov.rb +567 -78
  50. data/data/rbot/plugins/math.rb +3 -3
  51. data/data/rbot/plugins/modes.rb +1 -1
  52. data/data/rbot/plugins/nickrecover.rb +1 -1
  53. data/data/rbot/plugins/nickserv.rb +7 -7
  54. data/data/rbot/plugins/note.rb +55 -0
  55. data/data/rbot/plugins/nslookup.rb +2 -2
  56. data/data/rbot/plugins/quakeauth.rb +4 -4
  57. data/data/rbot/plugins/quotes.rb +53 -19
  58. data/data/rbot/plugins/reaction.rb +76 -19
  59. data/data/rbot/plugins/remind.rb +3 -96
  60. data/data/rbot/plugins/ri.rb +1 -1
  61. data/data/rbot/plugins/rot13.rb +1 -1
  62. data/data/rbot/plugins/rss.rb +296 -190
  63. data/data/rbot/plugins/salut.rb +8 -8
  64. data/data/rbot/plugins/script.rb +48 -11
  65. data/data/rbot/plugins/search.rb +124 -28
  66. data/data/rbot/plugins/seen.rb +162 -31
  67. data/data/rbot/plugins/shortenurls.rb +1 -1
  68. data/data/rbot/plugins/slashdot.rb +19 -6
  69. data/data/rbot/plugins/spotify.rb +78 -0
  70. data/data/rbot/plugins/theyfightcrime.rb +10 -10
  71. data/data/rbot/plugins/time.rb +2 -2
  72. data/data/rbot/plugins/translator.rb +161 -85
  73. data/data/rbot/plugins/tube.rb +2 -2
  74. data/data/rbot/plugins/tumblr.rb +143 -0
  75. data/data/rbot/plugins/twitter.rb +25 -6
  76. data/data/rbot/plugins/urban.rb +6 -4
  77. data/data/rbot/plugins/url.rb +49 -10
  78. data/data/rbot/plugins/weather.rb +6 -6
  79. data/data/rbot/plugins/wserver.rb +5 -5
  80. data/data/rbot/plugins/youtube.rb +12 -12
  81. data/data/rbot/templates/lart/larts-italian +1 -1
  82. data/launch_here.rb +68 -0
  83. data/lib/rbot/botuser.rb +1 -1
  84. data/lib/rbot/compat19.rb +70 -0
  85. data/lib/rbot/config.rb +8 -6
  86. data/lib/rbot/core/auth.rb +37 -21
  87. data/lib/rbot/core/basics.rb +33 -2
  88. data/lib/rbot/core/config.rb +24 -17
  89. data/lib/rbot/core/filters_ui.rb +2 -2
  90. data/lib/rbot/core/irclog.rb +20 -11
  91. data/lib/rbot/core/remote.rb +9 -9
  92. data/lib/rbot/core/unicode.rb +4 -0
  93. data/lib/rbot/core/userdata.rb +16 -1
  94. data/lib/rbot/core/utils/extends.rb +76 -0
  95. data/lib/rbot/core/utils/filters.rb +47 -0
  96. data/lib/rbot/core/utils/httputil.rb +36 -26
  97. data/lib/rbot/core/utils/parse_time.rb +193 -0
  98. data/lib/rbot/core/utils/utils.rb +81 -56
  99. data/lib/rbot/core/utils/wordlist.rb +66 -0
  100. data/lib/rbot/core/wordlist_ui.rb +27 -0
  101. data/lib/rbot/irc.rb +59 -19
  102. data/lib/rbot/ircbot.rb +190 -58
  103. data/lib/rbot/ircsocket.rb +14 -8
  104. data/lib/rbot/language.rb +4 -3
  105. data/lib/rbot/load-gettext.rb +22 -9
  106. data/lib/rbot/message.rb +89 -18
  107. data/lib/rbot/messagemapper.rb +71 -19
  108. data/lib/rbot/plugins.rb +112 -44
  109. data/lib/rbot/{registry.rb → registry/bdb.rb} +226 -22
  110. data/lib/rbot/registry/tc.rb +531 -0
  111. data/lib/rbot/rfc2812.rb +33 -8
  112. data/lib/rbot/timer.rb +12 -20
  113. data/po/en_US/rbot-autorejoin.po +3 -0
  114. data/po/en_US/rbot-azgame.po +51 -43
  115. data/po/en_US/rbot-bash.po +15 -0
  116. data/po/en_US/rbot-dictclient.po +20 -20
  117. data/po/en_US/rbot-factoids.po +9 -9
  118. data/po/en_US/rbot-geoip.po +0 -0
  119. data/po/en_US/rbot-googlefight.po +24 -0
  120. data/po/en_US/rbot-grouphug.po +4 -4
  121. data/po/en_US/rbot-hangman.po +114 -0
  122. data/po/en_US/rbot-keywords.po +3 -3
  123. data/po/en_US/rbot-lastfm.po +268 -70
  124. data/po/en_US/rbot-markov.po +73 -2
  125. data/po/en_US/rbot-quotes.po +21 -21
  126. data/po/en_US/rbot-rss.po +6 -2
  127. data/po/en_US/rbot-script.po +3 -0
  128. data/po/en_US/rbot-seen.po +72 -0
  129. data/po/en_US/rbot-spell.po +2 -2
  130. data/po/en_US/rbot-translator.po +13 -13
  131. data/po/en_US/rbot-twitter.po +3 -3
  132. data/po/en_US/rbot-uno.po +131 -114
  133. data/po/en_US/rbot-wall.po +12 -13
  134. data/po/en_US/rbot-wheelfortune.po +41 -41
  135. data/po/en_US/rbot.po +254 -194
  136. data/po/fi/rbot-alias.po +82 -0
  137. data/po/fi/rbot-autoop.po +0 -0
  138. data/po/fi/rbot-autorejoin.po +20 -0
  139. data/po/fi/rbot-azgame.po +194 -0
  140. data/po/fi/rbot-bans.po +0 -0
  141. data/po/fi/rbot-bash.po +32 -0
  142. data/po/fi/rbot-botsnack.po +0 -0
  143. data/po/fi/rbot-cal.po +20 -0
  144. data/po/fi/rbot-chanserv.po +0 -0
  145. data/po/fi/rbot-chucknorris.po +0 -0
  146. data/po/fi/rbot-debugger.po +0 -0
  147. data/po/fi/rbot-deepthoughts.po +0 -0
  148. data/po/fi/rbot-delicious.po +0 -0
  149. data/po/fi/rbot-dice.po +0 -0
  150. data/po/fi/rbot-dict.po +0 -0
  151. data/po/fi/rbot-dictclient.po +111 -0
  152. data/po/fi/rbot-digg.po +0 -0
  153. data/po/fi/rbot-eightball.po +0 -0
  154. data/po/fi/rbot-excuse.po +0 -0
  155. data/po/fi/rbot-factoids.po +107 -0
  156. data/po/fi/rbot-figlet.po +36 -0
  157. data/po/fi/rbot-fish.po +0 -0
  158. data/po/fi/rbot-forecast.po +0 -0
  159. data/po/fi/rbot-fortune.po +0 -0
  160. data/po/fi/rbot-freshmeat.po +0 -0
  161. data/po/fi/rbot-geoip.po +0 -0
  162. data/po/fi/rbot-googlefight.po +24 -0
  163. data/po/fi/rbot-grouphug.po +35 -0
  164. data/po/fi/rbot-hangman.po +121 -0
  165. data/po/fi/rbot-hl2.po +0 -0
  166. data/po/fi/rbot-host.po +20 -0
  167. data/po/fi/rbot-imdb.po +0 -0
  168. data/po/fi/rbot-insult.po +0 -0
  169. data/po/fi/rbot-iplookup.po +0 -0
  170. data/po/fi/rbot-karma.po +0 -0
  171. data/po/fi/rbot-keywords.po +24 -0
  172. data/po/fi/rbot-lart.po +0 -0
  173. data/po/fi/rbot-lastfm.po +377 -0
  174. data/po/fi/rbot-linkbot.po +0 -0
  175. data/po/fi/rbot-markov.po +91 -0
  176. data/po/fi/rbot-math.po +0 -0
  177. data/po/fi/rbot-modes.po +0 -0
  178. data/po/fi/rbot-nickrecover.po +36 -0
  179. data/po/fi/rbot-nickserv.po +104 -0
  180. data/po/fi/rbot-nslookup.po +0 -0
  181. data/po/fi/rbot-quakeauth.po +0 -0
  182. data/po/fi/rbot-quiz.po +0 -0
  183. data/po/fi/rbot-quotes.po +108 -0
  184. data/po/fi/rbot-reaction.po +0 -0
  185. data/po/fi/rbot-remind.po +0 -0
  186. data/po/fi/rbot-remotectl.po +0 -0
  187. data/po/fi/rbot-ri.po +0 -0
  188. data/po/fi/rbot-roshambo.po +0 -0
  189. data/po/fi/rbot-rot13.po +0 -0
  190. data/po/fi/rbot-roulette.po +0 -0
  191. data/po/fi/rbot-rss.po +24 -0
  192. data/po/fi/rbot-salut.po +0 -0
  193. data/po/fi/rbot-script.po +20 -0
  194. data/po/fi/rbot-search.po +0 -0
  195. data/po/fi/rbot-seen.po +92 -0
  196. data/po/fi/rbot-shiritori.po +102 -0
  197. data/po/fi/rbot-shortenurls.po +0 -0
  198. data/po/fi/rbot-slashdot.po +0 -0
  199. data/po/fi/rbot-spell.po +54 -0
  200. data/po/fi/rbot-theyfightcrime.po +0 -0
  201. data/po/fi/rbot-threat.po +0 -0
  202. data/po/fi/rbot-time.po +0 -0
  203. data/po/fi/rbot-topic.po +0 -0
  204. data/po/fi/rbot-translator.po +77 -0
  205. data/po/fi/rbot-tube.po +0 -0
  206. data/po/fi/rbot-twitter.po +24 -0
  207. data/po/fi/rbot-uno.po +529 -0
  208. data/po/fi/rbot-urban.po +0 -0
  209. data/po/fi/rbot-url.po +0 -0
  210. data/po/fi/rbot-usermodes.po +0 -0
  211. data/po/fi/rbot-wall.po +32 -0
  212. data/po/fi/rbot-weather.po +0 -0
  213. data/po/fi/rbot-wheelfortune.po +205 -0
  214. data/po/fi/rbot-wow.po +0 -0
  215. data/po/fi/rbot-wserver.po +0 -0
  216. data/po/fi/rbot-youtube.po +58 -0
  217. data/po/fi/rbot.po +1152 -0
  218. data/po/fr/rbot-autorejoin.po +3 -0
  219. data/po/fr/rbot-azgame.po +51 -43
  220. data/po/fr/rbot-bash.po +15 -0
  221. data/po/fr/rbot-dictclient.po +20 -20
  222. data/po/fr/rbot-factoids.po +9 -9
  223. data/po/fr/rbot-geoip.po +0 -0
  224. data/po/fr/rbot-googlefight.po +24 -0
  225. data/po/fr/rbot-grouphug.po +4 -4
  226. data/po/fr/rbot-hangman.po +114 -0
  227. data/po/fr/rbot-keywords.po +3 -3
  228. data/po/fr/rbot-lastfm.po +268 -70
  229. data/po/fr/rbot-markov.po +74 -2
  230. data/po/fr/rbot-quotes.po +21 -21
  231. data/po/fr/rbot-rss.po +6 -2
  232. data/po/fr/rbot-script.po +3 -0
  233. data/po/fr/rbot-seen.po +72 -0
  234. data/po/fr/rbot-spell.po +2 -2
  235. data/po/fr/rbot-translator.po +13 -13
  236. data/po/fr/rbot-twitter.po +3 -3
  237. data/po/fr/rbot-uno.po +132 -114
  238. data/po/fr/rbot-wall.po +8 -9
  239. data/po/fr/rbot-wheelfortune.po +41 -41
  240. data/po/fr/rbot.po +268 -197
  241. data/po/it/rbot-autorejoin.po +3 -0
  242. data/po/it/rbot-azgame.po +50 -42
  243. data/po/it/rbot-bash.po +15 -0
  244. data/po/it/rbot-dictclient.po +20 -20
  245. data/po/it/rbot-factoids.po +9 -9
  246. data/po/it/rbot-geoip.po +0 -0
  247. data/po/it/rbot-googlefight.po +24 -0
  248. data/po/it/rbot-grouphug.po +4 -4
  249. data/po/it/rbot-hangman.po +114 -0
  250. data/po/it/rbot-keywords.po +3 -3
  251. data/po/it/rbot-lastfm.po +268 -70
  252. data/po/it/rbot-markov.po +75 -3
  253. data/po/it/rbot-quotes.po +21 -21
  254. data/po/it/rbot-rss.po +7 -3
  255. data/po/it/rbot-script.po +19 -0
  256. data/po/it/rbot-seen.po +72 -0
  257. data/po/it/rbot-spell.po +2 -2
  258. data/po/it/rbot-translator.po +13 -13
  259. data/po/it/rbot-twitter.po +3 -3
  260. data/po/it/rbot-uno.po +137 -116
  261. data/po/it/rbot-wall.po +8 -9
  262. data/po/it/rbot-wheelfortune.po +41 -41
  263. data/po/it/rbot.po +265 -208
  264. data/po/ja/rbot-autorejoin.po +3 -0
  265. data/po/ja/rbot-azgame.po +51 -43
  266. data/po/ja/rbot-bash.po +15 -0
  267. data/po/ja/rbot-dictclient.po +20 -20
  268. data/po/ja/rbot-factoids.po +9 -9
  269. data/po/ja/rbot-geoip.po +0 -0
  270. data/po/ja/rbot-googlefight.po +24 -0
  271. data/po/ja/rbot-grouphug.po +4 -4
  272. data/po/ja/rbot-hangman.po +114 -0
  273. data/po/ja/rbot-keywords.po +3 -3
  274. data/po/ja/rbot-lastfm.po +268 -70
  275. data/po/ja/rbot-markov.po +73 -2
  276. data/po/ja/rbot-quotes.po +21 -21
  277. data/po/ja/rbot-rss.po +6 -2
  278. data/po/ja/rbot-script.po +3 -0
  279. data/po/ja/rbot-seen.po +72 -0
  280. data/po/ja/rbot-spell.po +2 -2
  281. data/po/ja/rbot-translator.po +13 -13
  282. data/po/ja/rbot-twitter.po +3 -3
  283. data/po/ja/rbot-uno.po +131 -114
  284. data/po/ja/rbot-wall.po +8 -9
  285. data/po/ja/rbot-wheelfortune.po +41 -41
  286. data/po/ja/rbot.po +248 -192
  287. data/po/rbot-alias.pot +2 -2
  288. data/po/rbot-autorejoin.pot +21 -0
  289. data/po/rbot-azgame.pot +51 -43
  290. data/po/rbot-bash.pot +33 -0
  291. data/po/rbot-cal.pot +2 -2
  292. data/po/rbot-dictclient.pot +21 -21
  293. data/po/rbot-factoids.pot +10 -10
  294. data/po/rbot-figlet.pot +2 -2
  295. data/po/rbot-geoip.pot +0 -0
  296. data/po/rbot-googlefight.pot +25 -0
  297. data/po/rbot-grouphug.pot +6 -6
  298. data/po/rbot-hangman.pot +115 -0
  299. data/po/rbot-host.pot +2 -2
  300. data/po/rbot-keywords.pot +4 -4
  301. data/po/rbot-lastfm.pot +270 -72
  302. data/po/rbot-markov.pot +74 -3
  303. data/po/rbot-nickrecover.pot +2 -2
  304. data/po/rbot-nickserv.pot +2 -2
  305. data/po/rbot-quotes.pot +22 -22
  306. data/po/rbot-rss.pot +7 -3
  307. data/po/rbot-script.pot +21 -0
  308. data/po/rbot-seen.pot +90 -0
  309. data/po/rbot-shiritori.pot +2 -2
  310. data/po/rbot-spell.pot +3 -3
  311. data/po/rbot-translator.pot +14 -14
  312. data/po/rbot-twitter.pot +4 -4
  313. data/po/rbot-uno.pot +132 -115
  314. data/po/rbot-wall.pot +2 -2
  315. data/po/rbot-wheelfortune.pot +42 -42
  316. data/po/rbot-youtube.pot +2 -2
  317. data/po/rbot.pot +249 -193
  318. data/po/zh_CN/rbot-autorejoin.po +3 -0
  319. data/po/zh_CN/rbot-azgame.po +50 -42
  320. data/po/zh_CN/rbot-bash.po +15 -0
  321. data/po/zh_CN/rbot-dictclient.po +20 -20
  322. data/po/zh_CN/rbot-factoids.po +9 -9
  323. data/po/zh_CN/rbot-geoip.po +0 -0
  324. data/po/zh_CN/rbot-googlefight.po +24 -0
  325. data/po/zh_CN/rbot-grouphug.po +4 -4
  326. data/po/zh_CN/rbot-hangman.po +114 -0
  327. data/po/zh_CN/rbot-keywords.po +3 -3
  328. data/po/zh_CN/rbot-lastfm.po +268 -70
  329. data/po/zh_CN/rbot-markov.po +73 -2
  330. data/po/zh_CN/rbot-quotes.po +21 -21
  331. data/po/zh_CN/rbot-rss.po +6 -2
  332. data/po/zh_CN/rbot-script.po +3 -0
  333. data/po/zh_CN/rbot-seen.po +72 -0
  334. data/po/zh_CN/rbot-spell.po +2 -2
  335. data/po/zh_CN/rbot-translator.po +13 -13
  336. data/po/zh_CN/rbot-twitter.po +3 -3
  337. data/po/zh_CN/rbot-uno.po +131 -114
  338. data/po/zh_CN/rbot-wall.po +7 -8
  339. data/po/zh_CN/rbot-wheelfortune.po +41 -41
  340. data/po/zh_CN/rbot.po +248 -192
  341. data/po/zh_TW/rbot-autorejoin.po +3 -0
  342. data/po/zh_TW/rbot-azgame.po +50 -42
  343. data/po/zh_TW/rbot-bash.po +15 -0
  344. data/po/zh_TW/rbot-dictclient.po +20 -20
  345. data/po/zh_TW/rbot-factoids.po +9 -9
  346. data/po/zh_TW/rbot-geoip.po +0 -0
  347. data/po/zh_TW/rbot-googlefight.po +24 -0
  348. data/po/zh_TW/rbot-grouphug.po +4 -4
  349. data/po/zh_TW/rbot-hangman.po +114 -0
  350. data/po/zh_TW/rbot-keywords.po +3 -3
  351. data/po/zh_TW/rbot-lastfm.po +268 -70
  352. data/po/zh_TW/rbot-markov.po +73 -2
  353. data/po/zh_TW/rbot-quotes.po +21 -21
  354. data/po/zh_TW/rbot-rss.po +6 -2
  355. data/po/zh_TW/rbot-script.po +3 -0
  356. data/po/zh_TW/rbot-seen.po +72 -0
  357. data/po/zh_TW/rbot-spell.po +2 -2
  358. data/po/zh_TW/rbot-translator.po +13 -13
  359. data/po/zh_TW/rbot-twitter.po +3 -3
  360. data/po/zh_TW/rbot-uno.po +131 -114
  361. data/po/zh_TW/rbot-wall.po +7 -8
  362. data/po/zh_TW/rbot-wheelfortune.po +41 -41
  363. data/po/zh_TW/rbot.po +253 -194
  364. data/setup.rb +4 -4
  365. metadata +127 -18
  366. data/README +0 -43
  367. data/data/rbot/plugins/fish.rb +0 -121
  368. data/lib/rbot/dbhash.rb +0 -199
@@ -33,9 +33,6 @@ define_structure :QuizBundle, :question, :answer
33
33
  define_structure :PlayerStats, :score, :jokers, :jokers_time
34
34
  # Why do we still need jokers_time? //Firetech
35
35
 
36
- # Maximum number of jokers a player can gain
37
- Max_Jokers = 3
38
-
39
36
  # Control codes
40
37
  Color = "\003"
41
38
  Bold = "\002"
@@ -164,6 +161,11 @@ class QuizPlugin < Plugin
164
161
  :default => ['quiz.rbot'],
165
162
  :desc => "List of files and URLs that will be used to retrieve quiz questions")
166
163
 
164
+
165
+ Config.register Config::IntegerValue.new('quiz.max_jokers',
166
+ :default => 3,
167
+ :desc => "Maximum number of jokers a player can gain")
168
+
167
169
  def initialize()
168
170
  super
169
171
 
@@ -184,10 +186,11 @@ class QuizPlugin < Plugin
184
186
  # (in quiz/) or web pages.
185
187
  #
186
188
  def fetch_data( m )
187
- # Read the winning messages file
189
+ # Read the winning messages file
188
190
  @win_messages = Array.new
189
- if File.exists? "#{@bot.botclass}/quiz/win_messages"
190
- IO.foreach("#{@bot.botclass}/quiz/win_messages") { |line| @win_messages << line.chomp }
191
+ winfile = datafile 'win_messages'
192
+ if File.exists? winfile
193
+ IO.foreach(winfile) { |line| @win_messages << line.chomp }
191
194
  else
192
195
  warning( "win_messages file not found!" )
193
196
  # Fill the array with a least one message or code accessing it would fail
@@ -212,13 +215,12 @@ class QuizPlugin < Plugin
212
215
  m.reply "Failed to download questions from #{p}, ignoring sources"
213
216
  end
214
217
  else
215
- path = "#{@bot.botclass}/quiz/#{p}"
218
+ path = datafile p
216
219
  debug "Fetching from #{path}"
217
220
 
218
221
  # Local data
219
222
  begin
220
- datafile = File.new( path, File::RDONLY )
221
- data << "\n\n" << datafile.read
223
+ data << "\n\n" << File.read(path)
222
224
  rescue
223
225
  m.reply "Failed to read from local database file #{p}, skipping."
224
226
  end
@@ -338,7 +340,7 @@ class QuizPlugin < Plugin
338
340
  end
339
341
  end
340
342
 
341
- # If less than all other players' scores, append to table
343
+ # If less than all other players' scores, append to table
342
344
  unless inserted
343
345
  i += 1 unless q.rank_table.empty?
344
346
  q.rank_table << [nick, stats]
@@ -369,7 +371,7 @@ class QuizPlugin < Plugin
369
371
 
370
372
  message = m.message.downcase.strip
371
373
 
372
- nick = m.sourcenick.to_s
374
+ nick = m.sourcenick.to_s
373
375
 
374
376
  # Support multiple alternate answers and cores
375
377
  answer = q.answers.find { |ans| ans.valid?(message) }
@@ -406,7 +408,7 @@ class QuizPlugin < Plugin
406
408
  player.score = player.score + points
407
409
 
408
410
  # Reward player with a joker every X points
409
- if player.score % 15 == 0 and player.jokers < Max_Jokers
411
+ if player.score % 15 == 0 and player.jokers < @bot.config['quiz.max_jokers']
410
412
  player.jokers += 1
411
413
  m.reply "#{nick} gains a new joker. Rejoice :)"
412
414
  end
@@ -899,7 +901,7 @@ class QuizPlugin < Plugin
899
901
  debug q.rank_table.inspect
900
902
 
901
903
  nick = params[:nick]
902
- val = [params[:jokers].to_i, Max_Jokers].min
904
+ val = [params[:jokers].to_i, @bot.config['quiz.max_jokers']].min
903
905
  if q.registry.has_key?(nick)
904
906
  player = q.registry[nick]
905
907
  player.jokers = val
@@ -15,7 +15,7 @@ require 'time'
15
15
  class RoshamboPlugin < Plugin
16
16
 
17
17
  def initialize
18
- super
18
+ super
19
19
  @scoreboard = {}
20
20
  @beats = { :rock => :scissors, :paper => :rock, :scissors => :paper}
21
21
  @plays = @beats.keys
@@ -2,13 +2,13 @@ define_structure :RouletteHistory, :games, :shots, :deaths, :misses, :wins
2
2
 
3
3
  class RoulettePlugin < Plugin
4
4
  Config.register Config::BooleanValue.new('roulette.autospin',
5
- :default => true,
5
+ :default => true,
6
6
  :desc => "Automatically spins the roulette at the butlast shot")
7
7
  Config.register Config::BooleanValue.new('roulette.kick',
8
- :default => false,
8
+ :default => false,
9
9
  :desc => "Kicks shot players from the channel")
10
10
  Config.register Config::BooleanValue.new('roulette.twice_in_a_row',
11
- :default => false,
11
+ :default => false,
12
12
  :desc => "Allow players to go twice in a row")
13
13
 
14
14
  def initialize
@@ -174,7 +174,7 @@ class RoulettePlugin < Plugin
174
174
  k = match[1]
175
175
 
176
176
  total_players += 1
177
-
177
+
178
178
  win_rate = v.wins.to_f / v.games * 100
179
179
  if h_win_percent[0].nil? || win_rate > h_win_percent[1] && v.games > 2
180
180
  h_win_percent = [[k], win_rate]
@@ -1,7 +1,7 @@
1
1
  #-- vim:sw=2:et
2
2
  #kate: indent-width 2
3
3
  #++
4
- #
4
+ #
5
5
  # :title: Shiritori Plugin for RBot
6
6
  #
7
7
  # Author:: Yaohan Chen <yaohan.chen@gmail.com>
@@ -16,10 +16,10 @@
16
16
  # players can interrupt a turn to join, or a free mode where anyone can speak at any
17
17
  # time.
18
18
  #
19
- # In Japanese mode, if present, the plugin can use normalize-japanese
19
+ # In Japanese mode, if present, the plugin can use normalize-japanese
20
20
  # <http://neruchan.mine.nu:60880/normalize-japanese.rb> to allow
21
21
  # katakana words be used like hiragana.
22
- #
22
+ #
23
23
  # TODO
24
24
  # * a system to describe settings, so they can be displayed, changed and saved
25
25
  # * adjust settings during game
@@ -35,7 +35,7 @@ class Dictionary
35
35
  def has_word?(s)
36
36
  raise NotImplementedError
37
37
  end
38
-
38
+
39
39
  # whether any word starts with prefix, excluding words in excludes. This can be
40
40
  # possible with non-enumerable dictionaries since some dictionary engines provide
41
41
  # prefix searching.
@@ -51,12 +51,12 @@ class WordlistDictionary < Dictionary
51
51
  @words = words
52
52
  # debug "Created dictionary with #{@words.length} words"
53
53
  end
54
-
54
+
55
55
  # whether string s is a word
56
56
  def has_word?(s)
57
57
  @words.include? s
58
58
  end
59
-
59
+
60
60
  # whether any word starts with prefix, excluding words in excludes
61
61
  def any_word_starting?(prefix, excludes)
62
62
  # (@words - except).any? {|w| w =~ /\A#{prefix}.+/}
@@ -69,7 +69,7 @@ end
69
69
  # whether it's possible to continue a word
70
70
  class Shiritori
71
71
  attr_reader :used_words
72
-
72
+
73
73
  # dictionary:: a Dictionary object
74
74
  # overlap_lengths:: a Range for allowed lengths to overlap when continuing words
75
75
  # check_continuable:: whether all words are checked whether they're continuable,
@@ -82,7 +82,7 @@ class Shiritori
82
82
  @allow_reuse = allow_reuse
83
83
  @used_words = []
84
84
  end
85
-
85
+
86
86
  # Prefix of s with length n
87
87
  def head_of(s, n)
88
88
  # TODO ruby2 unicode
@@ -102,7 +102,7 @@ class Shiritori
102
102
  def range_under(r, n)
103
103
  r.begin .. [r.end, n-1].min
104
104
  end
105
-
105
+
106
106
  # TODO allow the ruleset to customize this
107
107
  def continues?(w2, w1)
108
108
  # this uses the definition w1[-n,n] == w2[0,n] && n < [w1.length, w2.length].min
@@ -110,7 +110,7 @@ class Shiritori
110
110
  range_under(@overlap_lengths, [len(w1), len(w2)].min).any? {|n|
111
111
  tail_of(w1, n)== head_of(w2, n)}
112
112
  end
113
-
113
+
114
114
  # Checks whether *any* unused word in the dictionary completes the word
115
115
  # This has the limitation that it can't detect when a word is continuable, but the
116
116
  # only continuers aren't continuable
@@ -118,8 +118,8 @@ class Shiritori
118
118
  range_under(@overlap_lengths, len(s)).any? {|n|
119
119
  @dictionary.any_word_starting?(tail_of(s, n), @used_words) }
120
120
  end
121
-
122
- # Given a string, give a verdict based on current shiritori state and dictionary
121
+
122
+ # Given a string, give a verdict based on current shiritori state and dictionary
123
123
  def process(s)
124
124
  # TODO optionally allow used words
125
125
  # TODO ruby2 unicode
@@ -167,14 +167,14 @@ class ShiritoriGame
167
167
  @timer_handle = nil
168
168
  @say = say
169
169
  @when_die = when_die
170
-
170
+
171
171
  # TODO allow other forms of dictionaries
172
172
  dictionary = WordlistDictionary.new(@ruleset[:words])
173
173
  @game = Shiritori.new(dictionary, @ruleset[:overlap_lengths],
174
174
  @ruleset[:check_continuable],
175
175
  @ruleset[:allow_reuse])
176
176
  end
177
-
177
+
178
178
  def say(s)
179
179
  @say.call(s)
180
180
  end
@@ -184,10 +184,10 @@ class ShiritoriGame
184
184
  # * when time_limit > 0, new players can join at any time, but existing players must
185
185
  # take turns, each of which expires after time_limit
186
186
  # * when time_imit is 0, anyone can speak in the game at any time
187
- def take_turns?
187
+ def take_turns?
188
188
  @players.length > 1 && @ruleset[:time_limit] > 0
189
189
  end
190
-
190
+
191
191
  # the player who has the current turn
192
192
  def current_player
193
193
  @players.first
@@ -200,7 +200,7 @@ class ShiritoriGame
200
200
  def previous_word
201
201
  @game.used_words[-2]
202
202
  end
203
-
203
+
204
204
  # announce the current word, and player if take_turns?
205
205
  def announce
206
206
  say(if take_turns?
@@ -237,13 +237,13 @@ class ShiritoriGame
237
237
  end
238
238
  announce
239
239
  end
240
-
240
+
241
241
  # handle when turn time limit goes out
242
242
  def time_out
243
243
  if @ruleset[:lose_when_timeout]
244
244
  say _("%{player} took too long and is out of the game. Try again next game!") %
245
245
  { :player => current_player }
246
- if @players.length == 2
246
+ if @players.length == 2
247
247
  # 2 players before, and one should remain now
248
248
  # since the game is ending, save the trouble of removing and booting the player
249
249
  say _("%{player} is the last remaining player and the winner! Congratulations!") %
@@ -269,12 +269,12 @@ class ShiritoriGame
269
269
  def handle_message(m)
270
270
  message = m.message
271
271
  speaker = m.sourcenick.to_s
272
-
272
+
273
273
  return unless @ruleset[:listen] =~ message
274
274
 
275
275
  # in take_turns mode, only new players are allowed to interrupt a turn
276
276
  return if @booted_players.include? speaker ||
277
- (take_turns? &&
277
+ (take_turns? &&
278
278
  speaker != current_player &&
279
279
  (@players.length > 1 && @players.include?(speaker)))
280
280
 
@@ -310,7 +310,7 @@ class ShiritoriGame
310
310
  m.reply _("It's impossible to continue the chain from %{word}. Start with another word.") % {:word => message}
311
311
  end
312
312
  end
313
-
313
+
314
314
  # end the game
315
315
  def die
316
316
  # redefine restart_timer to no-op
@@ -331,11 +331,11 @@ class ShiritoriPlugin < Plugin
331
331
  _("A game in which each player must continue the previous player's word, by using its last one or few characters/letters of the word to start a new word. 'shiritori <ruleset>' => Play shiritori with a set of rules. Available rulesets: %{rulesets}. 'shiritori stop' => Stop the current shiritori game.") %
332
332
  {:rulesets => @rulesets.keys.join(', ')}
333
333
  end
334
-
334
+
335
335
  def initialize()
336
336
  super
337
337
  @games = {}
338
-
338
+
339
339
  # TODO make rulesets more easily customizable
340
340
  # TODO initialize default ruleset from config
341
341
  # Default values of rulesets
@@ -390,7 +390,7 @@ class ShiritoriPlugin < Plugin
390
390
  if ruleset.has_key?(:wordlist_file)
391
391
  begin
392
392
  ruleset[:words] =
393
- File.new("#{@bot.botclass}/shiritori/#{ruleset[:wordlist_file]}").grep(
393
+ File.new(datafile(ruleset[:wordlist_file])).grep(
394
394
  ruleset[:listen]) {|l| ruleset[:normalize].call l.chomp}
395
395
  rescue
396
396
  raise "unable to load word list"
@@ -401,7 +401,7 @@ class ShiritoriPlugin < Plugin
401
401
  end
402
402
  return ruleset
403
403
  end
404
-
404
+
405
405
  # start shiritori in a channel
406
406
  def cmd_shiritori(m, params)
407
407
  if @games.has_key?( m.channel )
@@ -426,7 +426,7 @@ class ShiritoriPlugin < Plugin
426
426
  end
427
427
  end
428
428
  end
429
-
429
+
430
430
  # change rules for current game
431
431
  def cmd_set(m, params)
432
432
  require 'enumerator'
@@ -434,7 +434,7 @@ class ShiritoriPlugin < Plugin
434
434
  params[:rules].each_slice(2) {|opt, value| new_rules[opt] = value}
435
435
  raise NotImplementedError
436
436
  end
437
-
437
+
438
438
  # stop the current game
439
439
  def cmd_stop(m, params)
440
440
  if @games.has_key? m.channel
@@ -446,19 +446,19 @@ class ShiritoriPlugin < Plugin
446
446
  m.reply _("No game to stop here, because no game is being played.")
447
447
  end
448
448
  end
449
-
449
+
450
450
  # remove the game, so channel messages are no longer processed, and timer removed
451
451
  def remove_game(channel)
452
452
  @games.delete channel
453
453
  end
454
-
454
+
455
455
  # all messages from a channel is sent to its shiritori game if any
456
456
  def message(m)
457
457
  return unless @games.has_key?(m.channel)
458
458
  # send the message to the game in the channel to handle it
459
459
  @games[m.channel].handle_message m
460
460
  end
461
-
461
+
462
462
  # remove all games
463
463
  def cleanup
464
464
  @games.each_key {|g| g.die}
@@ -108,7 +108,7 @@ class UnoGame
108
108
  @color = 'Wild'
109
109
  raise if value and not value == '+4'
110
110
  if value
111
- @value = value.dup
111
+ @value = value.dup
112
112
  @shortform = 'w'+value
113
113
  else
114
114
  @value = nil
@@ -411,7 +411,7 @@ class UnoGame
411
411
  # only be possible if the first W+4 was illegal, so it wouldn't
412
412
  # apply for a W+4 played on a +2 anyway.
413
413
  #
414
- if @picker == 0 and Wild === cards.first and cards.first.value
414
+ if @picker == 0 and Wild === cards.first and cards.first.value
415
415
  # save the previous discard in case of challenge
416
416
  @last_discard = @discard.dup
417
417
  # save the color too, in case it was a Wild
@@ -761,7 +761,11 @@ class UnoGame
761
761
  }
762
762
  end
763
763
  if @picker > 0 and not halted
764
- p = @players[1]
764
+ if @discard.value == 'Reverse'
765
+ p = @players.last
766
+ else
767
+ p = @players[1]
768
+ end
765
769
  announce _("%{p} has to pick %{b}%{n}%{b} cards!") % {
766
770
  :p => p, :n => @picker, :b => Bold
767
771
  }
@@ -841,8 +845,14 @@ class UnoPlugin < Plugin
841
845
  _("The points won with a game of %{uno} are totalled from the cards remaining in the hands of the other players."),
842
846
  _("Each normal (not special) card is worth its face value (from 0 to 9 points)."),
843
847
  _("Each colored special card (+2, Reverse, Skip) is worth 20 points."),
844
- _("Each Wild and Wild +4 is worth 50 points.")
848
+ _("Each Wild and Wild +4 is worth 50 points."),
849
+ help(plugin, 'top'),
850
+ help(plugin, 'topwin'),
845
851
  ].join(" ") % { :uno => UnoGame::UNO }
852
+ when 'top'
853
+ _("You can see the scoring table with 'uno top N' where N is the number of top scores to show.")
854
+ when 'topwin'
855
+ _("You can see the winners table with 'uno topwin N' where N is the number of top winners to show.")
846
856
  when /cards?/
847
857
  [
848
858
  _("There are 108 cards in a standard %{uno} deck."),
@@ -859,7 +869,7 @@ class UnoPlugin < Plugin
859
869
  _("'uno end' to end the game before its natural completion")
860
870
  ].join("; ")
861
871
  else
862
- _("%{uno} game. !uno to start a game. see 'help uno rules' for the rules, 'help uno admin' for admin commands. In-game commands: %{cmds}.") % {
872
+ _("%{uno} game. !uno to start a game. see 'help uno rules' for the rules, 'help uno admin' for admin commands, 'help uno score' for scoring rules. In-game commands: %{cmds}.") % {
863
873
  :uno => UnoGame::UNO,
864
874
  :cmds => help(plugin, 'commands')
865
875
  }
@@ -870,6 +880,7 @@ class UnoPlugin < Plugin
870
880
  return unless @games.key?(m.channel)
871
881
  return unless m.plugin # skip messages such as: <someuser> botname,
872
882
  g = @games[m.channel]
883
+ replied = true
873
884
  case m.plugin.intern
874
885
  when :jo # join game
875
886
  return if m.params
@@ -931,11 +942,14 @@ class UnoPlugin < Plugin
931
942
  when :tu # show whose turn is it
932
943
  return if m.params
933
944
  if g.has_turn?(m.source)
934
- m.nickreply _("it's your turn, sleepyhead")
945
+ m.reply _("it's your turn, sleepyhead"), :nick => true
935
946
  else
936
947
  g.show_turn(:cards => false)
937
948
  end
949
+ else
950
+ replied=false
938
951
  end
952
+ m.replied=true if replied
939
953
  end
940
954
 
941
955
  def create_game(m, p)
@@ -1147,6 +1161,14 @@ class UnoPlugin < Plugin
1147
1161
  scores << [v.won.inject(0) { |s, w| s+=w.score }, k]
1148
1162
  end
1149
1163
 
1164
+ if wins.empty?
1165
+ m.reply(_("no %{uno} games were completed here") % {
1166
+ :uno => UnoGame::UNO
1167
+ })
1168
+ return
1169
+ end
1170
+
1171
+
1150
1172
  if n = p[:scorenum]
1151
1173
  msg = _("%{uno} %{num} highest scores: ") % {
1152
1174
  :uno => UnoGame::UNO, :num => p[:scorenum]
@@ -476,9 +476,7 @@ class WheelOfFortune < Plugin
476
476
  # m.reply "STUPID! YOU SO STUPID!"
477
477
  return
478
478
  when *game.must_buy
479
- m.nickreply _("You must buy the %{vowel}") % {
480
- :vowel => check
481
- }
479
+ m.reply _("You must buy the %{vowel}") % {:vowel => check}, :nick => true
482
480
  when :wrong
483
481
  return
484
482
  when Numeric, :missing