mod_spox 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +38 -0
- data/INSTALL +5 -2
- data/bin/mod_spox +7 -3
- data/data/mod_spox/extras/Confess.rb +4 -4
- data/data/mod_spox/extras/Karma.rb +2 -2
- data/data/mod_spox/extras/Logger.rb +167 -0
- data/data/mod_spox/extras/Quotes.rb +2 -2
- data/data/mod_spox/extras/Roulette.rb +34 -16
- data/data/mod_spox/extras/Topten.rb +105 -0
- data/data/mod_spox/plugins/Authenticator.rb +2 -2
- data/data/mod_spox/plugins/Banner.rb +10 -10
- data/data/mod_spox/plugins/Initializer.rb +1 -1
- data/data/mod_spox/plugins/Triggers.rb +3 -3
- data/lib/mod_spox/Bot.rb +6 -5
- data/lib/mod_spox/BotConfig.rb +1 -1
- data/lib/mod_spox/ConfigurationWizard.rb +18 -17
- data/lib/mod_spox/Database.rb +9 -0
- data/lib/mod_spox/Helpers.rb +49 -0
- data/lib/mod_spox/Loader.rb +11 -0
- data/lib/mod_spox/PluginManager.rb +1 -0
- data/lib/mod_spox/Pool.rb +23 -107
- data/lib/mod_spox/Socket.rb +23 -37
- data/lib/mod_spox/Timer.rb +3 -3
- data/lib/mod_spox/handlers/Created.rb +1 -1
- data/lib/mod_spox/handlers/Handler.rb +1 -13
- data/lib/mod_spox/handlers/Invite.rb +1 -1
- data/lib/mod_spox/handlers/LuserOp.rb +1 -1
- data/lib/mod_spox/handlers/LuserUnknown.rb +1 -1
- data/lib/mod_spox/messages/internal/TimerAdd.rb +8 -0
- data/lib/mod_spox/messages/internal/TimerRemove.rb +8 -0
- data/lib/mod_spox/messages/internal/TimerResponse.rb +8 -1
- data/lib/mod_spox/models/Auth.rb +4 -4
- data/lib/mod_spox/models/Channel.rb +11 -0
- data/lib/mod_spox/models/Nick.rb +22 -11
- data/lib/mod_spox/models/Setting.rb +2 -2
- data/lib/mod_spox/models/Signature.rb +11 -2
- metadata +4 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
+
0.0.4 Release (Alpha status)
|
2
|
+
* Signatures now encoded when stored
|
3
|
+
* SQLite lockup fixed on new version of sequel
|
4
|
+
* Timer messages now have IDs
|
5
|
+
* Removed blocks from sequel usage to remove dependency on ParseTree
|
6
|
+
* This was done to enable jruby support
|
7
|
+
* mod_spox will currently load into jruby but is not currently working
|
8
|
+
* Added experimental memcache support (very buggy)
|
9
|
+
* New plugins:
|
10
|
+
* ChatLogger - Logs chatting to database. Provides a seen and lastspoke trigger
|
11
|
+
* Topten - Provides stats on user's chatting
|
12
|
+
* The bot as well as plugins have all been updated to work with Sequel 2.0 (removed deprecated)
|
13
|
+
* Processing pool has been reworked.
|
14
|
+
* Currently testing to see how memory is consumed.
|
15
|
+
* New version will play nicely with jruby thread pools
|
16
|
+
* Various small fixes and updates
|
17
|
+
|
18
|
+
0.0.3 Release (Alpha status)
|
19
|
+
* New features available from the following new plugins:
|
20
|
+
* AOLSpeak
|
21
|
+
* AutoKick
|
22
|
+
* AutoRejoin
|
23
|
+
* Confess
|
24
|
+
* EightBall
|
25
|
+
* LolSpeak
|
26
|
+
* PhpCli
|
27
|
+
* PhpFuncLookup
|
28
|
+
* Quotes
|
29
|
+
* Talk
|
30
|
+
* Translate
|
31
|
+
* Weather
|
32
|
+
* Help
|
33
|
+
* Added private/public/both specification for signatures
|
34
|
+
* Added smart thread creation/deletion for Pool
|
35
|
+
* Modified Rakefile to build gem without need for unused libraries
|
36
|
+
* Added support for action privmsgs
|
37
|
+
* Various fixes of small bugs
|
38
|
+
|
1
39
|
0.0.2 Release (Alpha status)
|
2
40
|
* New features available from the following new plugins:
|
3
41
|
* Karma
|
data/INSTALL
CHANGED
data/bin/mod_spox
CHANGED
@@ -15,11 +15,12 @@
|
|
15
15
|
begin
|
16
16
|
require 'fastthread'
|
17
17
|
rescue Object => boom
|
18
|
-
|
18
|
+
# ignore if not found #
|
19
19
|
end
|
20
20
|
|
21
|
-
$BOTVERSION='0.0.
|
21
|
+
$BOTVERSION='0.0.4'
|
22
22
|
$VERBOSITY = 0
|
23
|
+
$MOD_SPOX_PATH = nil
|
23
24
|
|
24
25
|
begin
|
25
26
|
require 'mod_spox/Loader'
|
@@ -33,7 +34,8 @@ opts = GetoptLong.new(
|
|
33
34
|
['--config', '-c', GetoptLong::NO_ARGUMENT],
|
34
35
|
['--debug', '-d', GetoptLong::OPTIONAL_ARGUMENT],
|
35
36
|
['--version', '-v', GetoptLong::NO_ARGUMENT],
|
36
|
-
['--help', '-h', GetoptLong::NO_ARGUMENT]
|
37
|
+
['--help', '-h', GetoptLong::NO_ARGUMENT],
|
38
|
+
['--path', '-p', GetoptLong::REQUIRED_ARGUMENT]
|
37
39
|
)
|
38
40
|
verbose = 0
|
39
41
|
opts.each do |opt, arg|
|
@@ -58,6 +60,8 @@ opts.each do |opt, arg|
|
|
58
60
|
wizard = ConfigurationWizard.new
|
59
61
|
wizard.run
|
60
62
|
exit
|
63
|
+
when '--path'
|
64
|
+
$MOD_SPOX_PATH = arg
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
@@ -46,7 +46,7 @@ class Confess < ModSpox::Plugin
|
|
46
46
|
reg = true
|
47
47
|
end
|
48
48
|
else
|
49
|
-
ids = Confession.map(:id)
|
49
|
+
ids = Confession.select(:id).map(:id)
|
50
50
|
c = Confession[ids[rand(ids.size - 1)].to_i]
|
51
51
|
end
|
52
52
|
if(c)
|
@@ -74,11 +74,11 @@ class Confess < ModSpox::Plugin
|
|
74
74
|
end
|
75
75
|
if(c)
|
76
76
|
if(params[:score] == '++')
|
77
|
-
c.
|
77
|
+
c.update_with_params(:positive => c.positive.to_i + 1)
|
78
78
|
else
|
79
|
-
c.
|
79
|
+
c.update_with_params(:negative => c.negative.to_i + 1)
|
80
80
|
end
|
81
|
-
c.
|
81
|
+
c.update_with_params(:score => ((c.positive.to_f) / (c.positive.to_f + c.negative.to_f)) * 100.0)
|
82
82
|
else
|
83
83
|
reply message.replyto, "\2Error:\2 Failed to find confession to score"
|
84
84
|
end
|
@@ -21,7 +21,7 @@ class Karma < ModSpox::Plugin
|
|
21
21
|
thing = thing[1..-2] if thing[0..0] == '(' && thing[-1..1] == ')'
|
22
22
|
adj = adj == '++' ? +1 : -1
|
23
23
|
karma = Datatype::Karma.find_or_create(:thing => thing, :channel_id => message.target.pk)
|
24
|
-
karma.
|
24
|
+
karma.update_with_params(:score => karma.score + adj)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -42,7 +42,7 @@ class Karma < ModSpox::Plugin
|
|
42
42
|
return unless message.is_public?
|
43
43
|
karma = Datatype::Karma.filter(:thing => params[:thing], :channel_id => message.target.pk).first
|
44
44
|
if(karma)
|
45
|
-
karma.
|
45
|
+
karma.update_with_params(:score => 0)
|
46
46
|
@pipeline << Privmsg.new(message.replyto, "Karma for \2#{karma.thing}\2 has been reset")
|
47
47
|
else
|
48
48
|
@pipeline << Privmsg.new(message.replyto, "\2Error:\2 #{params[:thing]} has no karma")
|
@@ -0,0 +1,167 @@
|
|
1
|
+
class ChatLogger < ModSpox::Plugin
|
2
|
+
|
3
|
+
# This plugin creates a log of conversations the bot sees. It
|
4
|
+
# is important to note that the order in which messages are
|
5
|
+
# added to the database may not be in order. Due to the
|
6
|
+
# async behavior of the pipeline, this plugin may (and most
|
7
|
+
# likely will) receive messages out of order. This will be most
|
8
|
+
# notable with triggers received and responses from the bot
|
9
|
+
|
10
|
+
include Models
|
11
|
+
|
12
|
+
def initialize(pipeline)
|
13
|
+
super
|
14
|
+
PublicLog.create_table unless PublicLog.table_exists?
|
15
|
+
PrivateLog.create_table unless PrivateLog.table_exists?
|
16
|
+
@pipeline.hook(self, :log_privmsg, :Incoming_Privmsg)
|
17
|
+
@pipeline.hook(self, :log_join, :Incoming_Join)
|
18
|
+
@pipeline.hook(self, :log_part, :Incoming_Part)
|
19
|
+
@pipeline.hook(self, :log_quit, :Incoming_Quit)
|
20
|
+
@pipeline.hook(self, :log_kick, :Incoming_Kick)
|
21
|
+
@pipeline.hook(self, :log_mode, :Incoming_Mode)
|
22
|
+
@pipeline.hook(self, :log_privmsg, :Incoming_Notice)
|
23
|
+
@pipeline.hook(self, :log_outpriv, :Outgoing_Privmsg)
|
24
|
+
@pipeline.hook(self, :log_outpriv, :Outgoing_Notice)
|
25
|
+
Signature.find_or_create(:signature => 'seen (\S+)', :plugin => name, :method => 'seen', :description => 'Report last sighting of nick').params = [:nick]
|
26
|
+
Signature.find_or_create(:signature => 'lastspoke (\S+)', :plugin => name, :method => 'spoke', :description => 'Report last time nick spoke').params = [:nick]
|
27
|
+
end
|
28
|
+
|
29
|
+
def log_outpriv(message)
|
30
|
+
type = message.is_a?(Messages::Outgoing::Privmsg) ? 'privmsg' : 'notice'
|
31
|
+
type = 'action' if message.is_action?
|
32
|
+
target = message.target.is_a?(Sequel::Model) ? message.target : Helpers.find_model(message.target)
|
33
|
+
if(target.is_a?(Models::Channel))
|
34
|
+
PublicLog.new(:message => message.message, :type => type, :sender => me.pk,
|
35
|
+
:channel => target.pk, :received => Time.now).save
|
36
|
+
else
|
37
|
+
PrivateLog.new(:message => message.message, :type => type, :sender => me.pk,
|
38
|
+
:receiver => target.pk, :received => Time.now).save
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def log_privmsg(message)
|
43
|
+
type = message.is_a?(Messages::Incoming::Privmsg) ? 'privmsg' : 'notice'
|
44
|
+
type = 'action' if message.is_action?
|
45
|
+
if(message.is_public?)
|
46
|
+
PublicLog.new(:message => message.message, :type => type, :sender => message.source.pk,
|
47
|
+
:channel => message.target.pk, :received => message.time).save
|
48
|
+
else
|
49
|
+
PrivateLog.new(:message => message.message, :type => type, :sender => message.source.pk,
|
50
|
+
:receiver => message.target.pk, :received => message.time).save
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def log_join(message)
|
55
|
+
PublicLog.new(:type => 'join', :sender => message.nick.pk, :channel => message.channel.pk, :received => message.time).save
|
56
|
+
end
|
57
|
+
|
58
|
+
def log_part(message)
|
59
|
+
PublicLog.new(:message => message.reason, :type => 'part', :sender => message.nick.pk,
|
60
|
+
:channel => message.channel.pk, :received => message.time).save
|
61
|
+
end
|
62
|
+
|
63
|
+
def log_quit(message)
|
64
|
+
PublicLog.new(:message => message.message, :type => 'quit', :sender => message.nick.pk, :received => message.time).save
|
65
|
+
end
|
66
|
+
|
67
|
+
def log_kick(message)
|
68
|
+
PublicLog.new(:message => "#{message.kickee.pk}|#{message.reason}", :type => 'kick', :sender => message.kicker.pk,
|
69
|
+
:channel => message.channel.pk, :received => message.time).save
|
70
|
+
end
|
71
|
+
|
72
|
+
# TODO: Fix this
|
73
|
+
def log_mode(message)
|
74
|
+
# if(message.for_channel?)
|
75
|
+
# PublicLog.new(:message => message.mode, :type => 'mode', :sender => message.source.pk,
|
76
|
+
# :channel => message.channel.pk, :received => message.time).save
|
77
|
+
# else
|
78
|
+
# PrivateLog.new(:message => message.mode, :type => 'mode', :sender => message.source.pk,
|
79
|
+
# :receiver => message.target.pk, :received => message.time).save
|
80
|
+
# end
|
81
|
+
end
|
82
|
+
|
83
|
+
def seen(m, p)
|
84
|
+
nick = Helpers.find_model(p[:nick], false)
|
85
|
+
if(nick.is_a?(Models::Nick))
|
86
|
+
record = PublicLog.filter(:sender => nick.pk).order(:received).last
|
87
|
+
record_p = PrivateLog.filter(:sender => nick.pk).order(:received).last
|
88
|
+
record = record_p if !record || (record_p && record && record_p.received > record.received)
|
89
|
+
if(record)
|
90
|
+
if(record.is_a?(PublicLog))
|
91
|
+
case record.values[:type]
|
92
|
+
when 'join'
|
93
|
+
message = "joining #{Channel[record.channel].name}"
|
94
|
+
when 'part'
|
95
|
+
message = "parting #{Channel[record.channel].name} with the message: #{record.message}"
|
96
|
+
when 'privmsg'
|
97
|
+
message = "in #{Channel[record.channel].name} saying: #{record.message}"
|
98
|
+
when 'action'
|
99
|
+
message = "in #{Channel[record.channel].name} saying: * #{p[:nick]} #{record.message}"
|
100
|
+
when 'notice'
|
101
|
+
message = "in #{Channel[record.channel].name} saying: #{record.message}"
|
102
|
+
when 'kick'
|
103
|
+
if(record.message =~ /^([0-9]+)\|/)
|
104
|
+
kickee = Nick[$1.to_i]
|
105
|
+
reason = $2
|
106
|
+
message = "kicking #{kickee.nick} from #{Channel[record.channel].name} (#{record.message})"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
else
|
110
|
+
message = "saying to me: #{record.message}"
|
111
|
+
end
|
112
|
+
reply m.replyto, "I last saw #{p[:nick]} on #{record.received} #{message}"
|
113
|
+
else
|
114
|
+
reply m.replyto, "\2Error:\2 Failed to find record of #{p[:nick]}"
|
115
|
+
end
|
116
|
+
else
|
117
|
+
reply m.replyto, "\2Error:\2 Failed to find record of #{p[:nick]}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def spoke(m, p)
|
122
|
+
nick = Helpers.find_model(p[:nick], false)
|
123
|
+
if(nick.is_a?(Models::Nick))
|
124
|
+
record = PublicLog.filter(:sender => nick.pk).filter("type in ('privmsg', 'action')").order(:received).last
|
125
|
+
record_p = PrivateLog.filter(:sender => nick.pk).order(:received).last
|
126
|
+
record = record_p if !record || (record_p && record && record_p.received > record.received)
|
127
|
+
if(record)
|
128
|
+
if(record.is_a?(PublicLog))
|
129
|
+
reply m.replyto, "I last saw #{p[:nick]} on #{record.received} saying: #{record.values[:type] == 'action' ? "* #{p[:nick]} #{record.message}" : record.message}"
|
130
|
+
else
|
131
|
+
reply m.replyto, "I last saw #{p[:nick]} on #{record.received} saying to me: #{record.message}"
|
132
|
+
end
|
133
|
+
else
|
134
|
+
reply m.replyto, "\2Error:\2 Failed to find record of #{p[:nick]}"
|
135
|
+
end
|
136
|
+
else
|
137
|
+
reply m.replyto, "\2Error:\2 Failed to find record of #{p[:nick]}"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class PrivateLog < Sequel::Model
|
142
|
+
set_schema do
|
143
|
+
primary_key :id
|
144
|
+
text :message, :null => false
|
145
|
+
text :type, :null => false, :default => 'privmsg'
|
146
|
+
boolean :action, :null => false, :default => false
|
147
|
+
timestamp :received, :null => false
|
148
|
+
foreign_key :sender, :table => :nicks
|
149
|
+
foreign_key :receiver, :table => :nicks
|
150
|
+
index :message, :type => :full_text
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class PublicLog < Sequel::Model
|
155
|
+
set_schema do
|
156
|
+
primary_key :id
|
157
|
+
text :message
|
158
|
+
text :type, :null => false, :default => 'privmsg'
|
159
|
+
boolean :action, :null => false, :default => false
|
160
|
+
timestamp :received, :null => false
|
161
|
+
foreign_key :sender, :table => :nicks
|
162
|
+
foreign_key :channel, :table => :channels
|
163
|
+
index :message, :type => :full_text
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -27,11 +27,11 @@ class Quotes < ModSpox::Plugin
|
|
27
27
|
reg = true
|
28
28
|
end
|
29
29
|
else
|
30
|
-
ids = Quote.map(:id)
|
30
|
+
ids = Quote.select(:id).map(:id)
|
31
31
|
quote = Quote[ids[rand(ids.size - 1)].to_i]
|
32
32
|
end
|
33
33
|
if(quote)
|
34
|
-
reply message.replyto, "\2[\2#{quote.pk}\2|\2#{quote.added.year}/#{quote.added.month}/#{quote.added.day}\2]:\2 #{reg ? quote.quote.gsub(/(#{params[:term]})/, "\2\\1\2") : quote.quote}"
|
34
|
+
reply message.replyto, "\2[\2#{quote.pk}\2|\2#{quote.added.year}/#{sprintf('%02d', quote.added.month)}/#{sprintf('%02d', quote.added.day)}\2]:\2 #{reg ? quote.quote.gsub(/(#{params[:term]})/, "\2\\1\2") : quote.quote}"
|
35
35
|
else
|
36
36
|
reply message.replyto, "\2Error:\2 Failed to find quote"
|
37
37
|
end
|
@@ -4,15 +4,33 @@ class Roulette < ModSpox::Plugin
|
|
4
4
|
|
5
5
|
def initialize(pipeline)
|
6
6
|
super(pipeline)
|
7
|
-
Signature.find_or_create(:signature => 'roulette', :plugin => name, :method => 'roulette')
|
8
|
-
Signature.find_or_create(:signature => 'suicide', :plugin => name, :method => 'suicide')
|
9
|
-
Signature.find_or_create(:signature => 'shoot (\S+)', :plugin => name, :method => 'shoot').params = [:nick]
|
10
|
-
Signature.find_or_create(:signature => 'roulette topten', :plugin => name, :method => 'topten')
|
11
|
-
Signature.find_or_create(:signature => 'roulette stats ?(\S+)?', :plugin => name, :method => 'stats').params = [:nick]
|
7
|
+
Signature.find_or_create(:signature => 'roulette', :plugin => name, :method => 'roulette', :requirement => 'public')
|
8
|
+
Signature.find_or_create(:signature => 'suicide', :plugin => name, :method => 'suicide', :requirement => 'public')
|
9
|
+
Signature.find_or_create(:signature => 'shoot (\S+)', :plugin => name, :method => 'shoot', :requirement => 'public').params = [:nick]
|
10
|
+
Signature.find_or_create(:signature => 'roulette topten', :plugin => name, :method => 'topten', :requirement => 'public')
|
11
|
+
Signature.find_or_create(:signature => 'roulette stats ?(\S+)?', :plugin => name, :method => 'stats', :requirement => 'public').params = [:nick]
|
12
|
+
Signature.find_or_create(:signature => 'roulette chambers', :plugin => name, :method => 'chambers', :requirement => 'public')
|
12
13
|
Game.create_table unless Game.table_exists?
|
13
14
|
Info.create_table unless Info.table_exists?
|
14
15
|
@banner = nil
|
15
|
-
@pipeline.hook(
|
16
|
+
@pipeline.hook(self, :get_banner, :Internal_PluginResponse)
|
17
|
+
end
|
18
|
+
|
19
|
+
# message:: ModSpox::Messages::Incoming::Privmsg
|
20
|
+
# Display chamber statistics
|
21
|
+
def chambers(m, p)
|
22
|
+
total = Game.all.size
|
23
|
+
result = Game.group(:chamber).select(:chamber, :COUNT[:chamber] => :total).reverse_order(:total)
|
24
|
+
if(result)
|
25
|
+
output = []
|
26
|
+
result.each do |res|
|
27
|
+
percent = sprintf('%.2d', ((res[:total].to_f / total.to_f) * 100.0))
|
28
|
+
output << "chamber #{res.chamber}: #{percent}% (#{res[:total]})"
|
29
|
+
end
|
30
|
+
reply m.replyto, "\2Chamber stats:\2 #{output.join(', ')}"
|
31
|
+
else
|
32
|
+
reply m.replyto, "\2Error:\2 No games found"
|
33
|
+
end
|
16
34
|
end
|
17
35
|
|
18
36
|
# message:: ModSpox::Messages::Internal::PluginResponse
|
@@ -57,7 +75,7 @@ class Roulette < ModSpox::Plugin
|
|
57
75
|
def topten(message, params)
|
58
76
|
return unless message.is_public?
|
59
77
|
ds = Database.db[:infos].left_outer_join(:games, :id => :game_id)
|
60
|
-
ds.select!(:nick_id, :COUNT[:win] => :wins).where!(:channel_id => message.target.pk, :win => true).group!(:nick_id).
|
78
|
+
ds.select!(:nick_id, :COUNT[:win] => :wins).where!(:channel_id => message.target.pk, :win => true).group!(:nick_id).reverse_order!(:wins).limit!(10)
|
61
79
|
Logger.log(ds.sql)
|
62
80
|
ids = ds.map(:nick_id)
|
63
81
|
top = []
|
@@ -109,7 +127,7 @@ class Roulette < ModSpox::Plugin
|
|
109
127
|
# channel:: ModSpox::Models::Channel
|
110
128
|
# Return number of games nick has won
|
111
129
|
def games_won(nick, channel)
|
112
|
-
Info.left_outer_join(:games, :id => :game_id).filter
|
130
|
+
Info.left_outer_join(:games, :id => :game_id).filter('nick_id = ?', nick.pk).filter('channel_id = ?', channel.pk).filter('win = ?', true).size
|
113
131
|
end
|
114
132
|
|
115
133
|
# nick:: ModSpox::Models::Nick
|
@@ -123,14 +141,14 @@ class Roulette < ModSpox::Plugin
|
|
123
141
|
# channel:: ModSpox::Models::Channel
|
124
142
|
# Return number of games nick has played
|
125
143
|
def games_total(nick, channel)
|
126
|
-
Info.left_outer_join(:games, :id => :game_id).filter
|
144
|
+
Info.left_outer_join(:games, :id => :game_id).filter('nick_id = ?', nick.pk).filter('channel_id = ?', channel.pk).exclude(:game_id => game(channel).pk).size
|
127
145
|
end
|
128
146
|
|
129
147
|
# nick:: ModSpox::Models::Nick
|
130
148
|
# channel:: ModSpox::Models::Channel
|
131
149
|
# Return number of shots nick has taken
|
132
150
|
def total_shots(nick, channel)
|
133
|
-
v = Info.left_outer_join(:games, :id => :game_id).filter
|
151
|
+
v = Info.left_outer_join(:games, :id => :game_id).filter('nick_id = ?', nick.pk).filter('channel_id = ?', channel.pk).exclude(:game_id => game(channel).pk).sum(:infos__shots)
|
134
152
|
v = 0 unless v
|
135
153
|
return v
|
136
154
|
end
|
@@ -165,8 +183,8 @@ class Roulette < ModSpox::Plugin
|
|
165
183
|
def kill_nick(nick, channel)
|
166
184
|
unless(@banner.nil?)
|
167
185
|
begin
|
168
|
-
@banner.ban(nick, channel, '*BANG*', true, false)
|
169
|
-
rescue NotOperator => boom
|
186
|
+
@banner.ban(nick, channel, 30, '*BANG*', true, false)
|
187
|
+
rescue Banner::NotOperator => boom
|
170
188
|
reply(channel, "#{nick.nick}: *BANG*")
|
171
189
|
rescue Object => boom
|
172
190
|
Logger.log("Error: Roulette ban generated an unexpected error: #{boom}")
|
@@ -180,7 +198,7 @@ class Roulette < ModSpox::Plugin
|
|
180
198
|
# Return current game
|
181
199
|
def game(channel)
|
182
200
|
@pipeline << Messages::Internal::PluginRequest.new(self, 'Banner') if @banner.nil?
|
183
|
-
game = Game.filter
|
201
|
+
game = Game.filter('shots > ?', 0).filter('channel_id = ?', channel.pk).first
|
184
202
|
unless(game)
|
185
203
|
chamber = rand(5) + 1
|
186
204
|
game = Game.new(:chamber => chamber, :shots => chamber, :channel_id => channel.pk)
|
@@ -195,8 +213,8 @@ class Roulette < ModSpox::Plugin
|
|
195
213
|
def shot(nick, channel)
|
196
214
|
cur_game = game(channel)
|
197
215
|
info = Info.find_or_create(:game_id => cur_game.pk, :nick_id => nick.pk)
|
198
|
-
info.
|
199
|
-
cur_game.
|
216
|
+
info.update_with_params(:shots => info.shots + 1)
|
217
|
+
cur_game.update_with_params(:shots => cur_game.shots - 1)
|
200
218
|
raise Bullet.new(cur_game) if cur_game.shots < 1
|
201
219
|
end
|
202
220
|
|
@@ -205,7 +223,7 @@ class Roulette < ModSpox::Plugin
|
|
205
223
|
# Return number of games nick has won
|
206
224
|
def game_over(nick, game)
|
207
225
|
Info.filter(:game_id => game.pk).each do |info|
|
208
|
-
info.
|
226
|
+
info.update_with_params(:win => true) unless info.nick_id == nick.pk
|
209
227
|
end
|
210
228
|
end
|
211
229
|
|
@@ -0,0 +1,105 @@
|
|
1
|
+
class Topten < ModSpox::Plugin
|
2
|
+
|
3
|
+
include Models
|
4
|
+
|
5
|
+
def initialize(pipeline)
|
6
|
+
super
|
7
|
+
ChatStat.create_table unless ChatStat.table_exists?
|
8
|
+
Signature.find_or_create(:signature => 'topten', :plugin => name, :method => 'topten',
|
9
|
+
:requirement => 'public', :description => 'Show topten users since midnight')
|
10
|
+
Signature.find_or_create(:signature => 'topten ([0-9]{4}\/[0-9]{2}\/[0-9]{2})', :plugin => name, :method => 'archive',
|
11
|
+
:description => 'Show topten from given date', :requirement => 'public').params = [:date]
|
12
|
+
Signature.find_or_create(:signature => 'stats ?(\S+)?', :plugin => name, :method => 'stats', :description => 'Show stats on nick',
|
13
|
+
:requirement => 'public').params = [:nick]
|
14
|
+
Signature.find_or_create(:signature => 'stats lifetime? (\S+)?', :plugin => name, :method => 'life_stats',
|
15
|
+
:description => 'Show stat totals for given nick', :requirement => 'public').params = [:nick]
|
16
|
+
@pipeline.hook(self, :log_stats, :Incoming_Privmsg)
|
17
|
+
end
|
18
|
+
|
19
|
+
def topten(m, p)
|
20
|
+
stats = ChatStat.filter(:channel_id => m.target.pk, :daykey => construct_daykey).reverse_order(:bytes).limit(10)
|
21
|
+
if(stats.size > 0)
|
22
|
+
users = []
|
23
|
+
stats.each do |stat|
|
24
|
+
bytes = (stat.bytes > 1023) ? "#{sprintf('%.2f', (stat.bytes / 1024.0))}kb" : "#{stat.bytes}b"
|
25
|
+
users << "#{Nick[stat.nick_id].nick}: #{bytes}"
|
26
|
+
end
|
27
|
+
reply m.replyto, "\2Topten:\2 #{users.join(', ')}"
|
28
|
+
else
|
29
|
+
reply m.replyto, "\2Error:\2 No stats found for this channel."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def archive(m, p)
|
34
|
+
stats = ChatStat.filter(:channel_id => m.target.pk, :daykey => p[:date]).reverse_order(:bytes).limit(10)
|
35
|
+
if(stats.size > 0)
|
36
|
+
users = []
|
37
|
+
stats.each do |stat|
|
38
|
+
bytes = (stat.bytes > 1023) ? "#{sprintf('%.2f', (stat.bytes / 1024.0))}kb" : "#{stat.bytes}b"
|
39
|
+
users << "#{Nick[stat.nick_id].nick}: #{bytes}"
|
40
|
+
end
|
41
|
+
reply m.replyto, "\2Topten:\2 #{users.join(', ')}"
|
42
|
+
else
|
43
|
+
reply m.replyto, "\2Error:\2 No stats found for date given."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def stats(m, p)
|
48
|
+
nick = p[:nick] ? Nick.locate(p[:nick], false) : m.source
|
49
|
+
if(nick.is_a?(Nick))
|
50
|
+
stat = ChatStat.filter(:nick_id => nick.pk, :channel_id => m.target.pk, :daykey => construct_daykey).first
|
51
|
+
if(stat)
|
52
|
+
bytes = (stat.bytes > 1023) ? "#{sprintf('%.2f', (stat.bytes / 1024.0))}kb" : "#{stat.bytes}b"
|
53
|
+
reply m.replyto, "#{nick.nick}: #{bytes} logged. #{stat.words} words spoken. #{stat.questions} questions asked."
|
54
|
+
else
|
55
|
+
reply m.replyto, "\2Error:\2 #{nick.nick} has no stats recorded for today"
|
56
|
+
end
|
57
|
+
else
|
58
|
+
reply m.replyto, "\2Error:\2 Failed to find record of nick: #{p[:nick]}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def life_stats(m, p)
|
63
|
+
nick = p[:nick] ? Nick.locate(p[:nick], false) : m.source
|
64
|
+
if(nick)
|
65
|
+
result = ChatStat.group(:nick_id).select(:SUM[:bytes] => :tbytes, :SUM[:words] => :twords, :SUM[:questions] => :tquestions).filter(:nick_id => nick.pk).first
|
66
|
+
bytes = (result.tbytes > 1023) ? "#{sprintf('%.2f', (result.tbytes / 1024.0))}kb" : "#{result.tbytes}b"
|
67
|
+
reply m.replyto, "#{nick.nick} (total): #{bytes} logged, #{result.twords} words spoken and #{result.tquestions} questions asked"
|
68
|
+
else
|
69
|
+
reply m.replyto, "\2Error:\2 Failed to find #{p[:nick]}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def log_stats(m)
|
74
|
+
return unless m.is_public?
|
75
|
+
key = construct_daykey
|
76
|
+
stat = ChatStat.find_or_create(:nick_id => m.source.pk, :channel_id => m.target.pk, :daykey => key)
|
77
|
+
words = m.message.scan(/([^ ]+ |[^ ]$)/).size
|
78
|
+
bytes = m.message.gsub(/[^a-zA-Z0-9`\~\!@#\$%\^&\*\(\)_\+\[\]\}\{;:'"\/\?\.>,<\\|\-=]/, '').length
|
79
|
+
questions = m.message.scan(/.+?(\? |\?$)/).size
|
80
|
+
stat.words += words
|
81
|
+
stat.bytes += bytes
|
82
|
+
stat.questions += questions
|
83
|
+
stat.save
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def construct_daykey
|
89
|
+
t = Time.now
|
90
|
+
return "#{t.year}/#{sprintf('%02d', t.month)}/#{sprintf('%02d', t.day)}"
|
91
|
+
end
|
92
|
+
|
93
|
+
class ChatStat < Sequel::Model
|
94
|
+
set_schema do
|
95
|
+
primary_key :id
|
96
|
+
integer :words, :null => false, :default => 0
|
97
|
+
integer :bytes, :null => false, :default => 0
|
98
|
+
integer :questions, :null => false, :default => 0
|
99
|
+
varchar :daykey, :null => false
|
100
|
+
foreign_key :channel_id, :table => :channels
|
101
|
+
foreign_key :nick_id, :table => :nicks
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -129,9 +129,9 @@ class Authenticator < ModSpox::Plugin
|
|
129
129
|
def nick_ident(message, params)
|
130
130
|
nick = Models::Nick.find_or_create(:nick => params[:nick])
|
131
131
|
if(params[:ident] == 'true')
|
132
|
-
nick.auth.
|
132
|
+
nick.auth.update_with_params(:services => true)
|
133
133
|
else
|
134
|
-
nick.auth.
|
134
|
+
nick.auth.update_with_params(:services => false)
|
135
135
|
end
|
136
136
|
@pipeline << Messages::Outgoing::Privmsg.new(message.replyto, "Nick #{params[:nick]} has been updated. Services for authentication has been set to #{params[:ident]}")
|
137
137
|
end
|
@@ -179,7 +179,7 @@ class Banner < ModSpox::Plugin
|
|
179
179
|
def ban_remove(message, params)
|
180
180
|
record = BanRecord[params[:id].to_i]
|
181
181
|
if(record)
|
182
|
-
record.
|
182
|
+
record.update_with_params(:remaining => 0)
|
183
183
|
updater
|
184
184
|
reply(message.replyto, 'Okay')
|
185
185
|
else
|
@@ -243,8 +243,8 @@ class Banner < ModSpox::Plugin
|
|
243
243
|
if(message.mode == '-b')
|
244
244
|
update = false
|
245
245
|
BanRecord.filter(:mask => message.target, :channel_id => message.channel.pk).each do |match|
|
246
|
-
match.
|
247
|
-
match.
|
246
|
+
match.update_vaules(:remaining => 0)
|
247
|
+
match.update_with_params(:removed => true)
|
248
248
|
update = true
|
249
249
|
end
|
250
250
|
updater if update
|
@@ -297,19 +297,19 @@ class Banner < ModSpox::Plugin
|
|
297
297
|
begin
|
298
298
|
time = @sleep.nil? ? 0 : (Object::Time.now - @sleep).to_i
|
299
299
|
if(time > 0)
|
300
|
-
BanRecord.filter
|
301
|
-
BanMask.filter
|
300
|
+
BanRecord.filter('remaining > ?', 0).update("remaining = remaining - #{time}")
|
301
|
+
BanMask.filter('bantime > ?', 0).update("bantime = bantime - #{time}")
|
302
302
|
end
|
303
|
-
BanRecord.filter
|
303
|
+
BanRecord.filter('remaining <= ?', 0).filter('removed = ?', false).each do |record|
|
304
304
|
if(me.is_op?(record.channel))
|
305
305
|
@pipeline << ChannelMode.new(record.channel, '-b', record.mask)
|
306
|
-
record.
|
306
|
+
record.update_with_params(:removed => true)
|
307
307
|
@pipeline << Invite.new(record.nick, record.channel) if record.invite
|
308
308
|
end
|
309
309
|
end
|
310
|
-
BanMask.filter
|
311
|
-
next_ban_record = BanRecord.filter
|
312
|
-
next_mask_record = BanMask.filter
|
310
|
+
BanMask.filter('bantime < ?', 1).destroy
|
311
|
+
next_ban_record = BanRecord.filter('remaining > ?', 0).order(:remaining).first
|
312
|
+
next_mask_record = BanMask.filter('bantime > ?', 0).order(:bantime).first
|
313
313
|
if(next_ban_record && next_mask_record)
|
314
314
|
time = next_ban_record.bantime < next_mask_record.bantime ? next_ban_record.bantime : next_mask_record.bantime
|
315
315
|
elsif(next_ban_record)
|
@@ -38,7 +38,7 @@ include Messages::Outgoing
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def add(message, params)
|
41
|
-
Models::Trigger.find_or_create(:trigger => params[:trigger]).
|
41
|
+
Models::Trigger.find_or_create(:trigger => params[:trigger]).update_with_params(:active => true)
|
42
42
|
@pipeline << Privmsg.new(message.replyto, "Trigger #{params[:trigger]} is now active")
|
43
43
|
@pipeline << Messages::Internal::TriggersUpdate.new
|
44
44
|
end
|
@@ -58,7 +58,7 @@ include Messages::Outgoing
|
|
58
58
|
def activate(message, params)
|
59
59
|
trigger = Models::Trigger[params[:id]]
|
60
60
|
if(trigger)
|
61
|
-
trigger.
|
61
|
+
trigger.update_with_params(:active => true)
|
62
62
|
@pipeline << Privmsg.new(message.replyto, "Trigger #{trigger.trigger} has been activated")
|
63
63
|
@pipeline << Messages::Internal::TriggersUpdate.new
|
64
64
|
else
|
@@ -69,7 +69,7 @@ include Messages::Outgoing
|
|
69
69
|
def deactivate(message, params)
|
70
70
|
trigger = Models::Trigger[params[:id]]
|
71
71
|
if(trigger)
|
72
|
-
trigger.
|
72
|
+
trigger.update_with_params(:active => false)
|
73
73
|
@pipeline << Privmsg.new(message.replyto, "Trigger #{trigger.trigger} has been deactivated")
|
74
74
|
@pipeline << Messages::Internal::TriggersUpdate.new
|
75
75
|
else
|