2 BotConfig.register BotConfigArrayValue.new('core.address_prefix',
3 :default => [], :wizard => true,
4 :desc => "what non nick-matching prefixes should the bot respond to as if addressed (e.g !, so that '!foo' is treated like 'rbot: foo')"
12 # base user message class, all user messages derive from this
13 # (a user message is defined as having a source hostmask, a target
14 # nick/channel and a message part)
15 class BasicUserMessage
20 # when the message was received
23 # hostmask of message source
26 # nick of message source
27 attr_reader :sourcenick
29 # url part of message source
30 attr_reader :sourceaddress
32 # nick/channel message was sent to
35 # contents of the message
36 attr_accessor :message
38 # has the message been replied to/handled by a plugin?
39 attr_accessor :replied
41 # instantiate a new Message
42 # bot:: associated bot class
43 # source:: hostmask of the message source
44 # target:: nick/channel message is destined for
45 # message:: message part
46 def initialize(bot, source, target, message)
47 @msg_wants_id = false unless defined? @msg_wants_id
54 @message = BasicUserMessage.stripcolour message
58 if @msg_wants_id && @bot.capabilities["identify-msg".to_sym]
59 if @message =~ /([-+])(.*)/
60 @identified = ($1=="+")
63 warning "Message does not have identification"
67 # split source into consituent parts
68 if source =~ /^((\S+)!(\S+))$/
73 if target && target.downcase == @bot.nick.downcase
83 # returns true if the message was addressed to the bot.
84 # This includes any private message to the bot, or any public message
85 # which looks like it's addressed to the bot, e.g. "bot: foo", "bot, foo",
86 # a kick message when bot was kicked etc.
91 # has this message been replied to by a plugin?
96 # strip mIRC colour escapes from a string
97 def BasicUserMessage.stripcolour(string)
98 return "" unless string
99 ret = string.gsub(/\cC\d\d?(?:,\d\d?)?/, "")
100 #ret.tr!("\x00-\x1f", "")
106 # class for handling IRC user messages. Includes some utilities for handling
107 # the message, for example in plugins.
108 # The +message+ member will have any bot addressing "^bot: " removed
109 # (address? will return true in this case)
110 class UserMessage < BasicUserMessage
112 # for plugin messages, the name of the plugin invoked by the message
115 # for plugin messages, the rest of the message, with the plugin name
119 # convenience member. Who to reply to (i.e. would be sourcenick for a
120 # privately addressed message, or target (the channel) for a publicly
124 # channel the message was in, nil for privately addressed messages
127 # for PRIVMSGs, true if the message was a CTCP ACTION (CTCP stuff
128 # will be stripped from the message)
131 # instantiate a new UserMessage
132 # bot:: associated bot class
133 # source:: hostmask of the message source
134 # target:: nick/channel message is destined for
135 # message:: message part
136 def initialize(bot, source, target, message)
137 super(bot, source, target, message)
143 if target.downcase == @bot.nick.downcase
147 @replyto = @sourcenick
153 # check for option extra addressing prefixes, e.g "|search foo", or
154 # "!version" - first match wins
155 bot.config['core.address_prefix'].each {|mprefix|
156 if @message.gsub!(/^#{Regexp.escape(mprefix)}\s*/, "")
162 # even if they used above prefixes, we allow for silly people who
163 # combine all possible types, e.g. "|rbot: hello", or
164 # "/msg rbot rbot: hello", etc
165 if @message.gsub!(/^\s*#{Regexp.escape(bot.nick)}\s*([:;,>]|\s)\s*/i, "")
169 if(@message =~ /^\001ACTION\s(.+)\001/)
174 # free splitting for plugins
175 @params = @message.dup
176 if @params.gsub!(/^\s*(\S+)[\s$]*/, "")
177 @plugin = $1.downcase
178 @params = nil unless @params.length > 0
182 # returns true for private messages, e.g. "/msg bot hello"
187 # returns true if the message was in a channel
196 # convenience method to reply to a message, useful in plugins. It's the
198 # <tt>@bot.say m.replyto, string</tt>
199 # So if the message is private, it will reply to the user. If it was
200 # in a channel, it will reply in the channel.
202 @bot.say @replyto, string
206 # convenience method to reply to a message with an action. It's the
208 # <tt>@bot.action m.replyto, string</tt>
209 # So if the message is private, it will reply to the user. If it was
210 # in a channel, it will reply in the channel.
212 @bot.action @replyto, string
216 # convenience method to reply "okay" in the current language to the
219 @bot.say @replyto, @bot.lang.get("okay")
224 # class to manage IRC PRIVMSGs
225 class PrivMessage < UserMessage
226 def initialize(bot, source, target, message)
232 # class to manage IRC NOTICEs
233 class NoticeMessage < UserMessage
234 def initialize(bot, source, target, message)
240 # class to manage IRC KICKs
241 # +address?+ can be used as a shortcut to see if the bot was kicked,
242 # basically, +target+ was kicked from +channel+ by +source+ with +message+
243 class KickMessage < BasicUserMessage
244 # channel user was kicked from
247 def initialize(bot, source, target, channel, message="")
248 super(bot, source, target, message)
253 # class to pass IRC Nick changes in. @message contains the old nickame,
254 # @sourcenick contains the new one.
255 class NickMessage < BasicUserMessage
256 def initialize(bot, source, oldnick, newnick)
257 super(bot, source, oldnick, newnick)
261 class QuitMessage < BasicUserMessage
262 def initialize(bot, source, target, message="")
263 super(bot, source, target, message)
267 class TopicMessage < BasicUserMessage
270 # topic set at (unixtime)
271 attr_reader :timestamp
272 # topic set on channel
275 def initialize(bot, source, channel, timestamp, topic="")
276 super(bot, source, channel, topic)
278 @timestamp = timestamp
283 # class to manage channel joins
284 class JoinMessage < BasicUserMessage
287 def initialize(bot, source, channel, message="")
288 super(bot, source, channel, message)
290 # in this case sourcenick is the nick that could be the bot
291 @address = (sourcenick.downcase == @bot.nick.downcase)
295 # class to manage channel parts
296 # same as a join, but can have a message too
297 class PartMessage < JoinMessage