X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Fmessage.rb;h=62ba746921c5d3ad9c3be29fbb2deaa32011a8b8;hb=9c50738a84bec26402902513a4cd21b54dcc0a80;hp=ba5dcb43885f2e4ac4c8592a9c4af128002d46a6;hpb=ed78f06271350b42b36b4bcd5ede7395529823f6;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git
diff --git a/lib/rbot/message.rb b/lib/rbot/message.rb
index ba5dcb43..62ba7469 100644
--- a/lib/rbot/message.rb
+++ b/lib/rbot/message.rb
@@ -4,29 +4,41 @@ module Irc
:desc => "what non nick-matching prefixes should the bot respond to as if addressed (e.g !, so that '!foo' is treated like 'rbot: foo')"
)
+ BotConfig.register BotConfigBooleanValue.new('core.reply_with_nick',
+ :default => false, :wizard => true,
+ :desc => "if true, the bot will prepend the nick to what he has to say when replying (e.g. 'markey: you can't do that!')"
+ )
+
+ BotConfig.register BotConfigStringValue.new('core.nick_postfix',
+ :default => ':', :wizard => true,
+ :desc => "when replying with nick put this character after the nick of the user the bot is replying to"
+ )
+
+ Color = "\003"
+ Bold = "\002"
+ Underline = "\037"
+ Reverse = "\026"
+
# base user message class, all user messages derive from this
# (a user message is defined as having a source hostmask, a target
# nick/channel and a message part)
class BasicUserMessage
-
+
# associated bot
attr_reader :bot
-
+
+ # associated server
+ attr_reader :server
+
# when the message was received
attr_reader :time
- # hostmask of message source
+ # User that originated the message
attr_reader :source
-
- # nick of message source
- attr_reader :sourcenick
-
- # url part of message source
- attr_reader :sourceaddress
-
- # nick/channel message was sent to
+
+ # User/Channel message was sent to
attr_reader :target
-
+
# contents of the message
attr_accessor :message
@@ -35,10 +47,13 @@ module Irc
# instantiate a new Message
# bot:: associated bot class
- # source:: hostmask of the message source
- # target:: nick/channel message is destined for
- # message:: message part
- def initialize(bot, source, target, message)
+ # server:: Server where the message took place
+ # source:: User that sent the message
+ # target:: User/Channel is destined for
+ # message:: actual message
+ def initialize(bot, server, source, target, message)
+ @msg_wants_id = false unless defined? @msg_wants_id
+
@time = Time.now
@bot = bot
@source = source
@@ -46,19 +61,41 @@ module Irc
@target = target
@message = BasicUserMessage.stripcolour message
@replied = false
+ @server = server
- # split source into consituent parts
- if source =~ /^((\S+)!(\S+))$/
- @sourcenick = $2
- @sourceaddress = $3
+ @identified = false
+ if @msg_wants_id && @server.capabilities[:"identify-msg"]
+ if @message =~ /([-+])(.*)/
+ @identified = ($1=="+")
+ @message = $2
+ else
+ warning "Message does not have identification"
+ end
end
-
- if target && target.downcase == @bot.nick.downcase
+
+ if target && target == @bot.myself
@address = true
end
-
+
+ end
+
+ # Access the nick of the source
+ #
+ def sourcenick
+ @source.nick
+ end
+
+ # Access the user@host of the source
+ #
+ def sourceaddress
+ "#{@source.user}@#{@source.host}"
+ end
+
+ # Was the message from an identified user?
+ def identified?
+ return @identified
end
-
+
# returns true if the message was addressed to the bot.
# This includes any private message to the bot, or any public message
# which looks like it's addressed to the bot, e.g. "bot: foo", "bot, foo",
@@ -87,10 +124,10 @@ module Irc
# The +message+ member will have any bot addressing "^bot: " removed
# (address? will return true in this case)
class UserMessage < BasicUserMessage
-
+
# for plugin messages, the name of the plugin invoked by the message
attr_reader :plugin
-
+
# for plugin messages, the rest of the message, with the plugin name
# removed
attr_reader :params
@@ -102,28 +139,28 @@ module Irc
# channel the message was in, nil for privately addressed messages
attr_reader :channel
-
+
# for PRIVMSGs, true if the message was a CTCP ACTION (CTCP stuff
# will be stripped from the message)
attr_reader :action
-
+
# instantiate a new UserMessage
# bot:: associated bot class
# source:: hostmask of the message source
# target:: nick/channel message is destined for
# message:: message part
- def initialize(bot, source, target, message)
- super(bot, source, target, message)
+ def initialize(bot, server, source, target, message)
+ super(bot, server, source, target, message)
@target = target
@private = false
@plugin = nil
@action = false
-
- if target.downcase == @bot.nick.downcase
+
+ if target == @bot.myself
@private = true
@address = true
@channel = nil
- @replyto = @sourcenick
+ @replyto = source
else
@replyto = @target
@channel = @target
@@ -137,19 +174,19 @@ module Irc
break
end
}
-
+
# even if they used above prefixes, we allow for silly people who
- # combine all possible types, e.g. "|rbot: hello", or
+ # combine all possible types, e.g. "|rbot: hello", or
# "/msg rbot rbot: hello", etc
- if @message.gsub!(/^\s*#{bot.nick}\s*([:;,>]|\s)\s*/, "")
+ if @message.gsub!(/^\s*#{Regexp.escape(bot.nick)}\s*([:;,>]|\s)\s*/i, "")
@address = true
end
-
+
if(@message =~ /^\001ACTION\s(.+)\001/)
@message = $1
@action = true
end
-
+
# free splitting for plugins
@params = @message.dup
if @params.gsub!(/^\s*(\S+)[\s$]*/, "")
@@ -177,25 +214,81 @@ module Irc
# @bot.say m.replyto, string
# So if the message is private, it will reply to the user. If it was
# in a channel, it will reply in the channel.
- def reply(string)
- @bot.say @replyto, string
+ def plainreply(string, options={})
+ @bot.say @replyto, string, options
+ @replied = true
+ end
+
+ # Same as reply, but when replying in public it adds the nick of the user
+ # the bot is replying to
+ def nickreply(string, options={})
+ extra = self.public? ? "#{@source}#{@bot.config['core.nick_postfix']} " : ""
+ @bot.say @replyto, extra + string, options
+ @replied = true
+ end
+
+ # the default reply style is to nickreply unless the reply already contains
+ # 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#{@source}\b/
+ return nickreply(string, options)
+ end
+ plainreply(string, options)
+ end
+
+ # convenience method to reply to a message with an action. It's the
+ # same as doing:
+ # @bot.action m.replyto, string
+ # So if the message is private, it will reply to the user. If it was
+ # in a channel, it will reply in the channel.
+ def act(string, options={})
+ @bot.action @replyto, string, options
@replied = true
end
# convenience method to reply "okay" in the current language to the
# message
+ def plainokay
+ self.plainreply @bot.lang.get("okay")
+ end
+
+ # Like the above, but append the username
+ def nickokay
+ str = @bot.lang.get("okay").dup
+ if self.public?
+ # remove final punctuation
+ str.gsub!(/[!,.]$/,"")
+ str += ", #{@source}"
+ end
+ self.plainreply str
+ end
+
+ # the default okay style is the same as the default reply style
+ #
def okay
- @bot.say @replyto, @bot.lang.get("okay")
+ if @bot.config['core.reply_with_nick']
+ return nickokay
+ end
+ plainokay
end
end
# class to manage IRC PRIVMSGs
class PrivMessage < UserMessage
+ def initialize(bot, server, source, target, message)
+ @msg_wants_id = true
+ super
+ end
end
-
+
# class to manage IRC NOTICEs
class NoticeMessage < UserMessage
+ def initialize(bot, server, source, target, message)
+ @msg_wants_id = true
+ super
+ end
end
# class to manage IRC KICKs
@@ -204,9 +297,9 @@ module Irc
class KickMessage < BasicUserMessage
# channel user was kicked from
attr_reader :channel
-
- def initialize(bot, source, target, channel, message="")
- super(bot, source, target, message)
+
+ def initialize(bot, server, source, target, channel, message="")
+ super(bot, server, source, target, message)
@channel = channel
end
end
@@ -214,14 +307,22 @@ module Irc
# class to pass IRC Nick changes in. @message contains the old nickame,
# @sourcenick contains the new one.
class NickMessage < BasicUserMessage
- def initialize(bot, source, oldnick, newnick)
- super(bot, source, oldnick, newnick)
+ def initialize(bot, server, source, oldnick, newnick)
+ super(bot, server, source, oldnick, newnick)
+ end
+
+ def oldnick
+ return @target
+ end
+
+ def newnick
+ return @message
end
end
class QuitMessage < BasicUserMessage
- def initialize(bot, source, target, message="")
- super(bot, source, target, message)
+ def initialize(bot, server, source, target, message="")
+ super(bot, server, source, target, message)
end
end
@@ -233,10 +334,10 @@ module Irc
# topic set on channel
attr_reader :channel
- def initialize(bot, source, channel, timestamp, topic="")
- super(bot, source, channel, topic)
+ def initialize(bot, server, source, channel, topic=ChannelTopic.new)
+ super(bot, server, source, channel, topic.text)
@topic = topic
- @timestamp = timestamp
+ @timestamp = topic.set_on
@channel = channel
end
end
@@ -245,14 +346,14 @@ module Irc
class JoinMessage < BasicUserMessage
# channel joined
attr_reader :channel
- def initialize(bot, source, channel, message="")
- super(bot, source, channel, message)
+ def initialize(bot, server, source, channel, message="")
+ super(bot, server, source, channel, message)
@channel = channel
# in this case sourcenick is the nick that could be the bot
- @address = (sourcenick.downcase == @bot.nick.downcase)
+ @address = (source == @bot.myself)
end
end
-
+
# class to manage channel parts
# same as a join, but can have a message too
class PartMessage < JoinMessage