rbot 0.9.14 → 0.9.15
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +6 -2
- data/REQUIREMENTS +7 -1
- data/Rakefile +10 -32
- data/bin/rbot +6 -1
- data/bin/svnwatch-postcommit-hook +68 -0
- data/data/rbot/contrib/plugins/stats.rb +3 -3
- data/data/rbot/contrib/plugins/vandale.rb +1 -1
- data/data/rbot/filters/rss.rb +72 -0
- data/data/rbot/languages/finnish.lang +50 -0
- data/data/rbot/plugins/alias.rb +6 -6
- data/data/rbot/plugins/autorejoin.rb +41 -2
- data/data/rbot/plugins/bans.rb +100 -6
- data/data/rbot/plugins/bash.rb +9 -4
- data/data/rbot/plugins/cal.rb +1 -1
- data/data/rbot/plugins/chucknorris.rb +6 -6
- data/data/rbot/plugins/debugger.rb +7 -3
- data/data/rbot/plugins/deepthoughts.rb +1 -1
- data/data/rbot/plugins/delicious.rb +6 -2
- data/data/rbot/plugins/dice.rb +7 -7
- data/data/rbot/plugins/dict.rb +4 -3
- data/data/rbot/plugins/dictclient.rb +17 -13
- data/data/rbot/plugins/digg.rb +3 -3
- data/data/rbot/plugins/eightball.rb +1 -1
- data/data/rbot/plugins/factoids.rb +13 -4
- data/data/rbot/plugins/figlet.rb +4 -4
- data/data/rbot/plugins/forecast.rb +3 -3
- data/data/rbot/plugins/fortune.rb +14 -8
- data/data/rbot/plugins/freshmeat.rb +2 -2
- data/data/rbot/plugins/games/azgame.rb +72 -19
- data/data/rbot/plugins/games/hangman.rb +499 -0
- data/data/rbot/plugins/games/quiz.rb +15 -13
- data/data/rbot/plugins/games/roshambo.rb +1 -1
- data/data/rbot/plugins/games/roulette.rb +4 -4
- data/data/rbot/plugins/games/shiritori.rb +31 -31
- data/data/rbot/plugins/games/uno.rb +28 -6
- data/data/rbot/plugins/games/wheelfortune.rb +1 -3
- data/data/rbot/plugins/geoip.rb +83 -28
- data/data/rbot/plugins/googlefight.rb +64 -0
- data/data/rbot/plugins/greet.rb +45 -0
- data/data/rbot/plugins/grouphug.rb +40 -12
- data/data/rbot/plugins/imdb.rb +4 -4
- data/data/rbot/plugins/insult.rb +2 -2
- data/data/rbot/plugins/karma.rb +6 -5
- data/data/rbot/plugins/keywords.rb +26 -22
- data/data/rbot/plugins/lart.rb +5 -6
- data/data/rbot/plugins/lastfm.rb +488 -125
- data/data/rbot/plugins/lib_spotify.rb +84 -0
- data/data/rbot/plugins/linkbot.rb +1 -1
- data/data/rbot/plugins/markov.rb +567 -78
- data/data/rbot/plugins/math.rb +3 -3
- data/data/rbot/plugins/modes.rb +1 -1
- data/data/rbot/plugins/nickrecover.rb +1 -1
- data/data/rbot/plugins/nickserv.rb +7 -7
- data/data/rbot/plugins/note.rb +55 -0
- data/data/rbot/plugins/nslookup.rb +2 -2
- data/data/rbot/plugins/quakeauth.rb +4 -4
- data/data/rbot/plugins/quotes.rb +53 -19
- data/data/rbot/plugins/reaction.rb +76 -19
- data/data/rbot/plugins/remind.rb +3 -96
- data/data/rbot/plugins/ri.rb +1 -1
- data/data/rbot/plugins/rot13.rb +1 -1
- data/data/rbot/plugins/rss.rb +296 -190
- data/data/rbot/plugins/salut.rb +8 -8
- data/data/rbot/plugins/script.rb +48 -11
- data/data/rbot/plugins/search.rb +124 -28
- data/data/rbot/plugins/seen.rb +162 -31
- data/data/rbot/plugins/shortenurls.rb +1 -1
- data/data/rbot/plugins/slashdot.rb +19 -6
- data/data/rbot/plugins/spotify.rb +78 -0
- data/data/rbot/plugins/theyfightcrime.rb +10 -10
- data/data/rbot/plugins/time.rb +2 -2
- data/data/rbot/plugins/translator.rb +161 -85
- data/data/rbot/plugins/tube.rb +2 -2
- data/data/rbot/plugins/tumblr.rb +143 -0
- data/data/rbot/plugins/twitter.rb +25 -6
- data/data/rbot/plugins/urban.rb +6 -4
- data/data/rbot/plugins/url.rb +49 -10
- data/data/rbot/plugins/weather.rb +6 -6
- data/data/rbot/plugins/wserver.rb +5 -5
- data/data/rbot/plugins/youtube.rb +12 -12
- data/data/rbot/templates/lart/larts-italian +1 -1
- data/launch_here.rb +68 -0
- data/lib/rbot/botuser.rb +1 -1
- data/lib/rbot/compat19.rb +70 -0
- data/lib/rbot/config.rb +8 -6
- data/lib/rbot/core/auth.rb +37 -21
- data/lib/rbot/core/basics.rb +33 -2
- data/lib/rbot/core/config.rb +24 -17
- data/lib/rbot/core/filters_ui.rb +2 -2
- data/lib/rbot/core/irclog.rb +20 -11
- data/lib/rbot/core/remote.rb +9 -9
- data/lib/rbot/core/unicode.rb +4 -0
- data/lib/rbot/core/userdata.rb +16 -1
- data/lib/rbot/core/utils/extends.rb +76 -0
- data/lib/rbot/core/utils/filters.rb +47 -0
- data/lib/rbot/core/utils/httputil.rb +36 -26
- data/lib/rbot/core/utils/parse_time.rb +193 -0
- data/lib/rbot/core/utils/utils.rb +81 -56
- data/lib/rbot/core/utils/wordlist.rb +66 -0
- data/lib/rbot/core/wordlist_ui.rb +27 -0
- data/lib/rbot/irc.rb +59 -19
- data/lib/rbot/ircbot.rb +190 -58
- data/lib/rbot/ircsocket.rb +14 -8
- data/lib/rbot/language.rb +4 -3
- data/lib/rbot/load-gettext.rb +22 -9
- data/lib/rbot/message.rb +89 -18
- data/lib/rbot/messagemapper.rb +71 -19
- data/lib/rbot/plugins.rb +112 -44
- data/lib/rbot/{registry.rb → registry/bdb.rb} +226 -22
- data/lib/rbot/registry/tc.rb +531 -0
- data/lib/rbot/rfc2812.rb +33 -8
- data/lib/rbot/timer.rb +12 -20
- data/po/en_US/rbot-autorejoin.po +3 -0
- data/po/en_US/rbot-azgame.po +51 -43
- data/po/en_US/rbot-bash.po +15 -0
- data/po/en_US/rbot-dictclient.po +20 -20
- data/po/en_US/rbot-factoids.po +9 -9
- data/po/en_US/rbot-geoip.po +0 -0
- data/po/en_US/rbot-googlefight.po +24 -0
- data/po/en_US/rbot-grouphug.po +4 -4
- data/po/en_US/rbot-hangman.po +114 -0
- data/po/en_US/rbot-keywords.po +3 -3
- data/po/en_US/rbot-lastfm.po +268 -70
- data/po/en_US/rbot-markov.po +73 -2
- data/po/en_US/rbot-quotes.po +21 -21
- data/po/en_US/rbot-rss.po +6 -2
- data/po/en_US/rbot-script.po +3 -0
- data/po/en_US/rbot-seen.po +72 -0
- data/po/en_US/rbot-spell.po +2 -2
- data/po/en_US/rbot-translator.po +13 -13
- data/po/en_US/rbot-twitter.po +3 -3
- data/po/en_US/rbot-uno.po +131 -114
- data/po/en_US/rbot-wall.po +12 -13
- data/po/en_US/rbot-wheelfortune.po +41 -41
- data/po/en_US/rbot.po +254 -194
- data/po/fi/rbot-alias.po +82 -0
- data/po/fi/rbot-autoop.po +0 -0
- data/po/fi/rbot-autorejoin.po +20 -0
- data/po/fi/rbot-azgame.po +194 -0
- data/po/fi/rbot-bans.po +0 -0
- data/po/fi/rbot-bash.po +32 -0
- data/po/fi/rbot-botsnack.po +0 -0
- data/po/fi/rbot-cal.po +20 -0
- data/po/fi/rbot-chanserv.po +0 -0
- data/po/fi/rbot-chucknorris.po +0 -0
- data/po/fi/rbot-debugger.po +0 -0
- data/po/fi/rbot-deepthoughts.po +0 -0
- data/po/fi/rbot-delicious.po +0 -0
- data/po/fi/rbot-dice.po +0 -0
- data/po/fi/rbot-dict.po +0 -0
- data/po/fi/rbot-dictclient.po +111 -0
- data/po/fi/rbot-digg.po +0 -0
- data/po/fi/rbot-eightball.po +0 -0
- data/po/fi/rbot-excuse.po +0 -0
- data/po/fi/rbot-factoids.po +107 -0
- data/po/fi/rbot-figlet.po +36 -0
- data/po/fi/rbot-fish.po +0 -0
- data/po/fi/rbot-forecast.po +0 -0
- data/po/fi/rbot-fortune.po +0 -0
- data/po/fi/rbot-freshmeat.po +0 -0
- data/po/fi/rbot-geoip.po +0 -0
- data/po/fi/rbot-googlefight.po +24 -0
- data/po/fi/rbot-grouphug.po +35 -0
- data/po/fi/rbot-hangman.po +121 -0
- data/po/fi/rbot-hl2.po +0 -0
- data/po/fi/rbot-host.po +20 -0
- data/po/fi/rbot-imdb.po +0 -0
- data/po/fi/rbot-insult.po +0 -0
- data/po/fi/rbot-iplookup.po +0 -0
- data/po/fi/rbot-karma.po +0 -0
- data/po/fi/rbot-keywords.po +24 -0
- data/po/fi/rbot-lart.po +0 -0
- data/po/fi/rbot-lastfm.po +377 -0
- data/po/fi/rbot-linkbot.po +0 -0
- data/po/fi/rbot-markov.po +91 -0
- data/po/fi/rbot-math.po +0 -0
- data/po/fi/rbot-modes.po +0 -0
- data/po/fi/rbot-nickrecover.po +36 -0
- data/po/fi/rbot-nickserv.po +104 -0
- data/po/fi/rbot-nslookup.po +0 -0
- data/po/fi/rbot-quakeauth.po +0 -0
- data/po/fi/rbot-quiz.po +0 -0
- data/po/fi/rbot-quotes.po +108 -0
- data/po/fi/rbot-reaction.po +0 -0
- data/po/fi/rbot-remind.po +0 -0
- data/po/fi/rbot-remotectl.po +0 -0
- data/po/fi/rbot-ri.po +0 -0
- data/po/fi/rbot-roshambo.po +0 -0
- data/po/fi/rbot-rot13.po +0 -0
- data/po/fi/rbot-roulette.po +0 -0
- data/po/fi/rbot-rss.po +24 -0
- data/po/fi/rbot-salut.po +0 -0
- data/po/fi/rbot-script.po +20 -0
- data/po/fi/rbot-search.po +0 -0
- data/po/fi/rbot-seen.po +92 -0
- data/po/fi/rbot-shiritori.po +102 -0
- data/po/fi/rbot-shortenurls.po +0 -0
- data/po/fi/rbot-slashdot.po +0 -0
- data/po/fi/rbot-spell.po +54 -0
- data/po/fi/rbot-theyfightcrime.po +0 -0
- data/po/fi/rbot-threat.po +0 -0
- data/po/fi/rbot-time.po +0 -0
- data/po/fi/rbot-topic.po +0 -0
- data/po/fi/rbot-translator.po +77 -0
- data/po/fi/rbot-tube.po +0 -0
- data/po/fi/rbot-twitter.po +24 -0
- data/po/fi/rbot-uno.po +529 -0
- data/po/fi/rbot-urban.po +0 -0
- data/po/fi/rbot-url.po +0 -0
- data/po/fi/rbot-usermodes.po +0 -0
- data/po/fi/rbot-wall.po +32 -0
- data/po/fi/rbot-weather.po +0 -0
- data/po/fi/rbot-wheelfortune.po +205 -0
- data/po/fi/rbot-wow.po +0 -0
- data/po/fi/rbot-wserver.po +0 -0
- data/po/fi/rbot-youtube.po +58 -0
- data/po/fi/rbot.po +1152 -0
- data/po/fr/rbot-autorejoin.po +3 -0
- data/po/fr/rbot-azgame.po +51 -43
- data/po/fr/rbot-bash.po +15 -0
- data/po/fr/rbot-dictclient.po +20 -20
- data/po/fr/rbot-factoids.po +9 -9
- data/po/fr/rbot-geoip.po +0 -0
- data/po/fr/rbot-googlefight.po +24 -0
- data/po/fr/rbot-grouphug.po +4 -4
- data/po/fr/rbot-hangman.po +114 -0
- data/po/fr/rbot-keywords.po +3 -3
- data/po/fr/rbot-lastfm.po +268 -70
- data/po/fr/rbot-markov.po +74 -2
- data/po/fr/rbot-quotes.po +21 -21
- data/po/fr/rbot-rss.po +6 -2
- data/po/fr/rbot-script.po +3 -0
- data/po/fr/rbot-seen.po +72 -0
- data/po/fr/rbot-spell.po +2 -2
- data/po/fr/rbot-translator.po +13 -13
- data/po/fr/rbot-twitter.po +3 -3
- data/po/fr/rbot-uno.po +132 -114
- data/po/fr/rbot-wall.po +8 -9
- data/po/fr/rbot-wheelfortune.po +41 -41
- data/po/fr/rbot.po +268 -197
- data/po/it/rbot-autorejoin.po +3 -0
- data/po/it/rbot-azgame.po +50 -42
- data/po/it/rbot-bash.po +15 -0
- data/po/it/rbot-dictclient.po +20 -20
- data/po/it/rbot-factoids.po +9 -9
- data/po/it/rbot-geoip.po +0 -0
- data/po/it/rbot-googlefight.po +24 -0
- data/po/it/rbot-grouphug.po +4 -4
- data/po/it/rbot-hangman.po +114 -0
- data/po/it/rbot-keywords.po +3 -3
- data/po/it/rbot-lastfm.po +268 -70
- data/po/it/rbot-markov.po +75 -3
- data/po/it/rbot-quotes.po +21 -21
- data/po/it/rbot-rss.po +7 -3
- data/po/it/rbot-script.po +19 -0
- data/po/it/rbot-seen.po +72 -0
- data/po/it/rbot-spell.po +2 -2
- data/po/it/rbot-translator.po +13 -13
- data/po/it/rbot-twitter.po +3 -3
- data/po/it/rbot-uno.po +137 -116
- data/po/it/rbot-wall.po +8 -9
- data/po/it/rbot-wheelfortune.po +41 -41
- data/po/it/rbot.po +265 -208
- data/po/ja/rbot-autorejoin.po +3 -0
- data/po/ja/rbot-azgame.po +51 -43
- data/po/ja/rbot-bash.po +15 -0
- data/po/ja/rbot-dictclient.po +20 -20
- data/po/ja/rbot-factoids.po +9 -9
- data/po/ja/rbot-geoip.po +0 -0
- data/po/ja/rbot-googlefight.po +24 -0
- data/po/ja/rbot-grouphug.po +4 -4
- data/po/ja/rbot-hangman.po +114 -0
- data/po/ja/rbot-keywords.po +3 -3
- data/po/ja/rbot-lastfm.po +268 -70
- data/po/ja/rbot-markov.po +73 -2
- data/po/ja/rbot-quotes.po +21 -21
- data/po/ja/rbot-rss.po +6 -2
- data/po/ja/rbot-script.po +3 -0
- data/po/ja/rbot-seen.po +72 -0
- data/po/ja/rbot-spell.po +2 -2
- data/po/ja/rbot-translator.po +13 -13
- data/po/ja/rbot-twitter.po +3 -3
- data/po/ja/rbot-uno.po +131 -114
- data/po/ja/rbot-wall.po +8 -9
- data/po/ja/rbot-wheelfortune.po +41 -41
- data/po/ja/rbot.po +248 -192
- data/po/rbot-alias.pot +2 -2
- data/po/rbot-autorejoin.pot +21 -0
- data/po/rbot-azgame.pot +51 -43
- data/po/rbot-bash.pot +33 -0
- data/po/rbot-cal.pot +2 -2
- data/po/rbot-dictclient.pot +21 -21
- data/po/rbot-factoids.pot +10 -10
- data/po/rbot-figlet.pot +2 -2
- data/po/rbot-geoip.pot +0 -0
- data/po/rbot-googlefight.pot +25 -0
- data/po/rbot-grouphug.pot +6 -6
- data/po/rbot-hangman.pot +115 -0
- data/po/rbot-host.pot +2 -2
- data/po/rbot-keywords.pot +4 -4
- data/po/rbot-lastfm.pot +270 -72
- data/po/rbot-markov.pot +74 -3
- data/po/rbot-nickrecover.pot +2 -2
- data/po/rbot-nickserv.pot +2 -2
- data/po/rbot-quotes.pot +22 -22
- data/po/rbot-rss.pot +7 -3
- data/po/rbot-script.pot +21 -0
- data/po/rbot-seen.pot +90 -0
- data/po/rbot-shiritori.pot +2 -2
- data/po/rbot-spell.pot +3 -3
- data/po/rbot-translator.pot +14 -14
- data/po/rbot-twitter.pot +4 -4
- data/po/rbot-uno.pot +132 -115
- data/po/rbot-wall.pot +2 -2
- data/po/rbot-wheelfortune.pot +42 -42
- data/po/rbot-youtube.pot +2 -2
- data/po/rbot.pot +249 -193
- data/po/zh_CN/rbot-autorejoin.po +3 -0
- data/po/zh_CN/rbot-azgame.po +50 -42
- data/po/zh_CN/rbot-bash.po +15 -0
- data/po/zh_CN/rbot-dictclient.po +20 -20
- data/po/zh_CN/rbot-factoids.po +9 -9
- data/po/zh_CN/rbot-geoip.po +0 -0
- data/po/zh_CN/rbot-googlefight.po +24 -0
- data/po/zh_CN/rbot-grouphug.po +4 -4
- data/po/zh_CN/rbot-hangman.po +114 -0
- data/po/zh_CN/rbot-keywords.po +3 -3
- data/po/zh_CN/rbot-lastfm.po +268 -70
- data/po/zh_CN/rbot-markov.po +73 -2
- data/po/zh_CN/rbot-quotes.po +21 -21
- data/po/zh_CN/rbot-rss.po +6 -2
- data/po/zh_CN/rbot-script.po +3 -0
- data/po/zh_CN/rbot-seen.po +72 -0
- data/po/zh_CN/rbot-spell.po +2 -2
- data/po/zh_CN/rbot-translator.po +13 -13
- data/po/zh_CN/rbot-twitter.po +3 -3
- data/po/zh_CN/rbot-uno.po +131 -114
- data/po/zh_CN/rbot-wall.po +7 -8
- data/po/zh_CN/rbot-wheelfortune.po +41 -41
- data/po/zh_CN/rbot.po +248 -192
- data/po/zh_TW/rbot-autorejoin.po +3 -0
- data/po/zh_TW/rbot-azgame.po +50 -42
- data/po/zh_TW/rbot-bash.po +15 -0
- data/po/zh_TW/rbot-dictclient.po +20 -20
- data/po/zh_TW/rbot-factoids.po +9 -9
- data/po/zh_TW/rbot-geoip.po +0 -0
- data/po/zh_TW/rbot-googlefight.po +24 -0
- data/po/zh_TW/rbot-grouphug.po +4 -4
- data/po/zh_TW/rbot-hangman.po +114 -0
- data/po/zh_TW/rbot-keywords.po +3 -3
- data/po/zh_TW/rbot-lastfm.po +268 -70
- data/po/zh_TW/rbot-markov.po +73 -2
- data/po/zh_TW/rbot-quotes.po +21 -21
- data/po/zh_TW/rbot-rss.po +6 -2
- data/po/zh_TW/rbot-script.po +3 -0
- data/po/zh_TW/rbot-seen.po +72 -0
- data/po/zh_TW/rbot-spell.po +2 -2
- data/po/zh_TW/rbot-translator.po +13 -13
- data/po/zh_TW/rbot-twitter.po +3 -3
- data/po/zh_TW/rbot-uno.po +131 -114
- data/po/zh_TW/rbot-wall.po +7 -8
- data/po/zh_TW/rbot-wheelfortune.po +41 -41
- data/po/zh_TW/rbot.po +253 -194
- data/setup.rb +4 -4
- metadata +127 -18
- data/README +0 -43
- data/data/rbot/plugins/fish.rb +0 -121
- data/lib/rbot/dbhash.rb +0 -199
data/lib/rbot/ircbot.rb
CHANGED
@@ -23,7 +23,7 @@ $log_thread = nil
|
|
23
23
|
|
24
24
|
require 'pp'
|
25
25
|
|
26
|
-
unless Kernel.
|
26
|
+
unless Kernel.respond_to? :pretty_inspect
|
27
27
|
def pretty_inspect
|
28
28
|
PP.pp(self, '')
|
29
29
|
end
|
@@ -41,6 +41,9 @@ class Exception
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
class ServerError < RuntimeError
|
45
|
+
end
|
46
|
+
|
44
47
|
def rawlog(level, message=nil, who_pos=1)
|
45
48
|
call_stack = caller
|
46
49
|
if call_stack.length > who_pos
|
@@ -132,6 +135,12 @@ $interrupted = 0
|
|
132
135
|
|
133
136
|
# these first
|
134
137
|
require 'rbot/rbotconfig'
|
138
|
+
begin
|
139
|
+
require 'rubygems'
|
140
|
+
rescue LoadError
|
141
|
+
log "rubygems unavailable"
|
142
|
+
end
|
143
|
+
|
135
144
|
require 'rbot/load-gettext'
|
136
145
|
require 'rbot/config'
|
137
146
|
require 'rbot/config-compat'
|
@@ -144,8 +153,6 @@ require 'rbot/timer'
|
|
144
153
|
require 'rbot/plugins'
|
145
154
|
require 'rbot/message'
|
146
155
|
require 'rbot/language'
|
147
|
-
require 'rbot/dbhash'
|
148
|
-
require 'rbot/registry'
|
149
156
|
|
150
157
|
module Irc
|
151
158
|
|
@@ -202,11 +209,16 @@ class Bot
|
|
202
209
|
@client.user
|
203
210
|
end
|
204
211
|
|
205
|
-
# bot
|
212
|
+
# bot nick in the client/server connection
|
206
213
|
def nick
|
207
214
|
myself.nick
|
208
215
|
end
|
209
216
|
|
217
|
+
# bot channels in the client/server connection
|
218
|
+
def channels
|
219
|
+
myself.channels
|
220
|
+
end
|
221
|
+
|
210
222
|
# nick wanted by the bot. This defaults to the irc.nick config value,
|
211
223
|
# but may be overridden by a manual !nick command
|
212
224
|
def wanted_nick
|
@@ -303,6 +315,9 @@ class Bot
|
|
303
315
|
Config.register Config::ArrayValue.new('irc.ignore_users',
|
304
316
|
:default => [],
|
305
317
|
:desc => "Which users to ignore input from. This is mainly to avoid bot-wars triggered by creative people")
|
318
|
+
Config.register Config::ArrayValue.new('irc.ignore_channels',
|
319
|
+
:default => [],
|
320
|
+
:desc => "Which channels to ignore input in. This is mainly to turn the bot into a logbot that doesn't interact with users in any way (in the specified channels)")
|
306
321
|
|
307
322
|
Config.register Config::IntegerValue.new('core.save_every',
|
308
323
|
:default => 60, :validate => Proc.new{|v| v >= 0},
|
@@ -395,6 +410,19 @@ class Bot
|
|
395
410
|
bot.set_default_send_options :truncate_text => v.dup
|
396
411
|
},
|
397
412
|
:desc => "When truncating overlong messages (see send.overlong) or when sending too many lines per message (see send.max_lines) replace the end of the last line with this text")
|
413
|
+
Config.register Config::IntegerValue.new('send.penalty_pct',
|
414
|
+
:default => 100,
|
415
|
+
:validate => Proc.new { |v| v >= 0 },
|
416
|
+
:on_change => Proc.new { |bot, v|
|
417
|
+
bot.socket.penalty_pct = v
|
418
|
+
},
|
419
|
+
:desc => "Percentage of IRC penalty to consider when sending messages to prevent being disconnected for excess flood. Set to 0 to disable penalty control.")
|
420
|
+
Config.register Config::StringValue.new('core.db',
|
421
|
+
:default => "bdb",
|
422
|
+
:wizard => true, :default => "bdb",
|
423
|
+
:validate => Proc.new { |v| ["bdb", "tc"].include? v },
|
424
|
+
:requires_restart => true,
|
425
|
+
:desc => "DB adaptor to use for storing settings and plugin data. Options are: bdb (Berkeley DB, stable adaptor, but troublesome to install and unmaintained), tc (Tokyo Cabinet, new adaptor, fast and furious, but may be not available and contain bugs)")
|
398
426
|
|
399
427
|
@argv = params[:argv]
|
400
428
|
@run_dir = params[:run_dir] || Dir.pwd
|
@@ -424,36 +452,25 @@ class Bot
|
|
424
452
|
botclass.gsub!("\\","/")
|
425
453
|
end
|
426
454
|
end
|
427
|
-
botclass
|
455
|
+
botclass = File.join(botclass, ".rbot")
|
428
456
|
end
|
429
457
|
botclass = File.expand_path(botclass)
|
430
458
|
@botclass = botclass.gsub(/\/$/, "")
|
431
459
|
|
432
|
-
|
433
|
-
# compare the templates dir with the current botclass, and fill it in with
|
434
|
-
# any missing file.
|
435
|
-
# Sadly, FileUtils.cp_r doesn't have an :update option, so we have to do it
|
436
|
-
# manually
|
437
|
-
template = File.join Config::datadir, 'templates'
|
438
|
-
# note that we use the */** pattern because we don't want to match
|
439
|
-
# keywords.rbot, which gets deleted on load and would therefore be missing always
|
440
|
-
missing = Dir.chdir(template) { Dir.glob('*/**') } - Dir.chdir(botclass) { Dir.glob('*/**') }
|
441
|
-
missing.map do |f|
|
442
|
-
dest = File.join(botclass, f)
|
443
|
-
FileUtils.mkdir_p File.dirname dest
|
444
|
-
FileUtils.cp File.join(template, f), dest
|
445
|
-
end
|
446
|
-
else
|
447
|
-
log "no #{botclass} directory found, creating from templates.."
|
448
|
-
if FileTest.exist? botclass
|
449
|
-
error "file #{botclass} exists but isn't a directory"
|
450
|
-
exit 2
|
451
|
-
end
|
452
|
-
FileUtils.cp_r Config::datadir+'/templates', botclass
|
453
|
-
end
|
460
|
+
repopulate_botclass_directory
|
454
461
|
|
455
|
-
|
456
|
-
Dir.mkdir(
|
462
|
+
registry_dir = File.join(@botclass, 'registry')
|
463
|
+
Dir.mkdir(registry_dir) unless File.exist?(registry_dir)
|
464
|
+
unless FileTest.directory? registry_dir
|
465
|
+
error "registry storage location #{registry_dir} is not a directory"
|
466
|
+
exit 2
|
467
|
+
end
|
468
|
+
save_dir = File.join(@botclass, 'safe_save')
|
469
|
+
Dir.mkdir(save_dir) unless File.exist?(save_dir)
|
470
|
+
unless FileTest.directory? save_dir
|
471
|
+
error "safe save location #{save_dir} is not a directory"
|
472
|
+
exit 2
|
473
|
+
end
|
457
474
|
|
458
475
|
# Time at which the last PING was sent
|
459
476
|
@last_ping = nil
|
@@ -474,10 +491,20 @@ class Bot
|
|
474
491
|
if @config['core.run_as_daemon']
|
475
492
|
$daemonize = true
|
476
493
|
end
|
494
|
+
case @config["core.db"]
|
495
|
+
when "bdb"
|
496
|
+
require 'rbot/registry/bdb'
|
497
|
+
when "tc"
|
498
|
+
require 'rbot/registry/tc'
|
499
|
+
else
|
500
|
+
raise _("Unknown DB adaptor: %s") % @config["core.db"]
|
501
|
+
end
|
477
502
|
|
478
503
|
@logfile = @config['log.file']
|
479
504
|
if @logfile.class!=String || @logfile.empty?
|
480
|
-
|
505
|
+
logfname = File.basename(botclass).gsub(/^\.+/,'')
|
506
|
+
logfname << ".log"
|
507
|
+
@logfile = File.join(botclass, logfname)
|
481
508
|
debug "Using `#{@logfile}' as debug log"
|
482
509
|
end
|
483
510
|
|
@@ -536,7 +563,7 @@ class Bot
|
|
536
563
|
end
|
537
564
|
end
|
538
565
|
|
539
|
-
File.open($opts['pidfile'] ||
|
566
|
+
File.open($opts['pidfile'] || File.join(@botclass, 'rbot.pid'), 'w') do |pf|
|
540
567
|
pf << "#{$$}\n"
|
541
568
|
end
|
542
569
|
|
@@ -566,7 +593,6 @@ class Bot
|
|
566
593
|
@auth.everyone.set_default_permission("*", true)
|
567
594
|
@auth.botowner.password= @config['auth.password']
|
568
595
|
|
569
|
-
Dir.mkdir("#{botclass}/plugins") unless File.exist?("#{botclass}/plugins")
|
570
596
|
@plugins = Plugins::manager
|
571
597
|
@plugins.bot_associate(self)
|
572
598
|
setup_plugins_path()
|
@@ -581,7 +607,7 @@ class Bot
|
|
581
607
|
debug "server.list is now #{@config['server.list'].inspect}"
|
582
608
|
end
|
583
609
|
|
584
|
-
@socket = Irc::Socket.new(@config['server.list'], @config['server.bindhost'], :ssl => @config['server.ssl'])
|
610
|
+
@socket = Irc::Socket.new(@config['server.list'], @config['server.bindhost'], :ssl => @config['server.ssl'], :penalty_pct =>@config['send.penalty_pct'])
|
585
611
|
@client = Client.new
|
586
612
|
|
587
613
|
@plugins.scan
|
@@ -629,11 +655,18 @@ class Bot
|
|
629
655
|
# debug "Message target is #{data[:target].inspect}"
|
630
656
|
# debug "Bot is #{myself.inspect}"
|
631
657
|
|
658
|
+
@config['irc.ignore_channels'].each { |channel|
|
659
|
+
if m.target.downcase == channel.downcase
|
660
|
+
m.ignored = true
|
661
|
+
break
|
662
|
+
end
|
663
|
+
}
|
632
664
|
@config['irc.ignore_users'].each { |mask|
|
633
665
|
if m.source.matches?(server.new_netmask(mask))
|
634
666
|
m.ignored = true
|
667
|
+
break
|
635
668
|
end
|
636
|
-
}
|
669
|
+
} unless m.ignored
|
637
670
|
|
638
671
|
@plugins.irc_delegate('privmsg', m)
|
639
672
|
}
|
@@ -736,6 +769,18 @@ class Bot
|
|
736
769
|
m.users = data[:users]
|
737
770
|
@plugins.delegate "names", m
|
738
771
|
}
|
772
|
+
@client[:banlist] = proc { |data|
|
773
|
+
m = BanlistMessage.new(self, server, server, data[:channel])
|
774
|
+
m.bans = data[:bans]
|
775
|
+
@plugins.delegate "banlist", m
|
776
|
+
}
|
777
|
+
@client[:nosuchtarget] = proc { |data|
|
778
|
+
m = NoSuchTargetMessage.new(self, server, server, data[:target], data[:message])
|
779
|
+
@plugins.delegate "nosuchtarget", m
|
780
|
+
}
|
781
|
+
@client[:error] = proc { |data|
|
782
|
+
raise ServerError, data[:message]
|
783
|
+
}
|
739
784
|
@client[:unknown] = proc { |data|
|
740
785
|
#debug "UNKNOWN: #{data[:serverstring]}"
|
741
786
|
m = UnknownMessage.new(self, server, server, nil, data[:serverstring])
|
@@ -753,15 +798,54 @@ class Bot
|
|
753
798
|
trap_sigs
|
754
799
|
end
|
755
800
|
|
801
|
+
def repopulate_botclass_directory
|
802
|
+
template_dir = File.join Config::datadir, 'templates'
|
803
|
+
if FileTest.directory? @botclass
|
804
|
+
# compare the templates dir with the current botclass dir, filling up the
|
805
|
+
# latter with any missing file. Sadly, FileUtils.cp_r doesn't have an
|
806
|
+
# :update option, so we have to do it manually.
|
807
|
+
# Note that we use the */** pattern because we don't want to match
|
808
|
+
# keywords.rbot, which gets deleted on load and would therefore be missing
|
809
|
+
# always
|
810
|
+
missing = Dir.chdir(template_dir) { Dir.glob('*/**') } - Dir.chdir(@botclass) { Dir.glob('*/**') }
|
811
|
+
missing.map do |f|
|
812
|
+
dest = File.join(@botclass, f)
|
813
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
814
|
+
FileUtils.cp File.join(template_dir, f), dest
|
815
|
+
end
|
816
|
+
else
|
817
|
+
log "no #{@botclass} directory found, creating from templates..."
|
818
|
+
if FileTest.exist? @botclass
|
819
|
+
error "file #{@botclass} exists but isn't a directory"
|
820
|
+
exit 2
|
821
|
+
end
|
822
|
+
FileUtils.cp_r template_dir, @botclass
|
823
|
+
end
|
824
|
+
end
|
825
|
+
|
826
|
+
# Return a path under the current botclass by joining the mentioned
|
827
|
+
# components. The components are automatically converted to String
|
828
|
+
def path(*components)
|
829
|
+
File.join(@botclass, *(components.map {|c| c.to_s}))
|
830
|
+
end
|
831
|
+
|
756
832
|
def setup_plugins_path
|
833
|
+
plugdir_default = File.join(Config::datadir, 'plugins')
|
834
|
+
plugdir_local = File.join(@botclass, 'plugins')
|
835
|
+
Dir.mkdir(plugdir_local) unless File.exist?(plugdir_local)
|
836
|
+
|
757
837
|
@plugins.clear_botmodule_dirs
|
758
|
-
@plugins.
|
759
|
-
@plugins.
|
760
|
-
|
838
|
+
@plugins.add_core_module_dir(File.join(Config::coredir, 'utils'))
|
839
|
+
@plugins.add_core_module_dir(Config::coredir)
|
840
|
+
if FileTest.directory? plugdir_local
|
841
|
+
@plugins.add_plugin_dir(plugdir_local)
|
842
|
+
else
|
843
|
+
warning "local plugin location #{plugdir_local} is not a directory"
|
844
|
+
end
|
761
845
|
|
762
846
|
@config['plugins.path'].each do |_|
|
763
|
-
path = _.sub(/^\(default\)/,
|
764
|
-
@plugins.
|
847
|
+
path = _.sub(/^\(default\)/, plugdir_default)
|
848
|
+
@plugins.add_plugin_dir(path)
|
765
849
|
end
|
766
850
|
end
|
767
851
|
|
@@ -782,7 +866,7 @@ class Bot
|
|
782
866
|
}
|
783
867
|
end
|
784
868
|
@default_send_options.update opts unless opts.empty?
|
785
|
-
|
869
|
+
end
|
786
870
|
|
787
871
|
# checks if we should be quiet on a channel
|
788
872
|
def quiet_on?(channel)
|
@@ -816,7 +900,8 @@ class Bot
|
|
816
900
|
# things to do when we receive a signal
|
817
901
|
def got_sig(sig, func=:quit)
|
818
902
|
debug "received #{sig}, queueing #{func}"
|
819
|
-
|
903
|
+
# this is not an interruption if we just need to reconnect
|
904
|
+
$interrupted += 1 unless func == :reconnect
|
820
905
|
self.send(func) unless @quit_mutex.locked?
|
821
906
|
debug "interrupted #{$interrupted} times"
|
822
907
|
if $interrupted >= 3
|
@@ -832,6 +917,7 @@ class Bot
|
|
832
917
|
trap("SIGINT") { got_sig("SIGINT") }
|
833
918
|
trap("SIGTERM") { got_sig("SIGTERM") }
|
834
919
|
trap("SIGHUP") { got_sig("SIGHUP", :restart) }
|
920
|
+
trap("SIGUSR1") { got_sig("SIGUSR1", :reconnect) }
|
835
921
|
rescue ArgumentError => e
|
836
922
|
debug "failed to trap signals (#{e.pretty_inspect}): running on Windows?"
|
837
923
|
rescue Exception => e
|
@@ -841,11 +927,15 @@ class Bot
|
|
841
927
|
|
842
928
|
# connect the bot to IRC
|
843
929
|
def connect
|
930
|
+
# make sure we don't have any spurious ping checks running
|
931
|
+
# (and initialize the vars if this is the first time we connect)
|
932
|
+
stop_server_pings
|
844
933
|
begin
|
845
934
|
quit if $interrupted > 0
|
846
935
|
@socket.connect
|
936
|
+
@last_rec = Time.now
|
847
937
|
rescue => e
|
848
|
-
raise e.class, "failed to connect to IRC server at #{@socket.server_uri}: "
|
938
|
+
raise e.class, "failed to connect to IRC server at #{@socket.server_uri}: #{e}"
|
849
939
|
end
|
850
940
|
quit if $interrupted > 0
|
851
941
|
|
@@ -859,14 +949,44 @@ class Bot
|
|
859
949
|
myself.user = @config['irc.user']
|
860
950
|
end
|
861
951
|
|
952
|
+
# disconnect the bot from IRC, if connected, and then connect (again)
|
953
|
+
def reconnect(message=nil, too_fast=false)
|
954
|
+
# we will wait only if @last_rec was not nil, i.e. if we were connected or
|
955
|
+
# got disconnected by a network error
|
956
|
+
# if someone wants to manually call disconnect() _and_ reconnect(), they
|
957
|
+
# will have to take care of the waiting themselves
|
958
|
+
will_wait = !!@last_rec
|
959
|
+
|
960
|
+
if @socket.connected?
|
961
|
+
disconnect(message)
|
962
|
+
end
|
963
|
+
|
964
|
+
begin
|
965
|
+
if will_wait
|
966
|
+
log "\n\nDisconnected\n\n"
|
967
|
+
|
968
|
+
quit if $interrupted > 0
|
969
|
+
|
970
|
+
log "\n\nWaiting to reconnect\n\n"
|
971
|
+
sleep @config['server.reconnect_wait']
|
972
|
+
sleep 10*@config['server.reconnect_wait'] if too_fast
|
973
|
+
end
|
974
|
+
|
975
|
+
connect
|
976
|
+
rescue Exception => e
|
977
|
+
will_wait = true
|
978
|
+
retry
|
979
|
+
end
|
980
|
+
end
|
981
|
+
|
862
982
|
# begin event handling loop
|
863
983
|
def mainloop
|
864
984
|
while true
|
985
|
+
too_fast = false
|
865
986
|
begin
|
866
|
-
quit if $interrupted > 0
|
867
|
-
connect
|
868
|
-
|
869
987
|
quit_msg = nil
|
988
|
+
reconnect(quit_msg, too_fast)
|
989
|
+
quit if $interrupted > 0
|
870
990
|
while @socket.connected?
|
871
991
|
quit if $interrupted > 0
|
872
992
|
|
@@ -892,6 +1012,11 @@ class Bot
|
|
892
1012
|
rescue Errno::ETIMEDOUT, Errno::ECONNABORTED, TimeoutError, SocketError => e
|
893
1013
|
error "network exception: #{e.pretty_inspect}"
|
894
1014
|
quit_msg = e.to_s
|
1015
|
+
rescue ServerError => e
|
1016
|
+
# received an ERROR from the server
|
1017
|
+
quit_msg = "server ERROR: " + e.message
|
1018
|
+
too_fast = e.message.index("reconnect too fast")
|
1019
|
+
retry
|
895
1020
|
rescue BDB::Fatal => e
|
896
1021
|
fatal "fatal bdb error: #{e.pretty_inspect}"
|
897
1022
|
DBTree.stats
|
@@ -907,15 +1032,6 @@ class Bot
|
|
907
1032
|
log_session_end
|
908
1033
|
exit 2
|
909
1034
|
end
|
910
|
-
|
911
|
-
disconnect(quit_msg)
|
912
|
-
|
913
|
-
log "\n\nDisconnected\n\n"
|
914
|
-
|
915
|
-
quit if $interrupted > 0
|
916
|
-
|
917
|
-
log "\n\nWaiting to reconnect\n\n"
|
918
|
-
sleep @config['server.reconnect_wait']
|
919
1035
|
end
|
920
1036
|
end
|
921
1037
|
|
@@ -926,8 +1042,22 @@ class Bot
|
|
926
1042
|
# Type can be PRIVMSG, NOTICE, etc, but those you should really use the
|
927
1043
|
# relevant say() or notice() methods. This one should be used for IRCd
|
928
1044
|
# extensions you want to use in modules.
|
929
|
-
def sendmsg(
|
930
|
-
|
1045
|
+
def sendmsg(original_type, original_where, original_message, options={})
|
1046
|
+
|
1047
|
+
# filter message with sendmsg filters
|
1048
|
+
ds = DataStream.new original_message.to_s.dup,
|
1049
|
+
:type => original_type, :dest => original_where,
|
1050
|
+
:options => @default_send_options.merge(options)
|
1051
|
+
filters = filter_names(:sendmsg)
|
1052
|
+
filters.each do |fname|
|
1053
|
+
debug "filtering #{ds[:text]} with sendmsg filter #{fname}"
|
1054
|
+
ds.merge! filter(self.global_filter_name(fname, :sendmsg), ds)
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
opts = ds[:options]
|
1058
|
+
type = ds[:type]
|
1059
|
+
where = ds[:dest]
|
1060
|
+
filtered = ds[:text]
|
931
1061
|
|
932
1062
|
# For starters, set up appropriate queue channels and rings
|
933
1063
|
mchan = opts[:queue_channel]
|
@@ -948,7 +1078,7 @@ class Bot
|
|
948
1078
|
end
|
949
1079
|
end
|
950
1080
|
|
951
|
-
multi_line =
|
1081
|
+
multi_line = filtered.gsub(/[\r\n]+/, "\n")
|
952
1082
|
|
953
1083
|
# if target is a channel with nocolor modes, strip colours
|
954
1084
|
if where.kind_of?(Channel) and where.mode.any?(*config['server.nocolor_modes'])
|
@@ -1151,7 +1281,9 @@ class Bot
|
|
1151
1281
|
|
1152
1282
|
# totally shutdown and respawn the bot
|
1153
1283
|
def restart(message=nil)
|
1154
|
-
message = "restarting, back in
|
1284
|
+
message = _("restarting, back in %{wait}...") % {
|
1285
|
+
:wait => @config['server.reconnect_wait']
|
1286
|
+
} if (!message || message.empty?)
|
1155
1287
|
shutdown(message)
|
1156
1288
|
sleep @config['server.reconnect_wait']
|
1157
1289
|
begin
|
data/lib/rbot/ircsocket.rb
CHANGED
@@ -48,8 +48,14 @@ class ::String
|
|
48
48
|
dests = pars.split($;,2).first
|
49
49
|
penalty += dests.split(',').size
|
50
50
|
when :WHO
|
51
|
-
|
52
|
-
|
51
|
+
args = pars.split
|
52
|
+
if args.length > 0
|
53
|
+
penalty += args.inject(0){ |sum,x| sum += ((x.length > 4) ? 3 : 5) }
|
54
|
+
else
|
55
|
+
penalty += 10
|
56
|
+
end
|
57
|
+
when :PART
|
58
|
+
penalty += 4
|
53
59
|
when :AWAY, :JOIN, :VERSION, :TIME, :TRACE, :WHOIS, :DNS
|
54
60
|
penalty += 2
|
55
61
|
when :INVITE, :NICK
|
@@ -246,6 +252,9 @@ module Irc
|
|
246
252
|
# normalized uri of the current server
|
247
253
|
attr_reader :server_uri
|
248
254
|
|
255
|
+
# penalty multiplier (percent)
|
256
|
+
attr_accessor :penalty_pct
|
257
|
+
|
249
258
|
# default trivial filter class
|
250
259
|
class IdentityFilter
|
251
260
|
def in(x)
|
@@ -275,11 +284,8 @@ module Irc
|
|
275
284
|
@spooler = false
|
276
285
|
@lines_sent = 0
|
277
286
|
@lines_received = 0
|
278
|
-
|
279
|
-
|
280
|
-
else
|
281
|
-
@ssl = false
|
282
|
-
end
|
287
|
+
@ssl = opts[:ssl]
|
288
|
+
@penalty_pct = opts[:penalty_pct] || 100
|
283
289
|
end
|
284
290
|
|
285
291
|
def connected?
|
@@ -437,7 +443,7 @@ module Irc
|
|
437
443
|
@sock.syswrite actual
|
438
444
|
@last_send = now
|
439
445
|
@flood_send = now if @flood_send < now
|
440
|
-
@flood_send += message.irc_send_penalty if penalty
|
446
|
+
@flood_send += message.irc_send_penalty*@penalty_pct/100.0 if penalty
|
441
447
|
@lines_sent += 1
|
442
448
|
end
|
443
449
|
rescue Exception => e
|