butler 1.8.1 → 1.8.2
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.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)
|