]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/nickserv.rb
Improve debugging output in messagemapper
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / nickserv.rb
1 # Automatically lookup nicks in @registry and identify when asked
2 # Takes over proper nick if required and nick is registered
3 # TODO allow custom IDENTIFY and GHOST names
4 # TODO instead of nickserv.wait it would be ideal if we could just
5 # set up "don't send further commands until you receive this particular message"
6
7 class NickServPlugin < Plugin
8   
9   BotConfig.register BotConfigStringValue.new('nickserv.name',
10     :default => "nickserv", :requires_restart => false,
11     :desc => "Name of the nick server (all lowercase)")
12   BotConfig.register BotConfigStringValue.new('nickserv.ident_request',
13     :default => "IDENTIFY", :requires_restart => false,
14     :on_change => Proc.new { |bot, v| bot.plugins.delegate "set_ident_request", v },
15     :desc => "String to look for to see if the nick server is asking us to identify")
16   BotConfig.register BotConfigBooleanValue.new('nickserv.wants_nick',
17     :default => true, :requires_restart => false,
18     :desc => "Set to false if the nick server doesn't expect the nick as a parameter in the identify command")
19   BotConfig.register BotConfigIntegerValue.new('nickserv.wait',
20     :default => 30, :validate => Proc.new { |v| v > 0 }, :requires_restart => false,
21     :desc => "Seconds to wait after sending a message to nickserv, e.g. after ghosting")
22
23   def help(plugin, topic="")
24     case topic
25     when ""
26       return "nickserv plugin: handles nickserv protected IRC nicks. topics password, register, identify, listnicks"
27     when "password"
28       return "nickserv password <nick> <passwd>: remember the password for nick <nick> and use it to identify in future"
29     when "register"
30       return "nickserv register [<password> [<email>]]: register the current nick, choosing a random password unless <password> is supplied - current nick must not already be registered for this to work. Also specify email if required by your services"
31     when "identify"
32       return "nickserv identify: identify with nickserv - shouldn't be needed - bot should identify with nickserv immediately on request - however this could be useful after splits or service disruptions, or when you just set the password for the current nick"
33     when "listnicks"
34       return "nickserv listnicks: lists nicknames and associated password the bot knows about - you will need config level auth access to do this one and it will reply by privmsg only"
35     end
36   end
37   
38   def genpasswd
39     # generate a random password
40     passwd = ""
41     8.times do
42       passwd += (rand(26) + (rand(2) == 0 ? 65 : 97) ).chr
43     end
44     return passwd
45   end
46
47   def set_ident_request(val)
48     @ident_request = Regexp.new(val)
49   end
50
51   def initialize
52     super
53     # this plugin only wants to store strings!
54     class << @registry
55       def store(val)
56         val
57       end
58       def restore(val)
59         val
60       end
61     end
62     set_ident_request(@bot.config['nickserv.ident_request'])
63   end
64
65   def password(m, params)
66     nick = params[:nick] || @bot.nick
67     passwd = params[:passwd]
68     if nick == @bot.nick
69       @bot.say @bot.config['nickserv.name'], "SET PASSWORD #{passwd}"
70     else
71       m.reply "I'm only changing this in my database, I won't inform #{@bot.config['nickserv.name']} of the change"
72     end
73     @registry[nick] = passwd
74     m.okay
75   end
76
77   def nick_register(m, params)
78     passwd = params[:passwd] ? params[:passwd] : genpasswd
79     message = "REGISTER #{passwd}"
80     message += " #{params[:email]}" if params[:email]
81     @bot.sendmsg "PRIVMSG", @bot.config['nickserv.name'], message
82     @registry[@bot.nick] = passwd
83     m.okay
84   end
85
86   def listnicks(m, params)
87     if @registry.length > 0
88       @registry.each {|k,v|
89         @bot.say m.sourcenick, "#{k} => #{v}"
90       }
91     else
92       m.reply "none known"
93     end
94   end
95
96   def do_identify(nick=@bot.nick)
97     if @registry.has_key?(nick)
98       if @bot.config['nickserv.wants_nick']
99         @bot.sendmsg "PRIVMSG", @bot.config['nickserv.name'], "IDENTIFY #{nick} #{@registry[nick]}"
100       else
101         if nick == @bot.nick
102           @bot.sendmsg "PRIVMSG", @bot.config['nickserv.name'], "IDENTIFY #{@registry[nick]}"
103         else
104           # We cannot identify for different nicks if we can't use the nickname ...
105           return false
106         end
107       end
108       return true
109     end
110     return false
111   end
112
113   def identify(m, params)
114     if do_identify
115       m.okay
116     else
117       m.reply "I dunno the nickserv password for the nickname #{@bot.nick} :("
118     end
119   end
120   
121   def connect
122     do_identify
123   end
124   
125   def nicktaken(nick)
126     if @registry.has_key?(nick)
127       @bot.sendmsg "PRIVMSG", @bot.config['nickserv.name'], "GHOST #{nick} #{@registry[nick]}"
128       if do_identify nick
129         sleep @bot.config['nickserv.wait']
130         @bot.nickchg nick
131         # We need to wait after changing nick, otherwise the server
132         # might refuse to execute further commangs, e.g. subsequent JOIN
133         # commands until the nick has changed.
134         sleep @bot.config['nickserv.wait']
135       else
136         debug "Failed to identify for nick #{nick}, cannot take over"
137       end
138     end
139   end
140
141   def listen(m)
142     return unless(m.kind_of? NoticeMessage)
143
144     if (m.sourcenick == @bot.config['nickserv.name'] && m.message =~ @ident_request)
145       debug "nickserv asked us to identify for nick #{@bot.nick}"
146       do_identify
147     end
148   end
149
150 end
151 plugin = NickServPlugin.new
152 plugin.map 'nickserv password [:nick] :passwd', :action => "password"
153 plugin.map 'nickserv register :passwd :email', :action => 'nick_register',
154            :defaults => {:passwd => false, :email => false}
155 plugin.map 'nickserv listnicks', :action => "listnicks"
156 plugin.map 'nickserv identify', :action => "identify"
157
158 plugin.default_auth('*', false)
159