mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-25 04:02:45 +01:00
Merge branch 'wip/protocol-cleanup' into devel
This commit is contained in:
commit
a32d937b91
@ -6,14 +6,103 @@ import time
|
||||
|
||||
from pylinkirc.classes import Protocol
|
||||
from pylinkirc.log import log
|
||||
from pylinkirc import utils
|
||||
|
||||
class IRCS2SProtocol(Protocol):
|
||||
COMMAND_TOKENS = {}
|
||||
|
||||
def __init__(self, irc):
|
||||
super().__init__(irc)
|
||||
self.protocol_caps = {'can-spawn-clients', 'has-ts', 'can-host-relay',
|
||||
'can-track-servers'}
|
||||
|
||||
def handle_events(self, data):
|
||||
"""Event handler for RFC1459-like protocols.
|
||||
|
||||
This passes most commands to the various handle_ABCD() functions
|
||||
elsewhere defined protocol modules, coersing various sender prefixes
|
||||
from nicks and server names to UIDs and SIDs respectively,
|
||||
whenever possible.
|
||||
|
||||
Commands sent without an explicit sender prefix will have them set to
|
||||
the SID of the uplink server.
|
||||
"""
|
||||
data = data.split(" ")
|
||||
args = self.parseArgs(data)
|
||||
|
||||
sender = args[0]
|
||||
sender = sender.lstrip(':')
|
||||
|
||||
# If the sender isn't in numeric format, try to convert it automatically.
|
||||
sender_sid = self._getSid(sender)
|
||||
sender_uid = self._getUid(sender)
|
||||
|
||||
if sender_sid in self.irc.servers:
|
||||
# Sender is a server (converting from name to SID gave a valid result).
|
||||
sender = sender_sid
|
||||
elif sender_uid in self.irc.users:
|
||||
# Sender is a user (converting from name to UID gave a valid result).
|
||||
sender = sender_uid
|
||||
else:
|
||||
# No sender prefix; treat as coming from uplink IRCd.
|
||||
sender = self.irc.uplink
|
||||
args.insert(0, sender)
|
||||
|
||||
if self.irc.isInternalClient(sender) or self.irc.isInternalServer(sender):
|
||||
log.warning("(%s) Received command %s being routed the wrong way!", self.irc.name, command)
|
||||
return
|
||||
|
||||
raw_command = args[1].upper()
|
||||
args = args[2:]
|
||||
|
||||
log.debug('(%s) Found message sender as %s', self.irc.name, sender)
|
||||
|
||||
# For P10, convert the command token into a regular command, if present.
|
||||
command = self.COMMAND_TOKENS.get(raw_command, raw_command)
|
||||
if command != raw_command:
|
||||
log.debug('(%s) Translating token %s to command %s', self.irc.name, raw_command, command)
|
||||
|
||||
if command == 'ENCAP':
|
||||
# Special case for TS6 encapsulated commands (ENCAP), in forms like this:
|
||||
# <- :00A ENCAP * SU 42XAAAAAC :GLolol
|
||||
command = args[1]
|
||||
args = args[2:]
|
||||
log.debug("(%s) Rewriting incoming ENCAP to command %s (args: %s)", self.irc.name, command, args)
|
||||
|
||||
try:
|
||||
func = getattr(self, 'handle_'+command.lower())
|
||||
except AttributeError: # Unhandled command
|
||||
pass
|
||||
else:
|
||||
parsed_args = func(sender, command, args)
|
||||
if parsed_args is not None:
|
||||
return [sender, command, parsed_args]
|
||||
|
||||
def handle_privmsg(self, source, command, args):
|
||||
"""Handles incoming PRIVMSG/NOTICE."""
|
||||
# TS6:
|
||||
# <- :70MAAAAAA PRIVMSG #dev :afasfsa
|
||||
# <- :70MAAAAAA NOTICE 0ALAAAAAA :afasfsa
|
||||
# P10:
|
||||
# <- ABAAA P AyAAA :privmsg text
|
||||
# <- ABAAA O AyAAA :notice text
|
||||
target = args[0]
|
||||
|
||||
# Coerse =#channel from Charybdis op moderated +z to @#channel.
|
||||
if target.startswith('='):
|
||||
target = '@' + target[1:]
|
||||
|
||||
# We use lowercase channels internally, but uppercase UIDs.
|
||||
# Strip the target of leading prefix modes (for targets like @#channel)
|
||||
# before checking whether it's actually a channel.
|
||||
stripped_target = target.lstrip(''.join(self.irc.prefixmodes.values()))
|
||||
if utils.isChannel(stripped_target):
|
||||
target = self.irc.toLower(target)
|
||||
|
||||
return {'target': target, 'text': args[1]}
|
||||
|
||||
handle_notice = handle_privmsg
|
||||
|
||||
def check_nick_collision(self, nick):
|
||||
"""
|
||||
Nick collision checker.
|
||||
|
@ -824,63 +824,6 @@ class P10Protocol(IRCS2SProtocol):
|
||||
self._send(sid, "EB")
|
||||
self.irc.connected.set()
|
||||
|
||||
def handle_events(self, data):
|
||||
"""
|
||||
Event handler for the P10 protocol.
|
||||
|
||||
This passes most commands to the various handle_ABCD() functions defined elsewhere in the
|
||||
protocol modules, coersing various sender prefixes from nicks and server names to P10
|
||||
"numeric nicks", whenever possible.
|
||||
|
||||
Commands sent without an explicit sender prefix are treated as originating from the uplink
|
||||
server.
|
||||
"""
|
||||
data = data.split(" ")
|
||||
args = self.parseArgs(data)
|
||||
|
||||
sender = args[0]
|
||||
if sender.startswith(':'):
|
||||
# From https://github.com/evilnet/nefarious2/blob/a29b63144/doc/p10.txt#L140:
|
||||
# if source begins with a colon, it (except for the colon) is the name. otherwise, it is
|
||||
# a numeric. a P10 implementation must only send lines with a numeric source prefix.
|
||||
sender = sender[1:]
|
||||
|
||||
# If the sender isn't in numeric format, try to convert it automatically.
|
||||
sender_sid = self._getSid(sender)
|
||||
sender_uid = self._getUid(sender)
|
||||
if sender_sid in self.irc.servers:
|
||||
# Sender is a server (converting from name to SID gave a valid result).
|
||||
sender = sender_sid
|
||||
elif sender_uid in self.irc.users:
|
||||
# Sender is a user (converting from name to UID gave a valid result).
|
||||
sender = sender_uid
|
||||
else:
|
||||
# No sender prefix; treat as coming from uplink IRCd.
|
||||
sender = self.irc.uplink
|
||||
args.insert(0, sender)
|
||||
|
||||
command_token = args[1].upper()
|
||||
args = args[2:]
|
||||
|
||||
log.debug('(%s) Found message sender as %s', self.irc.name, sender)
|
||||
# Convert the token given into a regular command, if present.
|
||||
command = self.COMMAND_TOKENS.get(command_token, command_token)
|
||||
log.debug('(%s) Translating token %s to command %s', self.irc.name, command_token, command)
|
||||
|
||||
try:
|
||||
func = getattr(self, 'handle_'+command.lower())
|
||||
except AttributeError: # Unhandled command, ignore
|
||||
return
|
||||
|
||||
else: # Send a hook with the hook arguments given by the handler function.
|
||||
if self.irc.isInternalClient(sender) or self.irc.isInternalServer(sender):
|
||||
log.warning("(%s) Received command %s being routed the wrong way!", self.irc.name, command)
|
||||
return
|
||||
|
||||
parsed_args = func(sender, command, args)
|
||||
if parsed_args is not None:
|
||||
return [sender, command, parsed_args]
|
||||
|
||||
def handle_server(self, source, command, args):
|
||||
"""Handles incoming server introductions."""
|
||||
# <- SERVER nefarious.midnight.vpn 1 1460673022 1460673239 J10 ABP]] +h6 :Nefarious2 test server
|
||||
@ -1168,22 +1111,6 @@ class P10Protocol(IRCS2SProtocol):
|
||||
self.irc.channels[channel].modes, 'ts': ts or int(time.time())}
|
||||
|
||||
handle_create = handle_join
|
||||
|
||||
def handle_privmsg(self, source, command, args):
|
||||
"""Handles incoming PRIVMSG/NOTICE."""
|
||||
# <- ABAAA P AyAAA :privmsg text
|
||||
# <- ABAAA O AyAAA :notice text
|
||||
target = args[0]
|
||||
|
||||
# We use lower case channels internally, but mixed case UIDs.
|
||||
stripped_target = target.lstrip(''.join(self.irc.prefixmodes.values()))
|
||||
if utils.isChannel(stripped_target):
|
||||
target = self.irc.toLower(target)
|
||||
|
||||
return {'target': target, 'text': args[1]}
|
||||
|
||||
handle_notice = handle_privmsg
|
||||
|
||||
def handle_end_of_burst(self, source, command, args):
|
||||
"""Handles end of burst from our uplink."""
|
||||
# Send EOB acknowledgement; this is required by the P10 specification,
|
||||
|
@ -294,83 +294,6 @@ class TS6BaseProtocol(IRCS2SProtocol):
|
||||
self.irc.users[source].away = text
|
||||
|
||||
### HANDLERS
|
||||
|
||||
def handle_events(self, data):
|
||||
"""Event handler for TS6 protocols.
|
||||
|
||||
This passes most commands to the various handle_ABCD() functions
|
||||
elsewhere defined protocol modules, coersing various sender prefixes
|
||||
from nicks and server names to UIDs and SIDs respectively,
|
||||
whenever possible.
|
||||
|
||||
Commands sent without an explicit sender prefix will have them set to
|
||||
the SID of the uplink server.
|
||||
"""
|
||||
data = data.split(" ")
|
||||
try: # Message starts with a SID/UID prefix.
|
||||
args = self.parsePrefixedArgs(data)
|
||||
sender = args[0]
|
||||
command = args[1]
|
||||
args = args[2:]
|
||||
# If the sender isn't in UID format, try to convert it automatically.
|
||||
# Unreal's protocol, for example, isn't quite consistent with this yet!
|
||||
sender_server = self._getSid(sender)
|
||||
if sender_server in self.irc.servers:
|
||||
# Sender is a server when converted from name to SID.
|
||||
numeric = sender_server
|
||||
else:
|
||||
# Sender is a user.
|
||||
numeric = self._getUid(sender)
|
||||
|
||||
# parsePrefixedArgs() will raise IndexError if the TS6 sender prefix is missing.
|
||||
except IndexError:
|
||||
# Raw command without an explicit sender; assume it's being sent by our uplink.
|
||||
args = self.parseArgs(data)
|
||||
numeric = self.irc.uplink
|
||||
command = args[0]
|
||||
args = args[1:]
|
||||
|
||||
if self.irc.isInternalClient(numeric) or self.irc.isInternalServer(numeric):
|
||||
log.warning("(%s) Received command %s being routed the wrong way!", self.irc.name, command)
|
||||
return
|
||||
|
||||
if command == 'ENCAP':
|
||||
# Special case for encapsulated commands (ENCAP), in forms like this:
|
||||
# <- :00A ENCAP * SU 42XAAAAAC :GLolol
|
||||
command = args[1]
|
||||
args = args[2:]
|
||||
log.debug("(%s) Rewriting incoming ENCAP to command %s (args: %s)", self.irc.name, command, args)
|
||||
|
||||
try:
|
||||
func = getattr(self, 'handle_'+command.lower())
|
||||
except AttributeError: # unhandled command
|
||||
pass
|
||||
else:
|
||||
parsed_args = func(numeric, command, args)
|
||||
if parsed_args is not None:
|
||||
return [numeric, command, parsed_args]
|
||||
|
||||
def handle_privmsg(self, source, command, args):
|
||||
"""Handles incoming PRIVMSG/NOTICE."""
|
||||
# <- :70MAAAAAA PRIVMSG #dev :afasfsa
|
||||
# <- :70MAAAAAA NOTICE 0ALAAAAAA :afasfsa
|
||||
target = args[0]
|
||||
|
||||
# Coerse =#channel from Charybdis op moderated +z to @#channel.
|
||||
if target.startswith('='):
|
||||
target = '@' + target[1:]
|
||||
|
||||
# We use lowercase channels internally, but uppercase UIDs.
|
||||
# Strip the target of leading prefix modes (for targets like @#channel)
|
||||
# before checking whether it's actually a channel.
|
||||
stripped_target = target.lstrip(''.join(self.irc.prefixmodes.values()))
|
||||
if utils.isChannel(stripped_target):
|
||||
target = self.irc.toLower(target)
|
||||
|
||||
return {'target': target, 'text': args[1]}
|
||||
|
||||
handle_notice = handle_privmsg
|
||||
|
||||
def handle_kick(self, source, command, args):
|
||||
"""Handles incoming KICKs."""
|
||||
# :70MAAAAAA KICK #test 70MAAAAAA :some reason
|
||||
|
Loading…
Reference in New Issue
Block a user