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')"
7 # base user message class, all user messages derive from this
8 # (a user message is defined as having a source hostmask, a target
9 # nick/channel and a message part)
10 class BasicUserMessage
15 # when the message was received
18 # hostmask of message source
21 # nick of message source
22 attr_reader :sourcenick
24 # url part of message source
25 attr_reader :sourceaddress
27 # nick/channel message was sent to
30 # contents of the message
31 attr_accessor :message
33 # has the message been replied to/handled by a plugin?
34 attr_accessor :replied
36 # instantiate a new Message
37 # bot:: associated bot class
38 # source:: hostmask of the message source
39 # target:: nick/channel message is destined for
40 # message:: message part
41 def initialize(bot, source, target, message)
47 @message = BasicUserMessage.stripcolour message
50 # split source into consituent parts
51 if source =~ /^((\S+)!(\S+))$/
56 if target && target.downcase == @bot.nick.downcase
62 # returns true if the message was addressed to the bot.
63 # This includes any private message to the bot, or any public message
64 # which looks like it's addressed to the bot, e.g. "bot: foo", "bot, foo",
65 # a kick message when bot was kicked etc.
70 # has this message been replied to by a plugin?
75 # strip mIRC colour escapes from a string
76 def BasicUserMessage.stripcolour(string)
77 return "" unless string
78 ret = string.gsub(/\cC\d\d?(?:,\d\d?)?/, "")
79 #ret.tr!("\x00-\x1f", "")
85 # class for handling IRC user messages. Includes some utilities for handling
86 # the message, for example in plugins.
87 # The +message+ member will have any bot addressing "^bot: " removed
88 # (address? will return true in this case)
89 class UserMessage < BasicUserMessage
91 # for plugin messages, the name of the plugin invoked by the message
94 # for plugin messages, the rest of the message, with the plugin name
98 # convenience member. Who to reply to (i.e. would be sourcenick for a
99 # privately addressed message, or target (the channel) for a publicly
103 # channel the message was in, nil for privately addressed messages
106 # for PRIVMSGs, true if the message was a CTCP ACTION (CTCP stuff
107 # will be stripped from the message)
110 # instantiate a new UserMessage
111 # bot:: associated bot class
112 # source:: hostmask of the message source
113 # target:: nick/channel message is destined for
114 # message:: message part
115 def initialize(bot, source, target, message)
116 super(bot, source, target, message)
122 if target.downcase == @bot.nick.downcase
126 @replyto = @sourcenick
132 # check for option extra addressing prefixes, e.g "|search foo", or
133 # "!version" - first match wins
134 bot.config['core.address_prefix'].each {|mprefix|
135 if @message.gsub!(/^#{Regexp.escape(mprefix)}\s*/, "")
141 # even if they used above prefixes, we allow for silly people who
142 # combine all possible types, e.g. "|rbot: hello", or
143 # "/msg rbot rbot: hello", etc
144 if @message.gsub!(/^\s*#{Regexp.escape(bot.nick)}\s*([:;,>]|\s)\s*/i, "")
148 if(@message =~ /^\001ACTION\s(.+)\001/)
153 # free splitting for plugins
154 @params = @message.dup
155 if @params.gsub!(/^\s*(\S+)[\s$]*/, "")
156 @plugin = $1.downcase
157 @params = nil unless @params.length > 0
161 # returns true for private messages, e.g. "/msg bot hello"
166 # returns true if the message was in a channel
175 # convenience method to reply to a message, useful in plugins. It's the
177 # <tt>@bot.say m.replyto, string</tt>
178 # So if the message is private, it will reply to the user. If it was
179 # in a channel, it will reply in the channel.
181 @bot.say @replyto, string
185 # convenience method to reply "okay" in the current language to the
188 @bot.say @replyto, @bot.lang.get("okay")
193 # class to manage IRC PRIVMSGs
194 class PrivMessage < UserMessage
197 # class to manage IRC NOTICEs
198 class NoticeMessage < UserMessage
201 # class to manage IRC KICKs
202 # +address?+ can be used as a shortcut to see if the bot was kicked,
203 # basically, +target+ was kicked from +channel+ by +source+ with +message+
204 class KickMessage < BasicUserMessage
205 # channel user was kicked from
208 def initialize(bot, source, target, channel, message="")
209 super(bot, source, target, message)
214 # class to pass IRC Nick changes in. @message contains the old nickame,
215 # @sourcenick contains the new one.
216 class NickMessage < BasicUserMessage
217 def initialize(bot, source, oldnick, newnick)
218 super(bot, source, oldnick, newnick)
222 class QuitMessage < BasicUserMessage
223 def initialize(bot, source, target, message="")
224 super(bot, source, target, message)
228 class TopicMessage < BasicUserMessage
231 # topic set at (unixtime)
232 attr_reader :timestamp
233 # topic set on channel
236 def initialize(bot, source, channel, timestamp, topic="")
237 super(bot, source, channel, topic)
239 @timestamp = timestamp
244 # class to manage channel joins
245 class JoinMessage < BasicUserMessage
248 def initialize(bot, source, channel, message="")
249 super(bot, source, channel, message)
251 # in this case sourcenick is the nick that could be the bot
252 @address = (sourcenick.downcase == @bot.nick.downcase)
256 # class to manage channel parts
257 # same as a join, but can have a message too
258 class PartMessage < JoinMessage