butler 1.8.1 → 1.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +212 -0
- data/{README → README.txt} +0 -0
- data/Rakefile +16 -11
- data/bin/botcontrol +35 -14
- data/data/butler/dialogs/create.rb +29 -40
- data/data/butler/dialogs/create_config.rb +1 -1
- data/data/butler/dialogs/dir.rb +13 -0
- data/data/butler/dialogs/en/create.yaml +24 -10
- data/data/butler/dialogs/en/dir.yaml +5 -0
- data/data/butler/dialogs/en/help.yaml +28 -11
- data/data/butler/dialogs/en/quickcreate.yaml +14 -0
- data/data/butler/dialogs/help.rb +16 -4
- data/data/butler/dialogs/quickcreate.rb +49 -0
- data/data/butler/plugins/core/access.rb +211 -0
- data/data/butler/plugins/core/logout.rb +11 -11
- data/data/butler/plugins/core/plugins.rb +23 -41
- data/data/butler/plugins/dev/bleakhouse.rb +46 -0
- data/data/butler/plugins/games/roll.rb +1 -1
- data/data/butler/plugins/operator/deop.rb +15 -20
- data/data/butler/plugins/operator/devoice.rb +14 -20
- data/data/butler/plugins/operator/limit.rb +56 -21
- data/data/butler/plugins/operator/op.rb +15 -20
- data/data/butler/plugins/operator/voice.rb +15 -20
- data/data/butler/plugins/service/define.rb +3 -3
- data/data/butler/plugins/service/more.rb +40 -0
- data/data/butler/plugins/util/cycle.rb +1 -1
- data/data/butler/plugins/util/load.rb +5 -5
- data/data/butler/plugins/util/pong.rb +3 -2
- data/lib/access/privilege.rb +17 -0
- data/lib/access/role.rb +33 -2
- data/lib/access/savable.rb +6 -0
- data/lib/access/yamlbase.rb +1 -2
- data/lib/butler/bot.rb +40 -7
- data/lib/butler/debuglog.rb +17 -0
- data/lib/butler/dialog.rb +1 -1
- data/lib/butler/irc/{channels.rb → channellist.rb} +2 -2
- data/lib/butler/irc/client.rb +60 -79
- data/lib/butler/irc/client/filter.rb +12 -0
- data/lib/butler/irc/client/listener.rb +55 -0
- data/lib/butler/irc/client/listenerlist.rb +69 -0
- data/lib/butler/irc/hostmask.rb +31 -16
- data/lib/butler/irc/message.rb +3 -3
- data/lib/butler/irc/parser.rb +2 -2
- data/lib/butler/irc/parser/rfc2812.rb +2 -6
- data/lib/butler/irc/socket.rb +12 -6
- data/lib/butler/irc/string.rb +4 -0
- data/lib/butler/irc/user.rb +0 -6
- data/lib/butler/irc/{users.rb → userlist.rb} +2 -2
- data/lib/butler/irc/whois.rb +6 -0
- data/lib/butler/plugin.rb +48 -14
- data/lib/butler/plugin/configproxy.rb +20 -0
- data/lib/butler/plugin/mapper.rb +308 -24
- data/lib/butler/plugin/matcher.rb +3 -1
- data/lib/butler/plugin/more.rb +65 -0
- data/lib/butler/plugin/onhandlers.rb +4 -4
- data/lib/butler/plugin/trigger.rb +4 -2
- data/lib/butler/plugins.rb +1 -1
- data/lib/butler/session.rb +11 -0
- data/lib/butler/version.rb +1 -1
- data/lib/cloptions.rb +1 -1
- data/lib/diagnostics.rb +20 -0
- data/lib/dialogline.rb +1 -1
- data/lib/durations.rb +19 -6
- data/lib/event.rb +8 -5
- data/lib/installer.rb +10 -3
- data/lib/ostructfixed.rb +11 -0
- data/lib/ruby/kernel/daemonize.rb +1 -2
- data/test/butler/plugin/mapper.rb +46 -0
- metadata +28 -11
- data/CHANGELOG +0 -44
- data/data/butler/plugins/core/privilege.rb +0 -103
@@ -0,0 +1,55 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
class Butler
|
10
|
+
module IRC
|
11
|
+
class Client
|
12
|
+
|
13
|
+
# Created by Butler::IRC::Client#subscribe() and similar methods
|
14
|
+
class Listener
|
15
|
+
AllSymbols = [nil].freeze
|
16
|
+
include Comparable
|
17
|
+
|
18
|
+
attr_reader :priority
|
19
|
+
attr_reader :symbols
|
20
|
+
attr_accessor :container
|
21
|
+
|
22
|
+
def initialize(symbols=nil, priority=0, *args, &callback)
|
23
|
+
@priority = priority
|
24
|
+
@symbols = (symbols ? Array(symbols) : AllSymbols).freeze
|
25
|
+
@args = args
|
26
|
+
@callback = callback
|
27
|
+
@container = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# will remove this listener from the clients dispatcher forever
|
31
|
+
def unsubscribe
|
32
|
+
@container.unsubscribe(self)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Comparison is done by priority, higher priority comes first, so
|
36
|
+
# Listener.new(nil, -100) > Listener.new(nil, 100)
|
37
|
+
def <=>(other)
|
38
|
+
other.priority <=> @priority
|
39
|
+
end
|
40
|
+
|
41
|
+
# set the priority of this listener
|
42
|
+
# see Butler::IRC::Client#subscribe() for infos about priority
|
43
|
+
def priority=(value)
|
44
|
+
@priority = Integer(value)
|
45
|
+
@container.mutated(self)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Invoke the listener, always passes self as first argument
|
49
|
+
def call(*args)
|
50
|
+
@callback.call(self, *(args+@args))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
require 'thread'
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
class Butler
|
14
|
+
module IRC
|
15
|
+
class Client
|
16
|
+
class ListenerList
|
17
|
+
include Enumerable
|
18
|
+
|
19
|
+
attr_reader :mutex
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@mutex = Mutex.new
|
23
|
+
@all = {}
|
24
|
+
@per_symbol = Hash.new { |h,k| h[k] = [] }
|
25
|
+
end
|
26
|
+
|
27
|
+
def each(&block)
|
28
|
+
@all.each_key(&block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def synchronized_each_for(symbol, &block)
|
32
|
+
@mutex.synchronize {
|
33
|
+
@per_symbol[symbol]+@per_symbol[nil]
|
34
|
+
}.each(&block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def subscribe(listener)
|
38
|
+
@mutex.synchronize {
|
39
|
+
raise "#{listener} already subscribed" if @all[listener]
|
40
|
+
listener.container = self
|
41
|
+
@all[listener] = true
|
42
|
+
listener.symbols.each { |s|
|
43
|
+
@per_symbol[s] << listener
|
44
|
+
@per_symbol[s] = @per_symbol[s].sort_by { |l| -l.priority }
|
45
|
+
}
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def unsubscribe(listener)
|
50
|
+
@mutex.synchronize {
|
51
|
+
@all.delete(listener)
|
52
|
+
listener.symbols.each { |s|
|
53
|
+
@per_symbol[s].delete(listener)
|
54
|
+
@per_symbol.delete(s) if @per_symbol[s].empty?
|
55
|
+
}
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def mutated(listener)
|
60
|
+
@mutex.synchronize {
|
61
|
+
listener.symbols.each { |symbol|
|
62
|
+
@per_symbol[s] = @per_symbol[s].sort_by { |l| -l.priority }
|
63
|
+
}
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/butler/irc/hostmask.rb
CHANGED
@@ -6,48 +6,63 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
require 'butler/irc/users'
|
10
|
-
|
11
|
-
|
12
|
-
|
13
9
|
class Butler
|
14
10
|
module IRC
|
15
11
|
# Provides methods to see if hostmasks match
|
16
12
|
class Hostmask
|
13
|
+
|
14
|
+
# List of characters to escape in hostmasks and with what to replace
|
17
15
|
Filter = [
|
18
16
|
[/([\\\[\]{}^`.-])/, '\\\\\1'],
|
19
17
|
[/\?/, "."],
|
20
18
|
[/\*/, ".*?"],
|
21
19
|
]
|
22
20
|
|
23
|
-
#
|
21
|
+
# Create a hostmask from a hostmask-string, e.g. "nick!user@host.tld"
|
22
|
+
# Also see Butler::IRC::User#hostmask
|
24
23
|
def initialize(mask)
|
25
|
-
@mask = mask.
|
26
|
-
|
27
|
-
#
|
28
|
-
|
24
|
+
@mask = mask.freeze
|
25
|
+
|
26
|
+
# FIXME, not yet correct, escaped * and ?
|
27
|
+
filtered = Filter.inject(@mask) { |s,(a,b)| s.gsub(a,b) }
|
28
|
+
# FIXME implement later
|
29
|
+
#string.gsub(/[\\\x00-\x1f]/) { |match| ("\\%02x" % match[0]) }
|
30
|
+
n,u,h = filtered.split(/[!@]/)
|
31
|
+
@regex = Regexp.new("\A(#{n})!(#{u})@(#{h})\z")
|
29
32
|
end
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
# Match a hostmask or anything that responds to #hostmask or #to_str
|
35
|
+
# Sets $1-$3 to nick, user and host if matched.
|
36
|
+
def =~(mask)
|
37
|
+
mask = mask.hostmask if mask.respond_to?(:hostmask)
|
38
|
+
!!(@regex =~ mask.to_str)
|
34
39
|
end
|
35
|
-
|
40
|
+
|
41
|
+
# Match a hostmask or anything that responds to #hostmask or #to_str
|
42
|
+
# Returns a MatchData instance with 3 captures (nick, user, host)
|
36
43
|
def match(mask)
|
37
44
|
mask = mask.hostmask if mask.kind_of?(User)
|
38
45
|
@regex.match(mask.to_str)
|
39
46
|
end
|
40
|
-
|
47
|
+
alias === match
|
48
|
+
|
49
|
+
# return the mask-string
|
41
50
|
def to_str
|
42
51
|
@mask
|
43
52
|
end
|
44
53
|
alias to_s to_str
|
45
|
-
|
54
|
+
|
55
|
+
def inspect # :nodoc:
|
56
|
+
"#<Hostmask #{@mask}>"
|
57
|
+
end
|
58
|
+
end # Hostmask
|
46
59
|
|
47
60
|
class User
|
61
|
+
# Return the users hostmask, uses wildcards for unknown parts
|
62
|
+
# FIXME enable wildcard enforcement
|
48
63
|
def hostmask
|
49
64
|
return Hostmask.new("#{@nick||'*'}!#{@user||'*'}@#{@host||'*'}")
|
50
65
|
end
|
51
66
|
end
|
52
67
|
end
|
53
|
-
end
|
68
|
+
end
|
data/lib/butler/irc/message.rb
CHANGED
@@ -8,16 +8,16 @@
|
|
8
8
|
|
9
9
|
#require 'ruby/string' # we need the transcode! method
|
10
10
|
|
11
|
+
|
12
|
+
|
11
13
|
class Butler
|
12
14
|
module IRC
|
13
15
|
|
14
16
|
# Butler::IRC::Message represents messages received by the server.
|
15
17
|
# It provides convenience methods that allow to access information about
|
16
18
|
# those messages easier, e.g. who (as Butler::IRC::User object) sent the
|
17
|
-
# message in which channel (IRC::Channel object) with what text.
|
19
|
+
# message in which channel (Butler::IRC::Channel object) with what text.
|
18
20
|
# Raw message and raw parsed data are still available though.
|
19
|
-
#
|
20
|
-
# =FIXME
|
21
21
|
class Message
|
22
22
|
# the command-symbol, see COMMANDS (e.g. :PRIVMSG, :JOIN, ...)
|
23
23
|
attr_reader :symbol
|
data/lib/butler/irc/parser.rb
CHANGED
@@ -6,12 +6,12 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
require 'butler/irc/
|
9
|
+
require 'butler/irc/channellist'
|
10
10
|
require 'butler/irc/hostmask'
|
11
11
|
require 'butler/irc/message'
|
12
12
|
require 'butler/irc/parser/commands'
|
13
13
|
require 'butler/irc/string'
|
14
|
-
require 'butler/irc/
|
14
|
+
require 'butler/irc/userlist'
|
15
15
|
require 'ruby/exception/detailed'
|
16
16
|
require 'ruby/hash/zip'
|
17
17
|
|
@@ -29,8 +29,7 @@ add("kill", :KILL, /^(\S*) (\S*) (.*)/, [:channel, :for, :text]) { |message
|
|
29
29
|
parser.channels.delete_user(message.for, :kill)
|
30
30
|
end
|
31
31
|
}
|
32
|
-
|
33
|
-
add("mode", :MODE, /^(\S*) :?(.*)/, [:for, :arguments]) { |message, parser|
|
32
|
+
add("mode", :MODE, /^(\S*) (.*)/, [:for, :arguments]) { |message, parser|
|
34
33
|
modifiers = message[:arguments].split(" ")
|
35
34
|
modes = modifiers.shift.split("")
|
36
35
|
flags = {"o" => User::Flags::OP, "v" => User::Flags::VOICE, "u" => User::Flags::UOP}
|
@@ -190,10 +189,7 @@ add("317", :RPL_WHOISIDLE, /^(\S+) (\S+) ([^:]+) :(.*)/, [:for, :nick, :values,
|
|
190
189
|
}
|
191
190
|
}
|
192
191
|
add("318", :RPL_ENDOFWHOIS)
|
193
|
-
add("319", :RPL_WHOISCHANNELS, /^(\S+) (\S+) :(.*)/, [:for, :nick, :channels])
|
194
|
-
# FIXME
|
195
|
-
message.alter_member(:channels, message.channels.split(" ").map { |channel| parser.channels.create(channel) })
|
196
|
-
}
|
192
|
+
add("319", :RPL_WHOISCHANNELS, /^(\S+) (\S+) :(.*)/, [:for, :nick, :channels]) # only add channels shared with butler to a user - that happens elsewhere already
|
197
193
|
add("321", :RPL_LISTSTART)
|
198
194
|
add("322", :RPL_LIST, /^(\S+) (\S+) (\d+) :(.*)/, [:for, :channelname, :usercount, :topic])
|
199
195
|
add("323", :RPL_LISTEND)
|
data/lib/butler/irc/socket.rb
CHANGED
@@ -6,11 +6,12 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
require '
|
10
|
-
require 'socket'
|
11
|
-
require 'ostructfixed'
|
9
|
+
require 'diagnostics'
|
12
10
|
require 'log/comfort'
|
11
|
+
require 'ostructfixed'
|
13
12
|
require 'ruby/string/chunks'
|
13
|
+
require 'socket'
|
14
|
+
require 'thread'
|
14
15
|
|
15
16
|
|
16
17
|
|
@@ -56,7 +57,7 @@ class Butler
|
|
56
57
|
VERSION = "1.0.0"
|
57
58
|
|
58
59
|
include Log::Comfort
|
59
|
-
|
60
|
+
|
60
61
|
# server the instance is linked with
|
61
62
|
attr_reader :server
|
62
63
|
# port used for connection
|
@@ -107,7 +108,7 @@ class Butler
|
|
107
108
|
@limit[key] = options.delete(key) if options.has_key?(key)
|
108
109
|
}
|
109
110
|
@mutex = Mutex.new
|
110
|
-
@socket =
|
111
|
+
@socket = Diagnostics.new(self, :write => [NoMethodError, "Must connect first to write to the socket"])
|
111
112
|
@connected = false
|
112
113
|
raise ArgumentError, "Unknown arguments: #{options.keys.inspect}" unless options.empty?
|
113
114
|
end
|
@@ -205,6 +206,7 @@ class Butler
|
|
205
206
|
end
|
206
207
|
|
207
208
|
# FIXME, figure out what the server supports, possibly requires it
|
209
|
+
# to be moved to Butler::IRC::Client (to allow ghosting, nickchange, identify)
|
208
210
|
def ghost(nickname, password)
|
209
211
|
write("NS :GHOST #{nickname} #{password}")
|
210
212
|
end
|
@@ -273,7 +275,6 @@ class Butler
|
|
273
275
|
end
|
274
276
|
|
275
277
|
# part specified channels
|
276
|
-
# FIXME, better way to implement the reason? use a block (yay)?
|
277
278
|
# returns the channels parted from.
|
278
279
|
def part(reason=nil, *channels)
|
279
280
|
if channels.empty?
|
@@ -310,6 +311,11 @@ class Butler
|
|
310
311
|
write("KICK #{channel} #{user} :#{reason}")
|
311
312
|
end
|
312
313
|
|
314
|
+
# send a mode command to a channel
|
315
|
+
def mode(channel, mode)
|
316
|
+
write("MODE #{channel} #{mode}")
|
317
|
+
end
|
318
|
+
|
313
319
|
# Give Op to user in channel
|
314
320
|
# User can be a nick or IRC::User, either one or an array.
|
315
321
|
def op(channel, *users)
|
data/lib/butler/irc/string.rb
CHANGED
@@ -45,6 +45,10 @@ class String
|
|
45
45
|
def valid_user?
|
46
46
|
strip_user_prefixes.valid_nickname?
|
47
47
|
end
|
48
|
+
|
49
|
+
def same_nick?(other)
|
50
|
+
strip_user_prefixes.downcase == other.to_str.strip_user_prefixes.downcase
|
51
|
+
end
|
48
52
|
|
49
53
|
# removes indicators from nicknames and channelnames
|
50
54
|
def strip_user_prefixes
|
data/lib/butler/irc/user.rb
CHANGED
@@ -166,7 +166,6 @@ class Butler
|
|
166
166
|
!common_channels(with_other_user).empty?
|
167
167
|
end
|
168
168
|
|
169
|
-
# FIXME
|
170
169
|
# add a channel to the user (should only be used by Butler::IRC::Parser)
|
171
170
|
def add_channel(channel, reason)
|
172
171
|
@channels[channel.to_str.downcase] ||= 0
|
@@ -176,7 +175,6 @@ class Butler
|
|
176
175
|
self
|
177
176
|
end
|
178
177
|
|
179
|
-
# FIXME
|
180
178
|
# remove a channel from the user (should only be used by Butler::IRC::Parser)
|
181
179
|
def delete_channel(channel, reason)
|
182
180
|
@channels.delete(channel.to_str.downcase)
|
@@ -185,28 +183,24 @@ class Butler
|
|
185
183
|
end
|
186
184
|
end
|
187
185
|
|
188
|
-
# FIXME
|
189
186
|
def add_flags(channel, flags)
|
190
187
|
channel = channel.to_str.downcase
|
191
188
|
raise ArgumentError, "User #{self} is not listed in #{channel}" unless @channels.include?(channel)
|
192
189
|
@channels[channel] |= flags
|
193
190
|
end
|
194
191
|
|
195
|
-
# FIXME
|
196
192
|
def delete_flags(channel, flags)
|
197
193
|
channel = channel.to_str.downcase
|
198
194
|
raise ArgumentError, "User #{self} is not listed in #{channel}" unless @channels.include?(channel)
|
199
195
|
@channels[channel] &= ~flags
|
200
196
|
end
|
201
197
|
|
202
|
-
# FIXME
|
203
198
|
def quit
|
204
199
|
@channels.each { |channel, _| delete_channel(channel, :quit) }
|
205
200
|
self.status = :offline
|
206
201
|
@users.delete(self, :quit)
|
207
202
|
end
|
208
203
|
|
209
|
-
# FIXME
|
210
204
|
def kill
|
211
205
|
@channels.each { |channel, _| delete_channel(channel, :kill) }
|
212
206
|
self.status = :offline
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
require 'butler/irc/
|
9
|
+
require 'butler/irc/channellist'
|
10
10
|
require 'butler/irc/string'
|
11
11
|
require 'butler/irc/user'
|
12
12
|
require 'thread'
|
@@ -16,7 +16,7 @@ require 'thread'
|
|
16
16
|
class Butler
|
17
17
|
module IRC
|
18
18
|
# Enumerable: all known & visible users
|
19
|
-
class
|
19
|
+
class UserList
|
20
20
|
include Enumerable
|
21
21
|
|
22
22
|
# the user that represents the clients user
|
data/lib/butler/plugin.rb
CHANGED
@@ -10,6 +10,7 @@ require 'butler/plugin/configproxy'
|
|
10
10
|
require 'butler/plugin/onhandlers'
|
11
11
|
require 'butler/plugin/mapper'
|
12
12
|
require 'butler/plugin/matcher'
|
13
|
+
require 'butler/plugin/more'
|
13
14
|
require 'butler/plugin/trigger'
|
14
15
|
require 'log/comfort'
|
15
16
|
require 'ostructfixed'
|
@@ -36,15 +37,16 @@ class Butler
|
|
36
37
|
# this method is called to initialize the plugin-class,
|
37
38
|
# do not override
|
38
39
|
def load_plugin(butler, base, path) # :nodoc:
|
39
|
-
@butler
|
40
|
-
@base
|
41
|
-
@name
|
42
|
-
@commands
|
43
|
-
@listener
|
44
|
-
@
|
40
|
+
@butler = butler
|
41
|
+
@base = base.dup.freeze
|
42
|
+
@name = File.basename(base).freeze
|
43
|
+
@commands = []
|
44
|
+
@listener = []
|
45
|
+
@mapping_type = Hash.new { |h,k| MappingTypes[k] }
|
46
|
+
@config = ConfigProxy.new(@butler.config, "plugin/#{name}")
|
45
47
|
|
46
48
|
if File.directory?(path) then
|
47
|
-
raise "Not supported yet"
|
49
|
+
raise "Not supported yet"
|
48
50
|
@path = OpenStruct.new(
|
49
51
|
:data => (@path+"/data").freeze,
|
50
52
|
:strings => (@path+"/strings").freeze,
|
@@ -104,12 +106,16 @@ class Butler
|
|
104
106
|
new(message).usage(data)
|
105
107
|
end
|
106
108
|
|
107
|
-
def on_load
|
109
|
+
def on_load(*args)
|
110
|
+
end
|
111
|
+
|
112
|
+
def on_login(*args)
|
108
113
|
end
|
109
114
|
|
110
115
|
def trigger(commands)
|
111
116
|
commands = { "en" => commands } unless commands.kind_of?(Hash)
|
112
117
|
commands.each { |lang, command|
|
118
|
+
raise "Invalid trigger, language must be a string" unless String === lang
|
113
119
|
trigger = Trigger.new(self, lang, command)
|
114
120
|
@butler.add_command(trigger)
|
115
121
|
@commands << trigger
|
@@ -119,6 +125,7 @@ class Butler
|
|
119
125
|
def map(meth, expressions)
|
120
126
|
expressions = { "en" => expressions } unless expressions.kind_of?(Hash)
|
121
127
|
expressions.each { |lang, expression|
|
128
|
+
raise "Invalid map, language must be a string, method a symbol and expression a string" unless String === lang and String === expression and Symbol === meth
|
122
129
|
mapper = Mapper.new(self, meth, lang, expression)
|
123
130
|
@butler.add_command(mapper)
|
124
131
|
@commands << mapper
|
@@ -142,8 +149,14 @@ class Butler
|
|
142
149
|
@listener << listener
|
143
150
|
listener
|
144
151
|
end
|
152
|
+
|
153
|
+
def on_disconnect(*args)
|
154
|
+
end
|
155
|
+
|
156
|
+
def on_quit(*args)
|
157
|
+
end
|
145
158
|
|
146
|
-
def on_unload
|
159
|
+
def on_unload(*args)
|
147
160
|
end
|
148
161
|
|
149
162
|
def unload_plugin
|
@@ -205,14 +218,35 @@ class Butler
|
|
205
218
|
# and translates it using vars as variables for the string interpolation.
|
206
219
|
# The string is subsequently mirc_formatted (see String#mirc_formatted).
|
207
220
|
# Besides that it works like Message#answer.
|
208
|
-
|
209
|
-
|
210
|
-
|
221
|
+
# Another feature of answer is, that it is 'moreified', that means if your answer-text is longer
|
222
|
+
# than 300 chars, butler will display 'more...' at the end and using the plugin 'more' the user
|
223
|
+
# can see the rest of the text.
|
224
|
+
def answer(text, vars={})
|
225
|
+
text = localize(text, vars) if text.kind_of?(Symbol)
|
226
|
+
@message.from.session["more"] = More.new(
|
227
|
+
@message,
|
228
|
+
nil,
|
229
|
+
text.mirc_formatted
|
230
|
+
)
|
231
|
+
@message.answer("#{@message.from.to_s+': ' if @message.public?}#{@message.from.session['more'].show}")
|
211
232
|
end
|
233
|
+
|
234
|
+
# Same as answer, but 'more' gets a lead prefixed (see Butler::Plugin::More for more info)
|
235
|
+
def answer_with_lead(lead, string, vars={})
|
236
|
+
text = localize(text, vars) if text.kind_of?(Symbol)
|
237
|
+
lead = localize(lead, vars) if text.kind_of?(Symbol)
|
238
|
+
@message.from.session["more"] = More.new(
|
239
|
+
@message,
|
240
|
+
lead.mirc_formatted,
|
241
|
+
text.mirc_formatted
|
242
|
+
)
|
243
|
+
@message.answer("#{@message.from.to_s+': ' if @message.public?}#{@message.from.session['more'].show}")
|
244
|
+
end
|
245
|
+
|
212
246
|
|
213
247
|
# == About
|
214
248
|
# Sends a privmsg (localized and formatted) to any number of recipients
|
215
|
-
# (
|
249
|
+
# (UserList or ChannelList)
|
216
250
|
#
|
217
251
|
# == Synopsis
|
218
252
|
# privmsg(:greet, "#some_channel", :from => @butler.myself.nick)
|
@@ -230,7 +264,7 @@ class Butler
|
|
230
264
|
|
231
265
|
# == About
|
232
266
|
# Sends a notice (localized and formatted) to any number of recipients
|
233
|
-
# (
|
267
|
+
# (UserList or ChannelList)
|
234
268
|
#
|
235
269
|
# == Synopsis
|
236
270
|
# notice(:greet, "#some_channel", :from => @butler.myself.nick)
|