Properly handle the bot's nick being already in use

This commit is contained in:
Vgr E. Barry 2016-11-16 16:18:27 -05:00
parent d62b9db896
commit 885889495a
3 changed files with 51 additions and 30 deletions

View File

@ -179,7 +179,7 @@ class IRCClient:
if not self.blocking:
self.socket.setblocking(0)
self.cap("LS 302")
self.send("CAP LS 302")
if self.server_pass and (not self.sasl_auth or "{password}" not in self.server_pass):
message = "PASS :{0}".format(self.server_pass).format(
@ -187,7 +187,7 @@ class IRCClient:
password=self.password)
self.send(message)
self.nick(self.nickname)
self.send("NICK", self.nickname)
self.user(self.ident, self.real_name)
if self.connect_cb:
@ -272,24 +272,20 @@ class IRCClient:
self.send("MODE {0}".format(" ".join(args)))
def kick(self, chan, nick, msg=""):
self.send("KICK", chan, nick, ":"+msg)
def nick(self, nick):
self.send("NICK {0}".format(nick))
def who(self, *args):
self.send("WHO {0}".format(" ".join(args)))
def cap(self, req):
self.send("CAP {0}".format(req))
def ns_identify(self, account, passwd, nickserv, command):
if command:
self.msg(nickserv, command.format(account=account, password=passwd))
def ns_ghost(self, nickserv, command):
def ns_ghost(self, nick, password, nickserv, command):
if command:
self.msg(nickserv, command.format(nick=self.nickname))
def ns_release(self, nickserv="NickServ", command="RELEASE {nick}"):
self.msg(nickserv, command.format(nick=nick, password=password))
def ns_release(self, nick, password, nickserv="NickServ", command="RELEASE {nick}"):
if command:
self.msg(nickserv, command.format(nick=self.nickname))
def ns_regain(self, nickserv="NickServ", command="REGAIN {nick}"):
self.msg(nickserv, command.format(nick=nick, password=password))
def ns_regain(self, nick, password, nickserv="NickServ", command="REGAIN {nick}"):
if command:
self.msg(nickserv, command.format(nick=self.nickname))
self.msg(nickserv, command.format(nick=nick, password=password))
def user(self, ident, rname):
self.send("USER", ident, self.host, self.host, ":{0}".format(rname or ident))
def mainLoop(self):

View File

@ -56,9 +56,6 @@ def connect_callback(cli):
# This callback only sets up event listeners
wolfgame.connect_callback()
users.Bot = users.User(cli, botconfig.NICK, None, None, None, None)
users.Bot.modes = set() # only for the bot (user modes)
# just in case we haven't managed to successfully auth yet
if not botconfig.SASL_AUTHENTICATION:
cli.ns_identify(botconfig.USERNAME or botconfig.NICK,
@ -82,24 +79,29 @@ def connect_callback(cli):
#if var.CHANSERV_OP_COMMAND: # TODO: Add somewhere else if needed
# cli.msg(var.CHANSERV, var.CHANSERV_OP_COMMAND.format(channel=botconfig.CHANNEL))
cli.nick(botconfig.NICK) # very important (for regain/release)
users.Bot.change_nick(botconfig.NICK)
def mustregain(cli, *blah):
if not botconfig.PASS:
def mustregain(cli, server, bot_nick, nick, msg):
if not botconfig.PASS or bot_nick == nick:
return
cli.ns_regain(nickserv=var.NICKSERV, command=var.NICKSERV_REGAIN_COMMAND)
cli.ns_regain(nick=botconfig.NICK, password=botconfig.PASS, nickserv=var.NICKSERV, command=var.NICKSERV_REGAIN_COMMAND)
users.Bot.change_nick(botconfig.NICK)
def mustrelease(cli, *rest):
if not botconfig.PASS:
def mustrelease(cli, server, bot_nick, nick, msg):
if not botconfig.PASS or bot_nick == nick:
return # prevents the bot from trying to release without a password
cli.ns_release(nickserv=var.NICKSERV, command=var.NICKSERV_RELEASE_COMMAND)
cli.nick(botconfig.NICK)
func = cli.ns_release
if getattr(botconfig, "USE_NICKSERV_GHOST", False): # FIXME
func = cli.ns_ghost
func(nick=botconfig.NICK, password=botconfig.PASS, nickserv=var.NICKSERV, command=var.NICKSERV_RELEASE_COMMAND)
users.Bot.change_nick(botconfig.NICK)
@hook("unavailresource", hookid=239)
@hook("nicknameinuse", hookid=239)
def must_use_temp_nick(cli, *etc):
cli.nick(botconfig.NICK+"_")
cli.user(botconfig.NICK, "")
users.Bot.nick += "_"
users.Bot.change_nick()
cli.user(botconfig.NICK, "") # TODO: can we remove this?
hook.unhook(239)
hook("unavailresource")(mustrelease)
@ -112,7 +114,6 @@ def connect_callback(cli):
supported_caps = set()
@hook("cap")
def on_cap(cli, svr, mynick, cmd, caps, star=None):
if cmd == "LS":
@ -129,12 +130,12 @@ def connect_callback(cli):
common_caps = request_caps & supported_caps
if common_caps:
cli.cap("REQ " ":{0}".format(" ".join(common_caps)))
cli.send("CAP REQ " ":{0}".format(" ".join(common_caps)))
elif cmd == "ACK":
if "sasl" in caps:
cli.send("AUTHENTICATE PLAIN")
else:
cli.cap("END")
cli.send("CAP END")
elif cmd == "NAK":
# This isn't supposed to happen. The server claimed to support a
# capability but now claims otherwise.
@ -151,7 +152,7 @@ def connect_callback(cli):
@hook("903")
def on_successful_auth(cli, blah, blahh, blahhh):
cli.cap("END")
cli.send("CAP END")
@hook("904")
@hook("905")
@ -162,4 +163,6 @@ def connect_callback(cli):
"in botconfig.USERNAME if it's different from the bot nick?")
cli.quit()
users.Bot = users.BotUser(cli, botconfig.NICK)
# vim: set sw=4 expandtab:

View File

@ -173,7 +173,7 @@ class User(IRCContext):
def __new__(cls, cli, nick, ident, host, realname, account, **kwargs):
self = super().__new__(cls)
super(cls, self).__init__(nick, cli, **kwargs)
super(User, self).__init__(nick, cli, **kwargs)
self._ident = ident
self._host = host
@ -523,3 +523,25 @@ class FakeUser(User):
@rawnick.setter
def rawnick(self, rawnick):
self.nick = parse_rawnick_as_dict(rawnick)["nick"]
class BotUser(User): # TODO: change all the 'if x is Bot' for 'if isinstance(x, BotUser)'
def __new__(cls, cli, nick):
self = super().__new__(cls, cli, nick, None, None, None, None)
self.modes = set()
return self
def change_nick(self, nick=None):
if nick is None:
nick = self.nick
self.client.send("NICK", nick)