80 | 80 |
// might change its copy.
|
81 | 81 |
Nick string
|
82 | 82 |
NickPassword string
|
83 | |
Client *irc.Conn
|
84 | |
AlertMsgs chan AlertMsg
|
|
83 |
|
|
84 |
NickservIdentifyPatterns []string
|
|
85 |
|
|
86 |
Client *irc.Conn
|
|
87 |
AlertMsgs chan AlertMsg
|
85 | 88 |
|
86 | 89 |
// irc.Conn has a Connected() method that can tell us wether the TCP
|
87 | 90 |
// connection is up, and thus if we should trigger connect/disconnect.
|
|
115 | 118 |
channelReconciler := NewChannelReconciler(config, client, delayerMaker, timeTeller)
|
116 | 119 |
|
117 | 120 |
notifier := &IRCNotifier{
|
118 | |
Nick: config.IRCNick,
|
119 | |
NickPassword: config.IRCNickPass,
|
120 | |
Client: client,
|
121 | |
AlertMsgs: alertMsgs,
|
122 | |
sessionUpSignal: make(chan bool),
|
123 | |
sessionDownSignal: make(chan bool),
|
124 | |
channelReconciler: channelReconciler,
|
125 | |
UsePrivmsg: config.UsePrivmsg,
|
126 | |
NickservDelayWait: nickservWaitSecs * time.Second,
|
127 | |
BackoffCounter: backoffCounter,
|
128 | |
timeTeller: timeTeller,
|
|
121 |
Nick: config.IRCNick,
|
|
122 |
NickPassword: config.IRCNickPass,
|
|
123 |
NickservIdentifyPatterns: config.NickservIdentifyPatterns,
|
|
124 |
Client: client,
|
|
125 |
AlertMsgs: alertMsgs,
|
|
126 |
sessionUpSignal: make(chan bool),
|
|
127 |
sessionDownSignal: make(chan bool),
|
|
128 |
channelReconciler: channelReconciler,
|
|
129 |
UsePrivmsg: config.UsePrivmsg,
|
|
130 |
NickservDelayWait: nickservWaitSecs * time.Second,
|
|
131 |
BackoffCounter: backoffCounter,
|
|
132 |
timeTeller: timeTeller,
|
129 | 133 |
}
|
130 | 134 |
|
131 | 135 |
notifier.registerHandlers()
|
|
146 | 150 |
n.sessionDownSignal <- false
|
147 | 151 |
})
|
148 | 152 |
|
149 | |
for _, event := range []string{irc.NOTICE, "433"} {
|
|
153 |
n.Client.HandleFunc(irc.NOTICE,
|
|
154 |
func(_ *irc.Conn, line *irc.Line) {
|
|
155 |
n.HandleNotice(line.Nick, line.Text())
|
|
156 |
})
|
|
157 |
|
|
158 |
for _, event := range []string{"433"} {
|
150 | 159 |
n.Client.HandleFunc(event, loggerHandler)
|
151 | 160 |
}
|
152 | 161 |
}
|
153 | 162 |
|
154 | |
func (n *IRCNotifier) MaybeIdentifyNick() {
|
|
163 |
func (n *IRCNotifier) HandleNotice(nick string, msg string) {
|
|
164 |
logging.Info("Received NOTICE from %s: %s", nick, msg)
|
|
165 |
if strings.ToLower(nick) == "nickserv" {
|
|
166 |
n.HandleNickservMsg(msg)
|
|
167 |
}
|
|
168 |
}
|
|
169 |
|
|
170 |
func (n *IRCNotifier) HandleNickservMsg(msg string) {
|
155 | 171 |
if n.NickPassword == "" {
|
156 | |
return
|
157 | |
}
|
158 | |
|
159 | |
// Very lazy/optimistic, but this is good enough for my irssi config,
|
160 | |
// so it should work here as well.
|
|
172 |
logging.Debug("Skip processing NickServ request, no password configured")
|
|
173 |
return
|
|
174 |
}
|
|
175 |
|
|
176 |
// Remove most common formatting options from NickServ messages
|
|
177 |
cleaner := strings.NewReplacer(
|
|
178 |
"\001", "", // bold
|
|
179 |
"\002", "", // faint
|
|
180 |
"\004", "", // underline
|
|
181 |
)
|
|
182 |
cleanedMsg := cleaner.Replace(msg)
|
|
183 |
|
|
184 |
for _, identifyPattern := range n.NickservIdentifyPatterns {
|
|
185 |
logging.Debug("Checking if NickServ message matches identify request '%s'", identifyPattern)
|
|
186 |
if strings.Contains(cleanedMsg, identifyPattern) {
|
|
187 |
logging.Info("Handling NickServ request to IDENTIFY")
|
|
188 |
n.Client.Privmsgf("NickServ", "IDENTIFY %s", n.NickPassword)
|
|
189 |
return
|
|
190 |
}
|
|
191 |
}
|
|
192 |
}
|
|
193 |
|
|
194 |
func (n *IRCNotifier) MaybeGhostNick() {
|
|
195 |
if n.NickPassword == "" {
|
|
196 |
logging.Debug("Skip GHOST check, no password configured")
|
|
197 |
return
|
|
198 |
}
|
|
199 |
|
161 | 200 |
currentNick := n.Client.Me().Nick
|
162 | 201 |
if currentNick != n.Nick {
|
163 | 202 |
logging.Info("My nick is '%s', sending GHOST to NickServ to get '%s'",
|
|
168 | 207 |
|
169 | 208 |
logging.Info("Changing nick to '%s'", n.Nick)
|
170 | 209 |
n.Client.Nick(n.Nick)
|
171 | |
}
|
172 | |
logging.Info("Sending IDENTIFY to NickServ")
|
173 | |
n.Client.Privmsgf("NickServ", "IDENTIFY %s", n.NickPassword)
|
|
210 |
time.Sleep(n.NickservDelayWait)
|
|
211 |
}
|
|
212 |
}
|
|
213 |
|
|
214 |
func (n *IRCNotifier) MaybeWaitForNickserv() {
|
|
215 |
if n.NickPassword == "" {
|
|
216 |
logging.Debug("Skip NickServ wait, no password configured")
|
|
217 |
return
|
|
218 |
}
|
|
219 |
|
|
220 |
// Very lazy/optimistic, but this is good enough for my irssi config,
|
|
221 |
// so it should work here as well.
|
|
222 |
logging.Info("Waiting for NickServ to notice us and issue an identify request")
|
174 | 223 |
time.Sleep(n.NickservDelayWait)
|
175 | 224 |
}
|
176 | 225 |
|
|
260 | 309 |
case <-n.sessionUpSignal:
|
261 | 310 |
n.sessionUp = true
|
262 | 311 |
n.sessionWg.Add(1)
|
263 | |
n.MaybeIdentifyNick()
|
|
312 |
n.MaybeGhostNick()
|
|
313 |
n.MaybeWaitForNickserv()
|
264 | 314 |
n.channelReconciler.Start(ctx)
|
265 | 315 |
ircConnectedGauge.Set(1)
|
266 | 316 |
case <-n.sessionDownSignal:
|