rbot 0.9.9 → 0.9.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. data/AUTHORS +8 -0
  2. data/ChangeLog +51 -0
  3. data/INSTALL +4 -0
  4. data/README +1 -0
  5. data/REQUIREMENTS +11 -0
  6. data/TODO +2 -0
  7. data/bin/rbot +21 -2
  8. data/data/rbot/languages/german.lang +4 -1
  9. data/data/rbot/languages/russian.lang +75 -0
  10. data/data/rbot/plugins/autoop.rb +42 -51
  11. data/data/rbot/plugins/bans.rb +205 -0
  12. data/data/rbot/plugins/bash.rb +56 -0
  13. data/data/rbot/plugins/chucknorris.rb +74 -0
  14. data/data/rbot/plugins/chucknorris.yml.gz +0 -0
  15. data/data/rbot/plugins/deepthoughts.rb +95 -0
  16. data/data/rbot/plugins/demauro.rb +95 -0
  17. data/data/rbot/plugins/digg.rb +51 -0
  18. data/data/rbot/plugins/figlet.rb +24 -0
  19. data/data/rbot/plugins/forecast.rb +133 -0
  20. data/data/rbot/plugins/freshmeat.rb +13 -7
  21. data/data/rbot/plugins/google.rb +2 -0
  22. data/data/rbot/plugins/grouphug.rb +36 -0
  23. data/data/rbot/plugins/imdb.rb +92 -0
  24. data/data/rbot/plugins/insult.rb +8 -1
  25. data/data/rbot/plugins/iplookup.rb +227 -0
  26. data/data/rbot/plugins/karma.rb +2 -2
  27. data/data/rbot/plugins/keywords.rb +470 -0
  28. data/data/rbot/plugins/lart.rb +132 -146
  29. data/data/rbot/plugins/lastfm.rb +25 -0
  30. data/data/rbot/plugins/markov.rb +204 -0
  31. data/data/rbot/plugins/math.rb +5 -1
  32. data/data/rbot/plugins/nickserv.rb +71 -11
  33. data/data/rbot/plugins/opme.rb +19 -19
  34. data/data/rbot/plugins/quakeauth.rb +2 -2
  35. data/data/rbot/plugins/quotes.rb +40 -25
  36. data/data/rbot/plugins/remind.rb +1 -1
  37. data/data/rbot/plugins/rot13.rb +2 -2
  38. data/data/rbot/plugins/roulette.rb +49 -15
  39. data/data/rbot/plugins/rss.rb +585 -0
  40. data/data/rbot/plugins/rubyurl.rb +39 -0
  41. data/data/rbot/plugins/seen.rb +2 -1
  42. data/data/rbot/plugins/slashdot.rb +5 -5
  43. data/data/rbot/plugins/spell.rb +5 -0
  44. data/data/rbot/plugins/theyfightcrime.rb +121 -0
  45. data/data/rbot/plugins/threat.rb +55 -0
  46. data/data/rbot/plugins/tinyurl.rb +39 -0
  47. data/data/rbot/plugins/topic.rb +204 -0
  48. data/data/rbot/plugins/urban.rb +71 -0
  49. data/data/rbot/plugins/url.rb +399 -4
  50. data/data/rbot/plugins/wow.rb +123 -0
  51. data/data/rbot/plugins/wserver.rb +1 -1
  52. data/data/rbot/templates/levels.rbot +2 -0
  53. data/lib/rbot/auth.rb +207 -96
  54. data/lib/rbot/channel.rb +5 -5
  55. data/lib/rbot/config.rb +125 -24
  56. data/lib/rbot/dbhash.rb +87 -21
  57. data/lib/rbot/httputil.rb +181 -13
  58. data/lib/rbot/ircbot.rb +525 -179
  59. data/lib/rbot/ircsocket.rb +330 -54
  60. data/lib/rbot/message.rb +66 -23
  61. data/lib/rbot/messagemapper.rb +25 -17
  62. data/lib/rbot/plugins.rb +244 -115
  63. data/lib/rbot/post-clean.rb +1 -0
  64. data/lib/rbot/{post-install.rb → post-config.rb} +1 -1
  65. data/lib/rbot/rbotconfig.rb +29 -14
  66. data/lib/rbot/registry.rb +111 -72
  67. data/lib/rbot/rfc2812.rb +208 -197
  68. data/lib/rbot/timer.rb +4 -0
  69. data/lib/rbot/utils.rb +2 -2
  70. metadata +127 -104
  71. data/data/rbot/plugins/rss.rb.disabled +0 -414
  72. data/lib/rbot/keywords.rb +0 -433
@@ -22,6 +22,9 @@ class MathPlugin < Plugin
22
22
  "ten" => "10"
23
23
  };
24
24
 
25
+ def name
26
+ "math"
27
+ end
25
28
  def help(plugin, topic="")
26
29
  "math <expression>, evaluate mathematical expression"
27
30
  end
@@ -108,7 +111,7 @@ class MathPlugin < Plugin
108
111
  end
109
112
  m.reply answer
110
113
  rescue Exception => e
111
- puts "couldn't evaluate expression \"#{m.params}\": #{e}"
114
+ error "couldn't evaluate expression \"#{m.params}\": #{e.inspect}"
112
115
  m.reply "illegal expression \"#{m.params}\""
113
116
  return
114
117
  end
@@ -120,3 +123,4 @@ class MathPlugin < Plugin
120
123
  end
121
124
  plugin = MathPlugin.new
122
125
  plugin.register("math")
126
+ plugin.register("maths")
@@ -1,7 +1,25 @@
1
- # automatically lookup nicks in @registry and identify when asked
1
+ # Automatically lookup nicks in @registry and identify when asked
2
+ # Takes over proper nick if required and nick is registered
3
+ # TODO allow custom IDENTIFY and GHOST names
4
+ # TODO instead of nickserv.wait it would be ideal if we could just
5
+ # set up "don't send further commands until you receive this particular message"
2
6
 
3
7
  class NickServPlugin < Plugin
4
8
 
9
+ BotConfig.register BotConfigStringValue.new('nickserv.name',
10
+ :default => "NickServ", :requires_restart => false,
11
+ :desc => "Name of the nick server")
12
+ BotConfig.register BotConfigStringValue.new('nickserv.ident_request',
13
+ :default => "IDENTIFY", :requires_restart => false,
14
+ :on_change => Proc.new { |bot, v| bot.plugins.delegate "set_ident_request", v },
15
+ :desc => "String to look for to see if the nick server is asking us to identify")
16
+ BotConfig.register BotConfigBooleanValue.new('nickserv.wants_nick',
17
+ :default => true, :requires_restart => false,
18
+ :desc => "Set to false if the nick server doesn't expect the nick as a parameter in the identify command")
19
+ BotConfig.register BotConfigIntegerValue.new('nickserv.wait',
20
+ :default => 30, :validate => Proc.new { |v| v > 0 }, :requires_restart => false,
21
+ :desc => "Seconds to wait after sending a message to nickserv, e.g. after ghosting")
22
+
5
23
  def help(plugin, topic="")
6
24
  case topic
7
25
  when ""
@@ -26,6 +44,10 @@ class NickServPlugin < Plugin
26
44
  return passwd
27
45
  end
28
46
 
47
+ def set_ident_request(val)
48
+ @ident_request = Regexp.new(val)
49
+ end
50
+
29
51
  def initialize
30
52
  super
31
53
  # this plugin only wants to store strings!
@@ -37,20 +59,23 @@ class NickServPlugin < Plugin
37
59
  val
38
60
  end
39
61
  end
62
+ set_ident_request(@bot.config['nickserv.ident_request'])
40
63
  end
41
64
 
42
65
  def password(m, params)
43
66
  @registry[params[:nick]] = params[:passwd]
44
67
  m.okay
45
68
  end
69
+
46
70
  def nick_register(m, params)
47
71
  passwd = params[:passwd] ? params[:passwd] : genpasswd
48
72
  message = "REGISTER #{passwd}"
49
73
  message += " #{params[:email]}" if params[:email]
50
- @bot.sendmsg "PRIVMSG", "NickServ", message
74
+ @bot.sendmsg "PRIVMSG", @bot.config['nickserv.name'], message
51
75
  @registry[@bot.nick] = passwd
52
76
  m.okay
53
77
  end
78
+
54
79
  def listnicks(m, params)
55
80
  if @registry.length > 0
56
81
  @registry.each {|k,v|
@@ -60,30 +85,65 @@ class NickServPlugin < Plugin
60
85
  m.reply "none known"
61
86
  end
62
87
  end
88
+
89
+ def do_identify(nick=@bot.nick)
90
+ if @registry.has_key?(nick)
91
+ if @bot.config['nickserv.wants_nick']
92
+ @bot.sendmsg "PRIVMSG", @bot.config['nickserv.name'], "IDENTIFY #{nick} #{@registry[nick]}"
93
+ else
94
+ if nick == @bot.nick
95
+ @bot.sendmsg "PRIVMSG", @bot.config['nickserv.name'], "IDENTIFY #{@registry[nick]}"
96
+ else
97
+ # We cannot identify for different nicks if we can't use the nickname ...
98
+ return false
99
+ end
100
+ end
101
+ return true
102
+ end
103
+ return false
104
+ end
105
+
63
106
  def identify(m, params)
64
- if @registry.has_key?(@bot.nick)
65
- @bot.sendmsg "PRIVMSG", "NickServ", "IDENTIFY #{@registry[@bot.nick]}"
107
+ if do_identify
66
108
  m.okay
67
109
  else
68
110
  m.reply "I dunno the nickserv password for the nickname #{@bot.nick} :("
69
111
  end
70
112
  end
71
113
 
114
+ def connect
115
+ do_identify
116
+ end
117
+
118
+ def nicktaken(nick)
119
+ if @registry.has_key?(nick)
120
+ @bot.sendmsg "PRIVMSG", @bot.config['nickserv.name'], "GHOST #{nick} #{@registry[nick]}"
121
+ if do_identify nick
122
+ sleep @bot.config['nickserv.wait']
123
+ @bot.nickchg nick
124
+ # We need to wait after changing nick, otherwise the server
125
+ # might refuse to execute further commangs, e.g. subsequent JOIN
126
+ # commands until the nick has changed.
127
+ sleep @bot.config['nickserv.wait']
128
+ else
129
+ debug "Failed to identify for nick #{nick}, cannot take over"
130
+ end
131
+ end
132
+ end
133
+
72
134
  def listen(m)
73
135
  return unless(m.kind_of? NoticeMessage)
74
136
 
75
- if (m.sourcenick == "NickServ" && m.message =~ /This nickname is owned by someone else/)
137
+ if (m.sourcenick == @bot.config['nickserv.name'] && m.message =~ @ident_request)
76
138
  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
139
+ do_identify
80
140
  end
81
141
  end
82
142
 
83
143
  end
84
144
  plugin = NickServPlugin.new
85
- plugin.map 'nickserv password :nick :passwd'
145
+ plugin.map 'nickserv password :nick :passwd', :action => "password"
86
146
  plugin.map 'nickserv register :passwd :email', :action => 'nick_register',
87
147
  :defaults => {:passwd => false, :email => false}
88
- plugin.map 'nickserv listnicks'
89
- plugin.map 'nickserv identify'
148
+ plugin.map 'nickserv listnicks', :action => "listnicks"
149
+ plugin.map 'nickserv identify', :action => "identify"
@@ -1,19 +1,19 @@
1
- class OpMePlugin < Plugin
2
-
3
- def help(plugin, topic="")
4
- return "opme <channel> => grant user ops in <channel>"
5
- end
6
-
7
- def privmsg(m)
8
- if(m.params)
9
- channel = m.params
10
- else
11
- channel = m.channel
12
- end
13
- target = m.sourcenick
14
- @bot.sendq("MODE #{channel} +o #{target}")
15
- m.okay
16
- end
17
- end
18
- plugin = OpMePlugin.new
19
- plugin.register("opme")
1
+ class OpMePlugin < Plugin
2
+
3
+ def help(plugin, topic="")
4
+ return "opme <channel> => grant user ops in <channel>"
5
+ end
6
+
7
+ def privmsg(m)
8
+ if(m.params)
9
+ channel = m.params
10
+ else
11
+ channel = m.channel
12
+ end
13
+ target = m.sourcenick
14
+ m.okay
15
+ @bot.sendq("MODE #{channel} +o #{target}")
16
+ end
17
+ end
18
+ plugin = OpMePlugin.new
19
+ plugin.register("opme")
@@ -27,7 +27,7 @@ class QPlugin < Plugin
27
27
  end
28
28
 
29
29
  def set(m, params)
30
- @registry['quakenet.user'] = params[:user]
30
+ @registry['quakenet.user'] = params[:nick]
31
31
  @registry['quakenet.auth'] = params[:passwd]
32
32
  m.okay
33
33
  end
@@ -48,4 +48,4 @@ class QPlugin < Plugin
48
48
  end
49
49
  plugin = QPlugin.new
50
50
  plugin.map 'qauth set :nick :passwd', :action => "set"
51
- plugin.map 'quath identify', :action => "identify"
51
+ plugin.map 'qauth identify', :action => "identify"
@@ -1,10 +1,13 @@
1
- Quote = Struct.new("Quote", "num", "date", "source", "quote")
1
+ # GB: Ok, we *really* need to switch to db for this plugin too
2
+
3
+ Quote = Struct.new("Quote", :num, :date, :source, :quote)
2
4
 
3
5
  class QuotePlugin < Plugin
4
6
  def initialize
5
7
  super
6
8
  @lists = Hash.new
7
9
  Dir["#{@bot.botclass}/quotes/*"].each {|f|
10
+ next if File.directory?(f)
8
11
  channel = File.basename(f)
9
12
  @lists[channel] = Array.new if(!@lists.has_key?(channel))
10
13
  IO.foreach(f) {|line|
@@ -17,12 +20,23 @@ class QuotePlugin < Plugin
17
20
  end
18
21
  def save
19
22
  Dir.mkdir("#{@bot.botclass}/quotes") if(!FileTest.directory?("#{@bot.botclass}/quotes"))
23
+ Dir.mkdir("#{@bot.botclass}/quotes/new") if(!FileTest.directory?("#{@bot.botclass}/quotes/new"))
20
24
  @lists.each {|channel, quotes|
21
- File.open("#{@bot.botclass}/quotes/#{channel}", "w") {|file|
22
- quotes.compact.each {|q|
23
- file.puts "#{q.num} | #{q.date} | #{q.source} | #{q.quote}"
25
+ begin
26
+ debug "Writing new quotefile for channel #{channel} ..."
27
+ File.open("#{@bot.botclass}/quotes/new/#{channel}", "w") {|file|
28
+ quotes.compact.each {|q|
29
+ file.puts "#{q.num} | #{q.date} | #{q.source} | #{q.quote}"
30
+ }
24
31
  }
25
- }
32
+ debug "Officializing quotefile for channel #{channel} ..."
33
+ File.rename("#{@bot.botclass}/quotes/new/#{channel}",
34
+ "#{@bot.botclass}/quotes/#{channel}")
35
+ rescue => e
36
+ error "failed to write quotefile for channel #{channel}!\n#{$!}"
37
+ error "#{e.class}: #{e}"
38
+ error e.backtrace.join("\n")
39
+ end
26
40
  }
27
41
  end
28
42
  def addquote(source, channel, quote)
@@ -41,7 +55,7 @@ class QuotePlugin < Plugin
41
55
  else
42
56
  # random quote
43
57
  return @lists[channel].compact[rand(@lists[channel].nitems)],
44
- @lists[channel].length - 1
58
+ @lists[channel].length - 1
45
59
  end
46
60
  end
47
61
  def delquote(channel, num)
@@ -49,6 +63,7 @@ class QuotePlugin < Plugin
49
63
  return false unless(@lists[channel].length > 0)
50
64
  if(@lists[channel][num])
51
65
  @lists[channel][num] = nil
66
+ @lists[channel].pop if num == @lists[channel].length - 1
52
67
  return true
53
68
  end
54
69
  return false
@@ -75,31 +90,31 @@ class QuotePlugin < Plugin
75
90
  return nil unless(@lists[channel].length > 0)
76
91
  matches = @lists[channel].compact.find_all {|a| a.quote =~ /#{regexp}/i }
77
92
  if(matches.length > 0)
78
- return matches[rand(matches.length)], @lists[channel].length - 1
93
+ return matches[rand(matches.length)], @lists[channel].length - 1
79
94
  else
80
95
  return nil
81
96
  end
82
97
  end
83
98
  def help(plugin, topic="")
84
99
  case topic
85
- when "addquote"
86
- return "addquote [<channel>] <quote> => Add quote <quote> for channel <channel>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !addquote without addressing if so configured"
87
- when "delquote"
88
- return "delquote [<channel>] <num> => delete quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !delquote without addressing if so configured"
89
- when "getquote"
90
- return "getquote [<channel>] [<num>] => get quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Without <num>, a random quote will be returned. Responds to !getquote without addressing if so configured"
91
- when "searchquote"
92
- return "searchquote [<channel>] <regexp> => search for quote from <channel> that matches <regexp>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !searchquote without addressing if so configured"
93
- when "topicquote"
94
- return "topicquote [<channel>] [<num>] => set topic to quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Without <num>, a random quote will be set. Responds to !topicquote without addressing if so configured"
95
- when "countquote"
96
- return "countquote [<channel>] <regexp> => count quotes from <channel> that match <regexp>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !countquote without addressing if so configured"
97
- when "whoquote"
98
- return "whoquote [<channel>] <num> => show who added quote <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately"
99
- when "whenquote"
100
- return "whenquote [<channel>] <num> => show when quote <num> was added. You only need to supply <channel> if you are addressing #{@bot.nick} privately"
101
- else
102
- return "Quote module (Quote storage and retrieval) topics: addquote, getquote, searchquote, topicquote, countquote, whoquote, whenquote"
100
+ when "addquote"
101
+ return "addquote [<channel>] <quote> => Add quote <quote> for channel <channel>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !addquote without addressing if so configured"
102
+ when "delquote"
103
+ return "delquote [<channel>] <num> => delete quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !delquote without addressing if so configured"
104
+ when "getquote"
105
+ return "getquote [<channel>] [<num>] => get quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Without <num>, a random quote will be returned. Responds to !getquote without addressing if so configured"
106
+ when "searchquote"
107
+ return "searchquote [<channel>] <regexp> => search for quote from <channel> that matches <regexp>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !searchquote without addressing if so configured"
108
+ when "topicquote"
109
+ return "topicquote [<channel>] [<num>] => set topic to quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Without <num>, a random quote will be set. Responds to !topicquote without addressing if so configured"
110
+ when "countquote"
111
+ return "countquote [<channel>] <regexp> => count quotes from <channel> that match <regexp>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !countquote without addressing if so configured"
112
+ when "whoquote"
113
+ return "whoquote [<channel>] <num> => show who added quote <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately"
114
+ when "whenquote"
115
+ return "whenquote [<channel>] <num> => show when quote <num> was added. You only need to supply <channel> if you are addressing #{@bot.nick} privately"
116
+ else
117
+ return "Quote module (Quote storage and retrieval) topics: addquote, delquote, getquote, searchquote, topicquote, countquote, whoquote, whenquote"
103
118
  end
104
119
  end
105
120
  def listen(m)
@@ -175,7 +175,7 @@ class RemindPlugin < Plugin
175
175
  def remind(m, params)
176
176
  who = params.has_key?(:who) ? params[:who] : m.sourcenick
177
177
  string = params[:string].to_s
178
- puts "in remind, string is: #{string}"
178
+ debug "in remind, string is: #{string}"
179
179
  if(string =~ /^(.*)\s+in\s+(.*)$/)
180
180
  subject = $1
181
181
  period = $2
@@ -3,8 +3,8 @@ class RotPlugin < Plugin
3
3
  "rot13 <string> => encode <string> to rot13 or back"
4
4
  end
5
5
  def rot13(m, params)
6
- m.reply params[:string].tr("A-Za-z", "N-ZA-Mn-za-m");
6
+ m.reply params[:string].join(" ").tr("A-Za-z", "N-ZA-Mn-za-m");
7
7
  end
8
8
  end
9
9
  plugin = RotPlugin.new
10
- plugin.map 'rot13 :string'
10
+ plugin.map 'rot13 *string'
@@ -21,35 +21,48 @@ class RoulettePlugin < Plugin
21
21
  end
22
22
 
23
23
  playerdata = nil
24
- if @registry.has_key?(m.sourcenick)
25
- playerdata = @registry[m.sourcenick]
24
+ if @registry.has_key?("player " + m.sourcenick)
25
+ playerdata = @registry["player " + m.sourcenick]
26
26
  else
27
27
  playerdata = RouletteHistory.new(0,0,0,0,0)
28
28
  end
29
-
29
+
30
+ totals = nil
31
+ if @registry.has_key?("totals")
32
+ totals = @registry["totals"]
33
+ else
34
+ totals = RouletteHistory.new(0,0,0,0,0)
35
+ end
36
+
30
37
  unless @players.include?(m.sourcenick)
31
38
  @players << m.sourcenick
32
39
  playerdata.games += 1
33
40
  end
34
41
  playerdata.shots += 1
42
+ totals.shots += 1
35
43
 
36
44
  shot = @chambers.pop
37
45
  if shot
38
46
  m.reply "#{m.sourcenick}: chamber #{6 - @chambers.length} of 6 => *BANG*"
39
47
  playerdata.deaths += 1
48
+ totals.deaths += 1
40
49
  @players.each {|plyr|
41
50
  next if plyr == m.sourcenick
42
- pdata = @registry[plyr]
51
+ pdata = @registry["player " + plyr]
43
52
  next if pdata == nil
44
53
  pdata.wins += 1
45
- @registry[plyr] = pdata
54
+ totals.wins += 1
55
+ @registry["player " + plyr] = pdata
46
56
  }
57
+ @players = Array.new
47
58
  else
48
59
  m.reply "#{m.sourcenick}: chamber #{6 - @chambers.length} of 6 => +click+"
49
60
  playerdata.misses += 1
61
+ totals.misses += 1
50
62
  end
51
63
 
52
- @registry[m.sourcenick] = playerdata
64
+ @registry["player " + m.sourcenick] = playerdata
65
+ @registry["totals"] = totals
53
66
 
54
67
  if shot || @chambers.empty?
55
68
  reload(m)
@@ -60,12 +73,24 @@ class RoulettePlugin < Plugin
60
73
  reset_chambers
61
74
  # all players win on a reload
62
75
  # (allows you to play 3-shot matches etc)
76
+ totals = nil
77
+ if @registry.has_key?("totals")
78
+ totals = @registry["totals"]
79
+ else
80
+ totals = RouletteHistory.new(0,0,0,0,0)
81
+ end
82
+
63
83
  @players.each {|plyr|
64
- pdata = @registry[plyr]
84
+ pdata = @registry["player " + plyr]
65
85
  next if pdata == nil
66
86
  pdata.wins += 1
67
- @registry[plyr] = pdata
87
+ totals.wins += 1
88
+ @registry["player " + plyr] = pdata
68
89
  }
90
+
91
+ totals.games += 1
92
+ @registry["totals"] = totals
93
+
69
94
  @players = Array.new
70
95
  end
71
96
  def reset_chambers
@@ -74,7 +99,7 @@ class RoulettePlugin < Plugin
74
99
  end
75
100
  def playerstats(m, params)
76
101
  player = params[:player]
77
- pstats = @registry[player]
102
+ pstats = @registry["player " + player]
78
103
  if pstats.nil?
79
104
  m.reply "#{player} hasn't played enough games yet"
80
105
  else
@@ -82,10 +107,17 @@ class RoulettePlugin < Plugin
82
107
  end
83
108
  end
84
109
  def stats(m, params)
110
+ if @registry.has_key?("totals")
111
+ totals = @registry["totals"]
112
+ total_games = totals.games
113
+ total_shots = totals.shots
114
+ else
115
+ total_games = 0
116
+ total_shots = 0
117
+ end
118
+
85
119
  total_players = 0
86
- total_games = 0
87
- total_shots = 0
88
-
120
+
89
121
  died_most = [nil,0]
90
122
  won_most = [nil,0]
91
123
  h_win_percent = [nil,0]
@@ -93,9 +125,11 @@ class RoulettePlugin < Plugin
93
125
  h_luck_percent = [nil,0]
94
126
  l_luck_percent = [nil,0]
95
127
  @registry.each {|k,v|
128
+ match = /player (.+)/.match(k)
129
+ next unless match
130
+ k = match[1]
131
+
96
132
  total_players += 1
97
- total_games += v.deaths
98
- total_shots += v.shots
99
133
 
100
134
  win_rate = v.wins.to_f / v.games * 100
101
135
  if h_win_percent[0].nil? || win_rate > h_win_percent[1] && v.games > 2
@@ -133,7 +167,7 @@ class RoulettePlugin < Plugin
133
167
  end
134
168
  }
135
169
  if total_games < 1
136
- m.reply "roulette stats: no games played yet"
170
+ m.reply "roulette stats: no games completed yet"
137
171
  else
138
172
  m.reply "roulette stats: #{total_games} games completed, #{total_shots} shots fired at #{total_players} players. Luckiest: #{h_luck_percent[0].join(',')} (#{sprintf '%.1f', h_luck_percent[1]}% clicks). Unluckiest: #{l_luck_percent[0].join(',')} (#{sprintf '%.1f', l_luck_percent[1]}% clicks). Highest survival rate: #{h_win_percent[0].join(',')} (#{sprintf '%.1f', h_win_percent[1]}%). Lowest survival rate: #{l_win_percent[0].join(',')} (#{sprintf '%.1f', l_win_percent[1]}%). Most wins: #{won_most[0].join(',')} (#{won_most[1]}). Most deaths: #{died_most[0].join(',')} (#{died_most[1]})."
139
173
  end