]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/points.rb
34af9b5090d1ad4fd7bb076e7e0c8a3aced1fcfe
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / points.rb
1 class PointsPlugin < 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     oldpoints = @bot.path 'points.rbot'
18     if File.exist? oldpoints
19       log "importing old points data"
20       IO.foreach(oldpoints) do |line|
21         if(line =~ /^(\S+)<=>([\d-]+)$/)
22           item = $1
23           points = $2.to_i
24           @registry[item] = points
25         end
26       end
27       File.delete oldpoints
28     end
29   end
30
31   def stats(m, params)
32     if (@registry.length)
33       max = @registry.values.max || "zero"
34       min = @registry.values.min || "zero"
35       best = @registry.to_hash.key(max) || "nobody"
36       worst = @registry.to_hash.key(min) || "nobody"
37       m.reply "#{@registry.length} items. Best: #{best} (#{max}); Worst: #{worst} (#{min})"
38     end
39   end
40
41   def dump(m, params)
42     if (@registry.length)
43       msg = "Points dump: "
44       msg << @registry.to_hash.sort_by { |k, v| v }.reverse.
45                        map { |k,v| "#{k}: #{v}" }.
46                        join(", ")
47       m.reply msg
48     else
49       m.reply "nobody has any points yet!"
50     end
51   end
52
53   def points(m, params)
54     thing = params[:key]
55     thing = m.sourcenick unless thing
56     thing = thing.to_s
57     points = @registry[thing]
58     if(points != 0)
59       m.reply "points for #{thing}: #{@registry[thing]}"
60     else
61       m.reply "#{thing} has zero points"
62     end
63   end
64
65   def setpoints(m, params)
66     thing = (params[:key] || m.sourcenick).to_s
67     @registry[thing] = params[:val].to_i
68     points(m, params)
69   end
70
71   def help(plugin, topic="")
72     "points module: Keeps track of internet points, infusing your pointless life with meaning. Listens to everyone's chat. <thing>++/<thing>-- => increase/decrease points for <thing>, points for <thing>? => show points for <thing>, pointstats => show best/worst, pointsdump => show everyone's points. Points are a community rating system - only in-channel messages can affect points and you cannot adjust your own."
73   end
74
75   def message(m)
76     return unless m.public? && m.message.match(/\+\+|--/)
77     arg = nil
78     op = nil
79     ac = Hash.new
80     m.message.split.each_with_index do |tok, i|
81       # ignore preceeding +/-
82       if op && arg.nil?
83         op = nil
84       end
85       tok.sub!(/[:,]$/, '') if i == 0
86       catch :me_if_you_can do
87         if m.channel.users[tok].nil?
88           if tok =~ /^(.*[^-].*)(?:--)$/
89             op, arg = '--', $1
90             next
91           elsif tok =~ /^(.*[^+].*)(?:\+\+)$/
92             op, arg = '++', $1
93             next
94           end
95         end
96
97         if (tok =~ /^--+$/) || (tok =~ /^\+\++$/)
98           op = tok.slice(0, 2)
99         else
100           arg = tok
101         end
102       end # catch
103
104       if op && arg
105         ac[arg] ||= 0
106         ac[arg] += (op == '--' ? -1 : 1) unless arg.downcase == m.sourcenick.downcase
107         op = arg = nil
108       end
109     end
110
111     ac.each do |k, v|
112       next if v == 0 or /--|\+\+/.match(k)
113       # strip invisible formatting characters like bold or color codes
114       k = k.gsub(FormattingRx, '')
115       next if k.downcase == m.sourcenick.downcase
116       @registry[k] += (v > 0 ? 1 : -1)
117       m.reply @bot.lang.get("thanks") if k == @bot.nick && v > 0
118       m.reply "#{k} now has #{@registry[k]} points!"
119     end
120   end
121 end
122
123 plugin = PointsPlugin.new
124
125 plugin.default_auth( 'edit', false )
126
127 plugin.map 'pointstats', :action => 'stats'
128 plugin.map 'points :key', :defaults => {:key => false}
129 plugin.map 'setpoints :key :val', :defaults => {:key => false}, :requirements => {:val => /^-?\d+$/}, :auth_path => 'edit::set!'
130 plugin.map 'points for :key'
131 plugin.map 'pointsdump', :action => 'dump'