Reverse = "\026"
Italic = "\011"
NormalText = "\017"
+ AttributeRx = /#{Bold}|#{Underline}|#{Reverse}|#{Italic}|#{NormalText}/
# Color is prefixed by \003 and followed by optional
# foreground and background specifications, two-digits-max
Color = "\003"
ColorRx = /#{Color}\d?\d?(?:,\d\d?)?/
+ FormattingRx = /#{AttributeRx}|#{ColorRx}/
+
# Standard color codes
ColorCode = {
:black => 1,
# User/Channel message was sent to
attr_reader :target
- # contents of the message
+ # contents of the message (stripped of initial/final format codes)
attr_accessor :message
# contents of the message (for logging purposes)
attr_accessor :logmessage
+ # contents of the message (stripped of all formatting)
+ attr_accessor :plainmessage
+
# has the message been replied to/handled by a plugin?
attr_accessor :replied
+ alias :replied? :replied
# should the message be ignored?
attr_accessor :ignored
alias :ignored? :ignored
+ # set this to true if the method that delegates the message is run in a thread
+ attr_accessor :in_thread
+ alias :in_thread? :in_thread
+
+ def inspect(fields=nil)
+ ret = self.__to_s__[0..-2]
+ ret << ' bot=' << @bot.__to_s__
+ ret << ' server=' << server.to_s
+ ret << ' time=' << time.to_s
+ ret << ' source=' << source.to_s
+ ret << ' target=' << target.to_s
+ ret << ' message=' << message.inspect
+ ret << ' logmessage=' << logmessage.inspect
+ ret << ' plainmessage=' << plainmessage.inspect
+ ret << fields if fields
+ ret << ' (identified)' if identified?
+ ret << ' (addressed to me)' if identified?
+ ret << ' (replied)' if replied?
+ ret << ' (ignored)' if ignored?
+ ret << ' (in thread)' if in_thread?
+ ret << '>'
+ end
+
# instantiate a new Message
# bot:: associated bot class
# server:: Server where the message took place
@source = source
@address = false
@target = target
- @message = BasicUserMessage.stripcolour message
+ @message = message || ""
@replied = false
@server = server
@ignored = false
+ @in_thread = false
@identified = false
if @msg_wants_id && @server.capabilities[:"identify-msg"]
end
end
@logmessage = @message.dup
+ @plainmessage = BasicUserMessage.strip_formatting(@message)
+ @message = BasicUserMessage.strip_initial_formatting(@message)
if target && target == @bot.myself
@address = true
ret
end
+ def BasicUserMessage.strip_initial_formatting(string)
+ return "" unless string
+ ret = string.gsub(/^#{FormattingRx}|#{FormattingRx}$/,"")
+ end
+
+ def BasicUserMessage.strip_formatting(string)
+ string.gsub(FormattingRx,"")
+ end
+
end
# class for handling welcome messages from the server
# (address? will return true in this case)
class UserMessage < BasicUserMessage
+ def inspect
+ fields = ' plugin=' << plugin.inspect
+ fields << ' params=' << params.inspect
+ fields << ' channel=' << channel.to_s if channel
+ fields << ' (reply to ' << replyto.to_s << ')'
+ if self.private?
+ fields << ' (private)'
+ else
+ fields << ' (public)'
+ end
+ if self.action?
+ fields << ' (action)'
+ elsif ctcp
+ fields << ' (CTCP ' << ctcp << ')'
+ end
+ super(fields)
+ end
+
# for plugin messages, the name of the plugin invoked by the message
attr_reader :plugin
# free splitting for plugins
@params = @message.dup
- if @params.gsub!(/^\s*(\S+)[\s$]*/, "")
+ # Created messges (such as by fake_message) can contain multiple lines
+ if @params.gsub!(/\A\s*(\S+)[\s$]*/m, "")
@plugin = $1.downcase
@params = nil unless @params.length > 0
end
# the nick or core.reply_with_nick is set to false
#
def reply(string, options={})
- if @bot.config['core.reply_with_nick'] and not string =~ /\b#{Regexp.escape(@source.to_s)}\b/
+ if @bot.config['core.reply_with_nick'] and not string =~ /(?:^|\W)#{Regexp.escape(@source.to_s)}(?:$|\W)/
return nickreply(string, options)
end
plainreply(string, options)
# class to manage IRC PRIVMSGs
class PrivMessage < UserMessage
- def initialize(bot, server, source, target, message)
- @msg_wants_id = true
- super
+ def initialize(bot, server, source, target, message, opts={})
+ @msg_wants_id = opts[:handle_id]
+ super(bot, server, source, target, message)
end
end
# class to manage IRC NOTICEs
class NoticeMessage < UserMessage
- def initialize(bot, server, source, target, message)
- @msg_wants_id = true
- super
+ def initialize(bot, server, source, target, message, opts={})
+ @msg_wants_id = opts[:handle_id]
+ super(bot, server, source, target, message)
end
end
# channel user was kicked from
attr_reader :channel
+ def inspect
+ fields = ' channel=' << channel.to_s
+ super(fields)
+ end
+
def initialize(bot, server, source, target, channel, message="")
super(bot, server, source, target, message)
@channel = channel
# channel user was invited to
attr_reader :channel
+ def inspect
+ fields = ' channel=' << channel.to_s
+ super(fields)
+ end
+
def initialize(bot, server, source, target, channel, message="")
super(bot, server, source, target, message)
@channel = channel
# class to pass IRC Nick changes in. @message contains the old nickame,
# @sourcenick contains the new one.
class NickMessage < BasicUserMessage
+ attr_accessor :is_on
def initialize(bot, server, source, oldnick, newnick)
super(bot, server, source, oldnick, newnick)
+ @is_on = []
end
def oldnick
def newnick
return @message
end
+
+ def inspect
+ fields = ' old=' << oldnick
+ fields << ' new=' << newnick
+ super(fields)
+ end
+ end
+
+ # class to manage mode changes
+ class ModeChangeMessage < BasicUserMessage
+ attr_accessor :modes
+ def initialize(bot, server, source, target, message="")
+ super(bot, server, source, target, message)
+ @address = (source == @bot.myself)
+ @modes = []
+ end
+
+ def inspect
+ fields = ' modes=' << modes.inspect
+ super(fields)
+ end
+ end
+
+ # class to manage NAME replies
+ class NamesMessage < BasicUserMessage
+ attr_accessor :users
+ def initialize(bot, server, source, target, message="")
+ super(bot, server, source, target, message)
+ @users = []
+ end
+
+ def inspect
+ fields = ' users=' << users.inspect
+ super(fields)
+ end
end
class QuitMessage < BasicUserMessage
+ attr_accessor :was_on
def initialize(bot, server, source, target, message="")
super(bot, server, source, target, message)
+ @was_on = []
end
end
# topic set on channel
attr_reader :channel
+ # :info if topic info, :set if topic set
+ attr_accessor :info_or_set
def initialize(bot, server, source, channel, topic=ChannelTopic.new)
super(bot, server, source, channel, topic.text)
@topic = topic
@timestamp = topic.set_on
@channel = channel
+ @info_or_set = nil
+ end
+
+ def inspect
+ fields = ' topic=' << topic
+ fields << ' (set on ' << timestamp << ')'
+ super(fields)
end
end
class JoinMessage < BasicUserMessage
# channel joined
attr_reader :channel
+
+ def inspect
+ fields = ' channel=' << channel.to_s
+ super(fields)
+ end
+
def initialize(bot, server, source, channel, message="")
super(bot, server, source, channel, message)
@channel = channel
# same as a join, but can have a message too
class PartMessage < JoinMessage
end
+
+ class UnknownMessage < BasicUserMessage
+ end
end