3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-27 21:19:31 +01:00

nefarious: implement NICK, QUIT, PART, KICK

This commit is contained in:
James Lu 2016-04-15 14:08:33 -07:00
parent 560aa5b1f8
commit e18c7025db

View File

@ -252,6 +252,27 @@ class P10Protocol(Protocol):
self.irc.channels[channel].users.add(client) self.irc.channels[channel].users.add(client)
self.irc.users[client].channels.add(channel) self.irc.users[client].channels.add(channel)
def kick(self, numeric, channel, target, reason=None):
"""Sends kicks from a PyLink client/server."""
if (not self.irc.isInternalClient(numeric)) and \
(not self.irc.isInternalServer(numeric)):
raise LookupError('No such PyLink client/server exists.')
channel = utils.toLower(self.irc, channel)
if not reason:
reason = 'No reason given'
# Mangle kick targets for IRCds that require it.
target = self._getOutgoingNick(target)
self._send(numeric, 'K %s %s :%s' % (channel, target, reason))
# We can pretend the target left by its own will; all we really care about
# is that the target gets removed from the channel userlist, and calling
# handle_part() does that just fine.
self.handle_part(target, 'KICK', [channel])
def message(self, numeric, target, text): def message(self, numeric, target, text):
"""Sends a PRIVMSG from a PyLink client.""" """Sends a PRIVMSG from a PyLink client."""
if not self.irc.isInternalClient(numeric): if not self.irc.isInternalClient(numeric):
@ -288,6 +309,15 @@ class P10Protocol(Protocol):
modes = modes[12:] modes = modes[12:]
self._send(numeric, 'M %s %s%s' % (target, joinedmodes, ' %s' % ts if send_ts else '')) self._send(numeric, 'M %s %s%s' % (target, joinedmodes, ' %s' % ts if send_ts else ''))
def nick(self, numeric, newnick):
"""Changes the nick of a PyLink client."""
# <- ABAAA N GL_ 1460753763
if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink client exists.')
self._send(numeric, 'NICK %s %s' % (newnick, int(time.time())))
self.irc.users[numeric].nick = newnick
def notice(self, numeric, target, text): def notice(self, numeric, target, text):
"""Sends a NOTICE from a PyLink client.""" """Sends a NOTICE from a PyLink client."""
if not self.irc.isInternalClient(numeric): if not self.irc.isInternalClient(numeric):
@ -295,6 +325,19 @@ class P10Protocol(Protocol):
self._send(numeric, 'O %s :%s' % (target, text)) self._send(numeric, 'O %s :%s' % (target, text))
def part(self, client, channel, reason=None):
"""Sends a part from a PyLink client."""
channel = utils.toLower(self.irc, channel)
if not self.irc.isInternalClient(client):
raise LookupError('No such PyLink client exists.')
msg = "L %s" % channel
if reason:
msg += " :%s" % reason
self._send(client, msg)
self.handle_part(client, 'PART', [channel])
def ping(self, source=None, target=None): def ping(self, source=None, target=None):
"""Sends a PING to a target server. Periodic PINGs are sent to our uplink """Sends a PING to a target server. Periodic PINGs are sent to our uplink
automatically by the Irc() internals; plugins shouldn't have to use this.""" automatically by the Irc() internals; plugins shouldn't have to use this."""
@ -306,6 +349,14 @@ class P10Protocol(Protocol):
else: else:
self._send(source, 'G %s' % source) self._send(source, 'G %s' % source)
def quit(self, numeric, reason):
"""Quits a PyLink client."""
if self.irc.isInternalClient(numeric):
self._send(numeric, "Q :%s" % reason)
self.removeClient(numeric)
else:
raise LookupError("No such PyLink client exists.")
### HANDLERS ### HANDLERS
def connect(self): def connect(self):
@ -475,6 +526,14 @@ class P10Protocol(Protocol):
#if accountname != "*": #if accountname != "*":
# self.irc.callHooks([uid, 'CLIENT_SERVICES_LOGIN', {'text': accountname}]) # self.irc.callHooks([uid, 'CLIENT_SERVICES_LOGIN', {'text': accountname}])
return {'uid': uid, 'ts': ts, 'nick': nick, 'realhost': realhost, 'host': host, 'ident': ident, 'ip': ip}
else:
# <- ABAAA N GL_ 1460753763
oldnick = self.irc.users[numeric].nick
newnick = self.irc.users[numeric].nick = args[0]
return {'newnick': newnick, 'oldnick': oldnick, 'ts': int(args[1])}
def handle_ping(self, source, command, args): def handle_ping(self, source, command, args):
"""Handles incoming PING requests.""" """Handles incoming PING requests."""
# Snippet from Jobe @ evilnet, thanks! AFAIK, the P10 docs are out of date and don't # Snippet from Jobe @ evilnet, thanks! AFAIK, the P10 docs are out of date and don't
@ -652,4 +711,45 @@ class P10Protocol(Protocol):
# OPMODE is like SAMODE on other IRCds, and it follows the same modesetting syntax. # OPMODE is like SAMODE on other IRCds, and it follows the same modesetting syntax.
handle_opmode = handle_mode handle_opmode = handle_mode
def handle_part(self, source, command, args):
"""Handles user parts."""
# <- ABAAA L #test,#test2
# <- ABAAA L #test :test
channels = utils.toLower(self.irc, args[0]).split(',')
for channel in channels:
# We should only get PART commands for channels that exist, right??
self.irc.channels[channel].removeuser(source)
try:
self.irc.users[source].channels.discard(channel)
except KeyError:
log.debug("(%s) handle_part: KeyError trying to remove %r from %r's channel list?",
self.irc.name, channel, source)
try:
reason = args[1]
except IndexError:
reason = ''
# Clear empty non-permanent channels.
if not self.irc.channels[channel].users:
del self.irc.channels[channel]
return {'channels': channels, 'text': reason}
def handle_kick(self, source, command, args):
"""Handles incoming KICKs."""
# <- ABAAA K #TEST AyAAA :PyLink-devel
channel = utils.toLower(self.irc, args[0])
kicked = args[1]
self.handle_part(kicked, 'KICK', [channel, args[2]])
return {'channel': channel, 'target': kicked, 'text': args[2]}
def handle_quit(self, numeric, command, args):
"""Handles incoming QUIT commands."""
# <- ABAAB Q :Killed (GL_ (bangbang))
self.removeClient(numeric)
return {'text': args[0]}
Class = P10Protocol Class = P10Protocol