mod_spox 0.0.3 → 0.0.4
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.
- 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
|