rbot 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/AUTHORS +16 -0
  2. data/COPYING +21 -0
  3. data/ChangeLog +418 -0
  4. data/INSTALL +8 -0
  5. data/README +44 -0
  6. data/REQUIREMENTS +34 -0
  7. data/TODO +5 -0
  8. data/Usage_en.txt +129 -0
  9. data/bin/rbot +81 -0
  10. data/data/rbot/contrib/plugins/figlet.rb +20 -0
  11. data/data/rbot/contrib/plugins/ri.rb +83 -0
  12. data/data/rbot/contrib/plugins/stats.rb +232 -0
  13. data/data/rbot/contrib/plugins/vandale.rb +49 -0
  14. data/data/rbot/languages/dutch.lang +73 -0
  15. data/data/rbot/languages/english.lang +75 -0
  16. data/data/rbot/languages/french.lang +39 -0
  17. data/data/rbot/languages/german.lang +67 -0
  18. data/data/rbot/plugins/autoop.rb +68 -0
  19. data/data/rbot/plugins/autorejoin.rb +16 -0
  20. data/data/rbot/plugins/cal.rb +15 -0
  21. data/data/rbot/plugins/dice.rb +81 -0
  22. data/data/rbot/plugins/eightball.rb +19 -0
  23. data/data/rbot/plugins/excuse.rb +470 -0
  24. data/data/rbot/plugins/fish.rb +61 -0
  25. data/data/rbot/plugins/fortune.rb +22 -0
  26. data/data/rbot/plugins/freshmeat.rb +98 -0
  27. data/data/rbot/plugins/google.rb +51 -0
  28. data/data/rbot/plugins/host.rb +14 -0
  29. data/data/rbot/plugins/httpd.rb.disabled +35 -0
  30. data/data/rbot/plugins/insult.rb +258 -0
  31. data/data/rbot/plugins/karma.rb +85 -0
  32. data/data/rbot/plugins/lart.rb +181 -0
  33. data/data/rbot/plugins/math.rb +122 -0
  34. data/data/rbot/plugins/nickserv.rb +89 -0
  35. data/data/rbot/plugins/nslookup.rb +43 -0
  36. data/data/rbot/plugins/opme.rb +19 -0
  37. data/data/rbot/plugins/quakeauth.rb +51 -0
  38. data/data/rbot/plugins/quotes.rb +321 -0
  39. data/data/rbot/plugins/remind.rb +228 -0
  40. data/data/rbot/plugins/roshambo.rb +54 -0
  41. data/data/rbot/plugins/rot13.rb +10 -0
  42. data/data/rbot/plugins/roulette.rb +147 -0
  43. data/data/rbot/plugins/rss.rb.disabled +414 -0
  44. data/data/rbot/plugins/seen.rb +89 -0
  45. data/data/rbot/plugins/slashdot.rb +94 -0
  46. data/data/rbot/plugins/spell.rb +36 -0
  47. data/data/rbot/plugins/tube.rb +71 -0
  48. data/data/rbot/plugins/url.rb +88 -0
  49. data/data/rbot/plugins/weather.rb +649 -0
  50. data/data/rbot/plugins/wserver.rb +71 -0
  51. data/data/rbot/plugins/xmlrpc.rb.disabled +52 -0
  52. data/data/rbot/templates/keywords.rbot +4 -0
  53. data/data/rbot/templates/lart/larts +98 -0
  54. data/data/rbot/templates/lart/praises +5 -0
  55. data/data/rbot/templates/levels.rbot +30 -0
  56. data/data/rbot/templates/users.rbot +1 -0
  57. data/lib/rbot/auth.rb +203 -0
  58. data/lib/rbot/channel.rb +54 -0
  59. data/lib/rbot/config.rb +363 -0
  60. data/lib/rbot/dbhash.rb +112 -0
  61. data/lib/rbot/httputil.rb +141 -0
  62. data/lib/rbot/ircbot.rb +808 -0
  63. data/lib/rbot/ircsocket.rb +185 -0
  64. data/lib/rbot/keywords.rb +433 -0
  65. data/lib/rbot/language.rb +69 -0
  66. data/lib/rbot/message.rb +256 -0
  67. data/lib/rbot/messagemapper.rb +262 -0
  68. data/lib/rbot/plugins.rb +291 -0
  69. data/lib/rbot/post-install.rb +8 -0
  70. data/lib/rbot/rbotconfig.rb +36 -0
  71. data/lib/rbot/registry.rb +271 -0
  72. data/lib/rbot/rfc2812.rb +1104 -0
  73. data/lib/rbot/timer.rb +201 -0
  74. data/lib/rbot/utils.rb +83 -0
  75. data/setup.rb +1360 -0
  76. metadata +129 -0
@@ -0,0 +1,85 @@
1
+ class KarmaPlugin < Plugin
2
+ def initialize
3
+ super
4
+
5
+ # this plugin only wants to store ints!
6
+ class << @registry
7
+ def store(val)
8
+ val.to_i
9
+ end
10
+ def restore(val)
11
+ val.to_i
12
+ end
13
+ end
14
+ @registry.set_default(0)
15
+
16
+ # import if old file format found
17
+ if(File.exist?("#{@bot.botclass}/karma.rbot"))
18
+ puts "importing old karma data"
19
+ IO.foreach("#{@bot.botclass}/karma.rbot") do |line|
20
+ if(line =~ /^(\S+)<=>([\d-]+)$/)
21
+ item = $1
22
+ karma = $2.to_i
23
+ @registry[item] = karma
24
+ end
25
+ end
26
+ File.delete("#{@bot.botclass}/karma.rbot")
27
+ end
28
+
29
+ end
30
+
31
+ def stats(m, params)
32
+ if (@registry.length)
33
+ max = @registry.values.max
34
+ min = @registry.values.min
35
+ best = @registry.to_hash.index(max)
36
+ worst = @registry.to_hash.index(min)
37
+ m.reply "#{@registry.length} items. Best: #{best} (#{max}); Worst: #{worst} (#{min})"
38
+ end
39
+ end
40
+
41
+ def karma(m, params)
42
+ thing = params[:key]
43
+ thing = m.sourcenick unless thing
44
+ thing = thing.to_s
45
+ karma = @registry[thing]
46
+ if(karma != 0)
47
+ m.reply "karma for #{thing}: #{@registry[thing]}"
48
+ else
49
+ m.reply "#{thing} has neutral karma"
50
+ end
51
+ end
52
+
53
+
54
+ def help(plugin, topic="")
55
+ "karma module: <thing>++/<thing>-- => increase/decrease karma for <thing>, karma for <thing>? => show karma for <thing>, karmastats => show stats. Karma is a community rating system - only in-channel messages can affect karma and you cannot adjust your own."
56
+ end
57
+ def listen(m)
58
+ return unless m.kind_of?(PrivMessage) && m.public?
59
+ # in channel message, the kind we are interested in
60
+ if(m.message =~ /(\+\+|--)/)
61
+ string = m.message.sub(/\W(--|\+\+)(\(.*?\)|[^(++)(\-\-)\s]+)/, "\2\1")
62
+ seen = Hash.new
63
+ while(string.sub!(/(\(.*?\)|[^(++)(\-\-)\s]+)(\+\+|--)/, ""))
64
+ key = $1
65
+ change = $2
66
+ next if seen[key]
67
+ seen[key] = true
68
+
69
+ key.sub!(/^\((.*)\)$/, "\1")
70
+ key.gsub!(/\s+/, " ")
71
+ next unless(key.length > 0)
72
+ next if(key == m.sourcenick)
73
+ if(change == "++")
74
+ @registry[key] += 1
75
+ elsif(change == "--")
76
+ @registry[key] -= 1
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ plugin = KarmaPlugin.new
83
+ plugin.map 'karmastats', :action => 'stats'
84
+ plugin.map 'karma :key', :defaults => {:key => false}
85
+ plugin.map 'karma for :key'
@@ -0,0 +1,181 @@
1
+ # Author: Michael Brailsford <brailsmt@yahoo.com>
2
+ # aka brailsmt
3
+ # Purpose: Provide for humorous larts and praises
4
+ # Copyright: 2002 Michael Brailsford. All rights reserved.
5
+ # License: This plugin is licensed under the BSD license. The terms of
6
+ # which follow.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions
10
+ # are met:
11
+ #
12
+ # 1. Redistributions of source code must retain the above copyright notice,
13
+ # this list of conditions and the following disclaimer.
14
+ #
15
+ # 2. Redistributions in binary form must reproduce the above copyright
16
+ # notice, this list of conditions and the following disclaimer in the
17
+ # documentation and/or other materials provided with the distribution.
18
+
19
+ class LartPlugin < Plugin
20
+
21
+ # Keep a 1:1 relation between commands and handlers
22
+ @@handlers = {
23
+ "lart" => "handle_lart",
24
+ "praise" => "handle_praise",
25
+ "addlart" => "handle_addlart",
26
+ "rmlart" => "handle_rmlart",
27
+ "addpraise" => "handle_addpraise",
28
+ "rmpraise" => "handle_rmpraise"
29
+ }
30
+
31
+ def name
32
+ "lart"
33
+ end
34
+
35
+ #{{{
36
+ def initialize
37
+ super
38
+ @larts = Array.new
39
+ @praises = Array.new
40
+ #read in the lart and praise files
41
+ if File.exists? "#{@bot.botclass}/lart/larts"
42
+ IO.foreach("#{@bot.botclass}/lart/larts") { |line|
43
+ @larts << line.chomp
44
+ }
45
+ end
46
+ if File.exists? "#{@bot.botclass}/lart/praises"
47
+ IO.foreach("#{@bot.botclass}/lart/praises") { |line|
48
+ @praises << line.chomp
49
+ }
50
+ end
51
+ end
52
+ #}}}
53
+ #{{{
54
+ def cleanup
55
+ end
56
+ #}}}
57
+ #{{{
58
+ def save
59
+ Dir.mkdir("#{@bot.botclass}/lart") if not FileTest.directory? "#{@bot.botclass}/lart"
60
+ File.open("#{@bot.botclass}/lart/larts", "w") { |file|
61
+ file.puts @larts
62
+ }
63
+ File.open("#{@bot.botclass}/lart/praises", "w") { |file|
64
+ file.puts @praises
65
+ }
66
+ end
67
+ #}}}
68
+ #{{{
69
+ def privmsg(m)
70
+ if not m.params
71
+ m.reply "What a crazy fool! Did you mean |help stats?"
72
+ return
73
+ end
74
+
75
+ meth = self.method(@@handlers[m.plugin])
76
+ meth.call(m) if(@bot.auth.allow?(m.plugin, m.source, m.replyto))
77
+ end
78
+ #}}}
79
+ #{{{
80
+ def help(plugin, topic="")
81
+ "Lart: The lart plugin allows you to punish/praise someone in the channel. You can also add new punishments and new praises as well as delete them. For the curious, LART is an acronym for Luser Attitude Readjustment Tool.\nUsage: punish/lart <nick> <reason> -- punishes <nick> for <reason>. The reason is optional.\n praise <nick> <reason> -- praises <nick> for <reason>. The reason is optional.\n mod[lart|punish|praise] [add|remove] -- Add or remove a lart or praise."
82
+ end
83
+ #}}}
84
+ # The following are command handlers {{{
85
+ #{{{
86
+ def handle_lart(m)
87
+ for_idx = m.params =~ /\s+\bfor\b/
88
+ if for_idx
89
+ nick = m.params[0, for_idx]
90
+ else
91
+ nick = m.params
92
+ end
93
+ lart = @larts[get_msg_idx(@larts.length)]
94
+ if lart == nil
95
+ m.reply "I dunno any larts"
96
+ return
97
+ end
98
+ if nick == @bot.nick
99
+ lart = replace_who lart, m.sourcenick
100
+ lart << " for trying to make me lart myself"
101
+ else
102
+ lart = replace_who lart, nick
103
+ lart << m.params[for_idx, m.params.length] if for_idx
104
+ end
105
+
106
+ @bot.action m.replyto, lart
107
+ end
108
+ #}}}
109
+ #{{{
110
+ def handle_praise(m)
111
+ for_idx = m.params =~ /\s+\bfor\b/
112
+ if for_idx
113
+ nick = m.params[0, for_idx]
114
+ else
115
+ nick = m.params
116
+ end
117
+ praise = @praises[get_msg_idx(@praises.length)]
118
+ if not praise
119
+ m.reply "I dunno any praises"
120
+ return
121
+ end
122
+
123
+ if nick == m.sourcenick
124
+ praise = @larts[get_msg_idx(@larts.length)]
125
+ praise = replace_who praise, nick
126
+ else
127
+ praise = replace_who praise, nick
128
+ praise << m.params.gsub(/#{nick}/, "")
129
+ end
130
+
131
+ @bot.action m.replyto, praise
132
+ end
133
+ #}}}
134
+ #{{{
135
+ def handle_addlart(m)
136
+ @larts << m.params
137
+ m.okay
138
+ end
139
+ #}}}
140
+ #{{{
141
+ def handle_rmlart(m)
142
+ @larts.delete m.params
143
+ m.okay
144
+ end
145
+ #}}}
146
+ #{{{
147
+ def handle_addpraise(m)
148
+ @praises << m.params
149
+ m.okay
150
+ end
151
+ #}}}
152
+ #{{{
153
+ def handle_rmpraise(m)
154
+ @praises.delete m.params
155
+ m.okay
156
+ end
157
+ #}}}
158
+ #}}}
159
+
160
+ # The following are utils for larts/praises {{{
161
+ #{{{
162
+ def replace_who(msg, nick)
163
+ msg.gsub(/<who>/i, "#{nick}")
164
+ end
165
+ #}}}
166
+ #{{{
167
+ def get_msg_idx(max)
168
+ idx = rand(max)
169
+ end
170
+ #}}}
171
+ #}}}
172
+ end
173
+ plugin = LartPlugin.new
174
+ plugin.register("lart")
175
+ plugin.register("praise")
176
+
177
+ plugin.register("addlart")
178
+ plugin.register("addpraise")
179
+
180
+ plugin.register("rmlart")
181
+ plugin.register("rmpraise")
@@ -0,0 +1,122 @@
1
+ class MathPlugin < Plugin
2
+ @@digits = {
3
+ "first" => "1",
4
+ "second" => "2",
5
+ "third" => "3",
6
+ "fourth" => "4",
7
+ "fifth" => "5",
8
+ "sixth" => "6",
9
+ "seventh" => "7",
10
+ "eighth" => "8",
11
+ "ninth" => "9",
12
+ "tenth" => "10",
13
+ "one" => "1",
14
+ "two" => "2",
15
+ "three" => "3",
16
+ "four" => "4",
17
+ "five" => "5",
18
+ "six" => "6",
19
+ "seven" => "7",
20
+ "eight" => "8",
21
+ "nine" => "9",
22
+ "ten" => "10"
23
+ };
24
+
25
+ def help(plugin, topic="")
26
+ "math <expression>, evaluate mathematical expression"
27
+ end
28
+ def privmsg(m)
29
+ unless(m.params)
30
+ m.reply "incorrect usage: " + help(m.plugin)
31
+ return
32
+ end
33
+
34
+ expr = m.params.dup
35
+ @@digits.each {|k,v|
36
+ expr.gsub!(/\b#{k}\b/, v)
37
+ }
38
+
39
+ while expr =~ /(exp ([\w\d]+))/
40
+ exp = $1
41
+ val = Math.exp($2).to_s
42
+ expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
43
+ end
44
+
45
+ while expr =~ /^\s*(dec2hex\s*(\d+))\s*\?*/
46
+ exp = $1
47
+ val = sprintf("%x", $2)
48
+ expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
49
+ end
50
+
51
+ expr.gsub(/\be\b/, Math.exp(1).to_s)
52
+
53
+ while expr =~ /(log\s*((\d+\.?\d*)|\d*\.?\d+))\s*/
54
+ exp = $1
55
+ res = $2
56
+
57
+ if res == 0
58
+ val = "Infinity"
59
+ else
60
+ val = Math.log(res).to_s
61
+ end
62
+
63
+ expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
64
+ end
65
+
66
+ while expr =~ /(bin2dec ([01]+))/
67
+ exp = $1
68
+ val = join('', unpack('B*', pack('N', $2)))
69
+ val.gsub!(/^0+/, "")
70
+ expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
71
+ end
72
+
73
+ expr.gsub!(/ to the power of /, " ** ")
74
+ expr.gsub!(/ to the /, " ** ")
75
+ expr.gsub!(/\btimes\b/, "*")
76
+ expr.gsub!(/\bdiv(ided by)? /, "/ ")
77
+ expr.gsub!(/\bover /, "/ ")
78
+ expr.gsub!(/\bsquared/, "**2 ")
79
+ expr.gsub!(/\bcubed/, "**3 ")
80
+ expr.gsub!(/\bto\s+(\d+)(r?st|nd|rd|th)?( power)?/, "**\1 ")
81
+ expr.gsub!(/\bpercent of/, "*0.01*")
82
+ expr.gsub!(/\bpercent/, "*0.01")
83
+ expr.gsub!(/\% of\b/, "*0.01*")
84
+ expr.gsub!(/\%/, "*0.01")
85
+ expr.gsub!(/\bsquare root of (\d+)/, "\1 ** 0.5 ")
86
+ expr.gsub!(/\bcubed? root of (\d+)/, "\1 **(1.0/3.0) ")
87
+ expr.gsub!(/ of /, " * ")
88
+ expr.gsub!(/(bit(-| )?)?xor(\'?e?d( with))?/, "^")
89
+ expr.gsub!(/(bit(-| )?)?or(\'?e?d( with))?/, "|")
90
+ expr.gsub!(/bit(-| )?and(\'?e?d( with))?/, "& ")
91
+ expr.gsub!(/(plus|and)/, "+")
92
+
93
+ if (expr =~ /^\s*[-\d*+\s()\/^\.\|\&\*\!]+\s*$/ &&
94
+ expr !~ /^\s*\(?\d+\.?\d*\)?\s*$/ &&
95
+ expr !~ /^\s*$/ &&
96
+ expr !~ /^\s*[( )]+\s*$/)
97
+
98
+ begin
99
+ debug "evaluating expression \"#{expr}\""
100
+ answer = eval(expr)
101
+ if answer =~ /^[-+\de\.]+$/
102
+ answer = sprintf("%1.12f", answer)
103
+ answer.gsub!(/\.?0+$/, "")
104
+ answer.gsub!(/(\.\d+)000\d+/, '\1')
105
+ if (answer.length > 30)
106
+ answer = "a number with >30 digits..."
107
+ end
108
+ end
109
+ m.reply answer
110
+ rescue Exception => e
111
+ puts "couldn't evaluate expression \"#{m.params}\": #{e}"
112
+ m.reply "illegal expression \"#{m.params}\""
113
+ return
114
+ end
115
+ else
116
+ m.reply "illegal expression \"#{m.params}\""
117
+ return
118
+ end
119
+ end
120
+ end
121
+ plugin = MathPlugin.new
122
+ plugin.register("math")
@@ -0,0 +1,89 @@
1
+ # automatically lookup nicks in @registry and identify when asked
2
+
3
+ class NickServPlugin < Plugin
4
+
5
+ def help(plugin, topic="")
6
+ case topic
7
+ when ""
8
+ return "nickserv plugin: handles nickserv protected IRC nicks. topics password, register, identify, listnicks"
9
+ when "password"
10
+ return "nickserv password <nick> <passwd>: remember the password for nick <nick> and use it to identify in future"
11
+ when "register"
12
+ return "nickserv register [<password> [<email>]]: register the current nick, choosing a random password unless <password> is supplied - current nick must not already be registered for this to work. Also specify email if required by your services"
13
+ when "identify"
14
+ return "nickserv identify: identify with nickserv - shouldn't be needed - bot should identify with nickserv immediately on request - however this could be useful after splits or service disruptions, or when you just set the password for the current nick"
15
+ when "listnicks"
16
+ return "nickserv listnicks: lists nicknames and associated password the bot knows about - you will need config level auth access to do this one and it will reply by privmsg only"
17
+ end
18
+ end
19
+
20
+ def genpasswd
21
+ # generate a random password
22
+ passwd = ""
23
+ 8.times do
24
+ passwd += (rand(26) + (rand(2) == 0 ? 65 : 97) ).chr
25
+ end
26
+ return passwd
27
+ end
28
+
29
+ def initialize
30
+ super
31
+ # this plugin only wants to store strings!
32
+ class << @registry
33
+ def store(val)
34
+ val
35
+ end
36
+ def restore(val)
37
+ val
38
+ end
39
+ end
40
+ end
41
+
42
+ def password(m, params)
43
+ @registry[params[:nick]] = params[:passwd]
44
+ m.okay
45
+ end
46
+ def nick_register(m, params)
47
+ passwd = params[:passwd] ? params[:passwd] : genpasswd
48
+ message = "REGISTER #{passwd}"
49
+ message += " #{params[:email]}" if params[:email]
50
+ @bot.sendmsg "PRIVMSG", "NickServ", message
51
+ @registry[@bot.nick] = passwd
52
+ m.okay
53
+ end
54
+ def listnicks(m, params)
55
+ if @registry.length > 0
56
+ @registry.each {|k,v|
57
+ @bot.say m.sourcenick, "#{k} => #{v}"
58
+ }
59
+ else
60
+ m.reply "none known"
61
+ end
62
+ end
63
+ def identify(m, params)
64
+ if @registry.has_key?(@bot.nick)
65
+ @bot.sendmsg "PRIVMSG", "NickServ", "IDENTIFY #{@registry[@bot.nick]}"
66
+ m.okay
67
+ else
68
+ m.reply "I dunno the nickserv password for the nickname #{@bot.nick} :("
69
+ end
70
+ end
71
+
72
+ def listen(m)
73
+ return unless(m.kind_of? NoticeMessage)
74
+
75
+ if (m.sourcenick == "NickServ" && m.message =~ /This nickname is owned by someone else/)
76
+ debug "nickserv asked us to identify for nick #{@bot.nick}"
77
+ if @registry.has_key?(@bot.nick)
78
+ @bot.sendmsg "PRIVMSG", "NickServ", "IDENTIFY " + @registry[@bot.nick]
79
+ end
80
+ end
81
+ end
82
+
83
+ end
84
+ plugin = NickServPlugin.new
85
+ plugin.map 'nickserv password :nick :passwd'
86
+ plugin.map 'nickserv register :passwd :email', :action => 'nick_register',
87
+ :defaults => {:passwd => false, :email => false}
88
+ plugin.map 'nickserv listnicks'
89
+ plugin.map 'nickserv identify'