mirror of
				https://github.com/jlu5/PyLink.git
				synced 2025-10-30 06:27:26 +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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 James Lu
						James Lu