def handle_join(self, numeric, command, args): """Handles incoming channel JOINs.""" # parameters: channelTS, channel, '+' (a plus sign) ts = int(args[0]) if args[0] == '0': # /join 0; part the user from all channels oldchans = self.irc.users[numeric].channels.copy() log.debug('(%s) Got /join 0 from %r, channel list is %r', self.irc.name, numeric, oldchans) for channel in oldchans: self.irc.channels[channel].users.discard(numeric) self.irc.users[numeric].channels.discard(channel) return { 'channels': oldchans, 'text': 'Left all channels.', 'parse_as': 'PART' } else: channel = utils.toLower(self.irc, args[1]) self.updateTS(channel, ts) # We send users and modes here because SJOIN and JOIN both use one hook, # for simplicity's sake (with plugins). return { 'channel': channel, 'users': [numeric], 'modes': self.irc.channels[channel].modes, 'ts': ts }
def handle_invite(self, numeric, command, args): """Handles incoming INVITEs.""" # <- :70MAAAAAC INVITE 0ALAAAAAA #blah 0 target = args[0] channel = utils.toLower(self.irc, args[1]) # We don't actually need to process this; just send the hook so plugins can use it return {'target': target, 'channel': channel}
def handle_fjoin(self, servernumeric, command, args): """Handles incoming FJOIN commands (InspIRCd equivalent of JOIN/SJOIN).""" # :70M FJOIN #chat 1423790411 +AFPfjnt 6:5 7:5 9:5 :o,1SRAABIT4 v,1IOAAF53R <...> channel = utils.toLower(self.irc, args[0]) # InspIRCd sends each channel's users in the form of 'modeprefix(es),UID' userlist = args[-1].split() their_ts = int(args[1]) our_ts = self.irc.channels[channel].ts self.updateTS(channel, their_ts) modestring = args[2:-1] or args[2] parsedmodes = utils.parseModes(self.irc, channel, modestring) utils.applyModes(self.irc, channel, parsedmodes) namelist = [] for user in userlist: modeprefix, user = user.split(',', 1) namelist.append(user) self.irc.users[user].channels.add(channel) if their_ts <= our_ts: utils.applyModes(self.irc, channel, [('+%s' % mode, user) for mode in modeprefix]) self.irc.channels[channel].users.add(user) return { 'channel': channel, 'users': namelist, 'modes': parsedmodes, 'ts': their_ts }
def sjoinServer(self, server, channel, users, ts=None): """Sends an SJOIN for a group of users to a channel. The sender should always be a server (SID). TS is optional, and defaults to the one we've stored in the channel state if not given. <users> is a list of (prefix mode, UID) pairs: Example uses: sjoinServer('100', '#test', [('', '100AAABBC'), ('o', 100AAABBB'), ('v', '100AAADDD')]) sjoinServer(self.irc.sid, '#test', [('o', self.irc.pseudoclient.uid)]) Note that for UnrealIRCd, no mode data is sent in an SJOIN command, only The channel name, TS, and user list. """ # <- :001 SJOIN 1444361345 #endlessvoid :001DJ1O02 # The nicklist consists of users joining the channel, with status prefixes for # their status ('@+', '@', '+' or ''), for example: # '@+1JJAAAAAB +2JJAAAA4C 1JJAAAADS'. channel = utils.toLower(self.irc, channel) server = server or self.irc.sid assert users, "sjoinServer: No users sent?" if not server: raise LookupError('No such PyLink server exists.') orig_ts = self.irc.channels[channel].ts ts = ts or orig_ts self.updateTS(channel, ts) changedmodes = [] uids = [] namelist = [] for userpair in users: assert len( userpair) == 2, "Incorrect format of userpair: %r" % userpair prefixes, user = userpair # Unreal uses slightly different prefixes in SJOIN. +q is * instead of ~, # and +a is ~ instead of &. # &, ", and ' are used for bursting bans. sjoin_prefixes = {'q': '*', 'a': '~', 'o': '@', 'h': '%', 'v': '+'} prefixchars = ''.join( [sjoin_prefixes.get(prefix, '') for prefix in prefixes]) if prefixchars: changedmodes + [('+%s' % prefix, user) for prefix in prefixes] namelist.append(prefixchars + user) uids.append(user) try: self.irc.users[user].channels.add(channel) except KeyError: # Not initialized yet? log.debug( "(%s) sjoinServer: KeyError trying to add %r to %r's channel list?", self.irc.name, channel, user) namelist = ' '.join(namelist) self._send( server, "SJOIN {ts} {channel} :{users}".format(ts=ts, users=namelist, channel=channel)) self.irc.channels[channel].users.update(uids) if ts <= orig_ts: # Only save our prefix modes in the channel state if our TS is lower than or equal to theirs. utils.applyModes(self.irc, channel, changedmodes)
def getTestFileToArray(): str = '' fp = utils.openFile('test.txt') for line in fp: str += line str = utils.toLower(str) return utils.extractWords(str)
def handle_mode(self, numeric, command, args): # <- :unreal.midnight.vpn MODE #endlessvoid +bb test!*@* *!*@bad.net # <- :unreal.midnight.vpn MODE #endlessvoid +q GL 1444361345 # <- :unreal.midnight.vpn MODE #endlessvoid +ntCo GL 1444361345 # <- :unreal.midnight.vpn MODE #endlessvoid +mntClfo 5 [10t]:5 GL 1444361345 # <- :GL MODE #services +v GL # This seems pretty relatively inconsistent - why do some commands have a TS at the end while others don't? # Answer: the first syntax (MODE sent by SERVER) is used for channel bursts - according to Unreal 3.2 docs, # the last argument should be interpreted as a timestamp ONLY if it is a number and the sender is a server. # Ban bursting does not give any TS, nor do normal users setting modes. SAMODE is special though, it will # send 0 as a TS argument (which should be ignored unless breaking the internal channel TS is desired). # Also, we need to get rid of that extra space following the +f argument. :| if utils.isChannel(args[0]): channel = utils.toLower(self.irc, args[0]) oldobj = self.irc.channels[channel].deepcopy() modes = list(filter(None, args[1:])) # normalize whitespace parsedmodes = utils.parseModes(self.irc, channel, modes) if parsedmodes: utils.applyModes(self.irc, channel, parsedmodes) if numeric in self.irc.servers and args[-1].isdigit(): # Sender is a server AND last arg is number. Perform TS updates. their_ts = int(args[-1]) if their_ts > 0: self.updateTS(channel, their_ts) return {'target': channel, 'modes': parsedmodes, 'oldchan': oldobj} else: log.warning("(%s) received MODE for non-channel target: %r", self.irc.name, args) raise NotImplementedError
def handle_privmsg(self, source, command, args): # Convert nicks to UIDs, where they exist. target = self._getNick(args[0]) # We use lowercase channels internally, but uppercase UIDs. if utils.isChannel(target): target = utils.toLower(self.irc, target) return {'target': target, 'text': args[1]}
def joinClient(self, client, channel): """Joins a PyLink client to a channel.""" # InspIRCd doesn't distinguish between burst joins and regular joins, # so what we're actually doing here is sending FJOIN from the server, # on behalf of the clients that are joining. channel = utils.toLower(self.irc, channel) server = utils.isInternalClient(self.irc, client) if not server: log.error( '(%s) Error trying to join client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel) raise LookupError('No such PyLink PseudoClient exists.') # Strip out list-modes, they shouldn't be ever sent in FJOIN. modes = [ m for m in self.irc.channels[channel].modes if m[0] not in self.irc.cmodes['*A'] ] self._send( server, "FJOIN {channel} {ts} {modes} :,{uid}".format( ts=self.irc.channels[channel].ts, uid=client, channel=channel, modes=utils.joinModes(modes))) self.irc.channels[channel].users.add(client) self.irc.users[client].channels.add(channel)
def handle_kick(self, source, command, args): """Handles incoming KICKs.""" # :70MAAAAAA KICK #endlessvoid 70MAAAAAA :some reason 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 joinClient(self, client, channel): """Joins a PyLink client to a channel.""" channel = utils.toLower(self.irc, channel) if not utils.isInternalClient(self.irc, client): raise LookupError('No such PyLink client exists.') self._send(client, "JOIN %s" % channel) self.irc.channels[channel].users.add(client) self.irc.users[client].channels.add(channel)
def sjoinServer(self, server, channel, users, ts=None): """Sends an SJOIN for a group of users to a channel. The sender should always be a Server ID (SID). TS is optional, and defaults to the one we've stored in the channel state if not given. <users> is a list of (prefix mode, UID) pairs: Example uses: sjoinServer('100', '#test', [('', '100AAABBC'), ('qo', 100AAABBB'), ('h', '100AAADDD')]) sjoinServer(self.irc.sid, '#test', [('o', self.irc.pseudoclient.uid)]) """ channel = utils.toLower(self.irc, channel) server = server or self.irc.sid assert users, "sjoinServer: No users sent?" log.debug('(%s) sjoinServer: got %r for users', self.irc.name, users) if not server: raise LookupError('No such PyLink PseudoClient exists.') orig_ts = self.irc.channels[channel].ts ts = ts or orig_ts self.updateTS(channel, ts) log.debug("sending SJOIN to %s%s with ts %s (that's %r)", channel, self.irc.name, ts, time.strftime("%c", time.localtime(ts))) # Strip out list-modes, they shouldn't ever be sent in FJOIN (protocol rules). modes = [ m for m in self.irc.channels[channel].modes if m[0] not in self.irc.cmodes['*A'] ] uids = [] changedmodes = [] namelist = [] # We take <users> as a list of (prefixmodes, uid) pairs. for userpair in users: assert len( userpair) == 2, "Incorrect format of userpair: %r" % userpair prefixes, user = userpair namelist.append(','.join(userpair)) uids.append(user) for m in prefixes: changedmodes.append(('+%s' % m, user)) try: self.irc.users[user].channels.add(channel) except KeyError: # Not initialized yet? log.debug( "(%s) sjoinServer: KeyError trying to add %r to %r's channel list?", self.irc.name, channel, user) if ts <= orig_ts: # Only save our prefix modes in the channel state if our TS is lower than or equal to theirs. utils.applyModes(self.irc, channel, changedmodes) namelist = ' '.join(namelist) self._send( server, "FJOIN {channel} {ts} {modes} :{users}".format( ts=ts, users=namelist, channel=channel, modes=utils.joinModes(modes))) self.irc.channels[channel].users.update(uids)
def handle_privmsg(self, source, command, args): """Handles incoming PRIVMSG/NOTICE.""" # <- :70MAAAAAA PRIVMSG #dev :afasfsa # <- :70MAAAAAA NOTICE 0ALAAAAAA :afasfsa target = args[0] # We use lowercase channels internally, but uppercase UIDs. if utils.isChannel(target): target = utils.toLower(self.irc, target) return {'target': target, 'text': args[1]}
def _sendKick(self, numeric, channel, target, reason=None): """Internal function to send kicks from a PyLink client/server.""" channel = utils.toLower(self.irc, channel) if not reason: reason = 'No reason given' self._send(numeric, 'KICK %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 handle_ftopic(self, numeric, command, args): """Handles incoming FTOPIC (sets topic on burst).""" # <- :70M FTOPIC #channel 1434510754 GLo|o|[email protected] :Some channel topic channel = utils.toLower(self.irc, args[0]) ts = args[1] setter = args[2] topic = args[-1] self.irc.channels[channel].topic = topic self.irc.channels[channel].topicset = True return {'channel': channel, 'setter': setter, 'ts': ts, 'topic': topic}
def partClient(self, client, channel, reason=None): """Sends a part from a PyLink client.""" channel = utils.toLower(self.irc, channel) if not utils.isInternalClient(self.irc, client): log.error( '(%s) Error trying to part client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel) raise LookupError('No such PyLink PseudoClient exists.') msg = "PART %s" % channel if reason: msg += " :%s" % reason self._send(client, msg) self.handle_part(client, 'PART', [channel])
def handle_sjoin(self, numeric, command, args): """Handles the UnrealIRCd SJOIN command.""" # <- :001 SJOIN 1444361345 #endlessvoid :001DJ1O02 # memberlist should be a list of UIDs with their channel status prefixes, as # in ":001AAAAAA @001AAAAAB +001AAAAAC". # Interestingly, no modes are ever sent in this command as far as I've seen. channel = utils.toLower(self.irc, args[1]) userlist = args[-1].split() our_ts = self.irc.channels[channel].ts their_ts = int(args[0]) self.updateTS(channel, their_ts) namelist = [] log.debug('(%s) handle_sjoin: got userlist %r for %r', self.irc.name, userlist, channel) for userpair in userlist: if userpair.startswith("&\"'"): # TODO: handle ban bursts too # &, ", and ' entries are used for bursting bans: # https://www.unrealircd.org/files/docs/technical/serverprotocol.html#S5_1 break r = re.search(r'([^\d]*)(.*)', userpair) user = r.group(2) # Unreal uses slightly different prefixes in SJOIN. +q is * instead of ~, # and +a is ~ instead of &. modeprefix = (r.group(1) or '').replace("~", "&").replace("*", "~") finalprefix = '' assert user, 'Failed to get the UID from %r; our regex needs updating?' % userpair log.debug('(%s) handle_sjoin: got modeprefix %r for user %r', self.irc.name, modeprefix, user) for m in modeprefix: # Iterate over the mapping of prefix chars to prefixes, and # find the characters that match. for char, prefix in self.irc.prefixmodes.items(): if m == prefix: finalprefix += char namelist.append(user) self.irc.users[user].channels.add(channel) # Only merge the remote's prefix modes if their TS is smaller or equal to ours. if their_ts <= our_ts: utils.applyModes(self.irc, channel, [('+%s' % mode, user) for mode in finalprefix]) self.irc.channels[channel].users.add(user) return { 'channel': channel, 'users': namelist, 'modes': self.irc.channels[channel].modes, 'ts': their_ts }
def handle_fmode(self, numeric, command, args): """Handles the FMODE command, used for channel mode changes.""" # <- :70MAAAAAA FMODE #chat 1433653462 +hhT 70MAAAAAA 70MAAAAAD channel = utils.toLower(self.irc, args[0]) oldobj = self.irc.channels[channel].deepcopy() modes = args[2:] changedmodes = utils.parseModes(self.irc, channel, modes) utils.applyModes(self.irc, channel, changedmodes) ts = int(args[1]) return { 'target': channel, 'modes': changedmodes, 'ts': ts, 'oldchan': oldobj }
def handle_tmode(self, numeric, command, args): """Handles incoming TMODE commands (channel mode change).""" # <- :42XAAAAAB TMODE 1437450768 #endlessvoid -c+lkC 3 agte4 channel = utils.toLower(self.irc, args[1]) oldobj = self.irc.channels[channel].deepcopy() modes = args[2:] changedmodes = utils.parseModes(self.irc, channel, modes) utils.applyModes(self.irc, channel, changedmodes) ts = int(args[0]) return { 'target': channel, 'modes': changedmodes, 'ts': ts, 'oldchan': oldobj }
def joinClient(self, client, channel): """Joins a PyLink client to a channel.""" channel = utils.toLower(self.irc, channel) # JOIN: # parameters: channelTS, channel, '+' (a plus sign) if not utils.isInternalClient(self.irc, client): log.error( '(%s) Error trying to join client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel) raise LookupError('No such PyLink PseudoClient exists.') self._send( client, "JOIN {ts} {channel} +".format(ts=self.irc.channels[channel].ts, channel=channel)) self.irc.channels[channel].users.add(client) self.irc.users[client].channels.add(channel)
def handle_topic(self, numeric, command, args): """Handles the TOPIC command.""" # <- GL TOPIC #services GL 1444699395 :weeee channel = utils.toLower(self.irc, args[0]) topic = args[-1] ts = args[2] oldtopic = self.irc.channels[channel].topic self.irc.channels[channel].topic = topic self.irc.channels[channel].topicset = True return { 'channel': channel, 'setter': numeric, 'ts': ts, 'topic': topic, 'oldtopic': oldtopic }
def showchan(irc, source, args): """<channel> Shows information about <channel>.""" try: channel = utils.toLower(irc, args[0]) except IndexError: irc.reply("Error: Not enough arguments. Needs 1: channel.") return if channel not in irc.channels: irc.reply('Error: Unknown channel %r.' % channel) return f = lambda s: irc.msg(source, s) c = irc.channels[channel] # Only show verbose info if caller is oper or is in the target channel. verbose = source in c.users or utils.isOper(irc, source) secret = ('s', None) in c.modes if secret and not verbose: # Hide secret channels from normal users. irc.msg(source, 'Error: Unknown channel %r.' % channel) return nicks = [irc.users[u].nick for u in c.users] pmodes = ('owner', 'admin', 'op', 'halfop', 'voice') f('Information on channel \x02%s\x02:' % channel) f('\x02Channel topic\x02: %s' % c.topic) f('\x02Channel creation time\x02: %s (%s)' % (ctime(c.ts), c.ts)) # Show only modes that aren't list-style modes. modes = utils.joinModes( [m for m in c.modes if m[0] not in irc.cmodes['*A']]) f('\x02Channel modes\x02: %s' % modes) if verbose: nicklist = [] # Iterate over the user list, sorted by nick. for user, nick in sorted(zip(c.users, nicks), key=lambda userpair: userpair[1].lower()): prefixmodes = [ irc.prefixmodes.get(irc.cmodes.get(pmode, ''), '') for pmode in pmodes if user in c.prefixmodes[pmode + 's'] ] nicklist.append(''.join(prefixmodes) + nick) while nicklist[:20]: # 20 nicks per line to prevent message cutoff. f('\x02User list\x02: %s' % ' '.join(nicklist[:20])) nicklist = nicklist[20:]
def handle_topic(self, numeric, command, args): """Handles incoming TOPIC changes from clients. For topic bursts, TB (TS6/charybdis) and FTOPIC (InspIRCd) are used instead.""" # <- :70MAAAAAA TOPIC #test :test channel = utils.toLower(self.irc, args[0]) topic = args[1] ts = int(time.time()) oldtopic = self.irc.channels[channel].topic self.irc.channels[channel].topic = topic self.irc.channels[channel].topicset = True return { 'channel': channel, 'setter': numeric, 'ts': ts, 'topic': topic, 'oldtopic': oldtopic }
def _sendModes(self, numeric, target, modes, ts=None): """Internal function to send mode changes from a PyLink client/server.""" # -> :9PYAAAAAA FMODE #pylink 1433653951 +os 9PYAAAAAA # -> :9PYAAAAAA MODE 9PYAAAAAA -i+w log.debug('(%s) inspircd._sendModes: received %r for mode list', self.irc.name, modes) if ('+o', None) in modes and not utils.isChannel(target): # https://github.com/inspself.ircd/inspself.ircd/blob/master/src/modules/m_spanningtree/opertype.cpp#L26-L28 # Servers need a special command to set umode +o on people. self._operUp(target) utils.applyModes(self.irc, target, modes) joinedmodes = utils.joinModes(modes) if utils.isChannel(target): ts = ts or self.irc.channels[utils.toLower(self.irc, target)].ts self._send(numeric, 'FMODE %s %s %s' % (target, ts, joinedmodes)) else: self._send(numeric, 'MODE %s %s' % (target, joinedmodes))
def initializeDefender(self, config): """ This method instantiates a defender object for the given configuration. Args: config (dict): Configurations for the defender. """ # Import defender module. defenderClass = config['class'] logging.debug('Try to use defender ' + defenderClass + ' from module defender.' + toLower(defenderClass)) defenderModule = importlib.import_module('.' + toLower(defenderClass), package='defender') # Get defender class. defender_ = getattr(defenderModule, defenderClass) # Instanciate defender. self.defender = defender_(config) logging.debug('Successfully created defender ' + defenderClass + ' from module defender.' + toLower(defenderClass) + ' [' + str(self.defender) + ']')
def _sendModes(self, numeric, target, modes, ts=None): """Internal function to send mode changes from a PyLink client/server.""" # <- :unreal.midnight.vpn MODE #endlessvoid +ntCo GL 1444361345 utils.applyModes(self.irc, target, modes) joinedmodes = utils.joinModes(modes) if utils.isChannel(target): # The MODE command is used for channel mode changes only ts = ts or self.irc.channels[utils.toLower(self.irc, target)].ts self._send(numeric, 'MODE %s %s %s' % (target, joinedmodes, ts)) else: # For user modes, the only way to set modes (for non-U:Lined servers) # is through UMODE2, which sets the modes on the caller. # U:Lines can use SVSMODE/SVS2MODE, but I won't expect people to # U:Line a PyLink daemon... if not utils.isInternalClient(self.irc, target): raise ProtocolError( 'Cannot force mode change on external clients!') self._send(target, 'UMODE2 %s' % joinedmodes)
def initializeProcess(self, config): """ This method instantiates a process object for the given configuration. Args: config (dict): Configurations for the process. """ # Import process module first. processClass = config['class'] processPackage = config['package'] logging.debug('Try to use process ' + processClass + ' from module process' + processPackage + "." + toLower(processClass)) processModule = importlib.import_module('process' + processPackage + "." + toLower(processClass), package='...process') # Get process class. process_ = getattr(processModule, processClass) # Instanciate process. self.process = process_(config) logging.debug('Successfully created process ' + processClass + ' from module process.' + toLower(processClass) + ' [' + str(self.process) + ']')
def handle_sjoin(self, servernumeric, command, args): """Handles incoming SJOIN commands.""" # parameters: channelTS, channel, simple modes, opt. mode parameters..., nicklist channel = utils.toLower(self.irc, args[1]) userlist = args[-1].split() their_ts = int(args[0]) our_ts = self.irc.channels[channel].ts self.updateTS(channel, their_ts) modestring = args[2:-1] or args[2] parsedmodes = utils.parseModes(self.irc, channel, modestring) utils.applyModes(self.irc, channel, parsedmodes) namelist = [] log.debug('(%s) handle_sjoin: got userlist %r for %r', self.irc.name, userlist, channel) for userpair in userlist: # charybdis sends this in the form "@+UID1, +UID2, UID3, @UID4" r = re.search(r'([^\d]*)(.*)', userpair) user = r.group(2) modeprefix = r.group(1) or '' finalprefix = '' assert user, 'Failed to get the UID from %r; our regex needs updating?' % userpair log.debug('(%s) handle_sjoin: got modeprefix %r for user %r', self.irc.name, modeprefix, user) for m in modeprefix: # Iterate over the mapping of prefix chars to prefixes, and # find the characters that match. for char, prefix in self.irc.prefixmodes.items(): if m == prefix: finalprefix += char namelist.append(user) self.irc.users[user].channels.add(channel) if their_ts <= our_ts: utils.applyModes(self.irc, channel, [('+%s' % mode, user) for mode in finalprefix]) self.irc.channels[channel].users.add(user) return { 'channel': channel, 'users': namelist, 'modes': parsedmodes, 'ts': their_ts }
def _sendModes(self, numeric, target, modes, ts=None): """Internal function to send mode changes from a PyLink client/server.""" utils.applyModes(self.irc, target, modes) modes = list(modes) if utils.isChannel(target): ts = ts or self.irc.channels[utils.toLower(self.irc, target)].ts # TMODE: # parameters: channelTS, channel, cmode changes, opt. cmode parameters... # On output, at most ten cmode parameters should be sent; if there are more, # multiple TMODE messages should be sent. while modes[:9]: joinedmodes = utils.joinModes(modes=[ m for m in modes[:9] if m[0] not in self.irc.cmodes['*A'] ]) modes = modes[9:] self._send(numeric, 'TMODE %s %s %s' % (ts, target, joinedmodes)) else: joinedmodes = utils.joinModes(modes) self._send(numeric, 'MODE %s %s' % (target, joinedmodes))
def handle_part(self, source, command, args): """Handles incoming PART commands.""" 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 or ((self.irc.cmodes.get('permanent'), None) in self.irc.channels[channel].modes)): del self.irc.channels[channel] return {'channels': channels, 'text': reason}
def handle_encap(self, numeric, command, args): """Handles incoming encapsulated commands (ENCAP). Hook arguments returned by this should have a parse_as field, that sets the correct hook name for the message. For InspIRCd, the only ENCAP command we handle right now is KNOCK.""" # <- :70MAAAAAA ENCAP * KNOCK #blah :agsdfas # From charybdis TS6 docs: https://github.com/grawity/self.irc-docs/blob/03ba884a54f1cef2193cd62b6a86803d89c1ac41/server/ts6.txt # ENCAP # source: any # parameters: target server mask, subcommand, opt. parameters... # Sends a command to matching servers. Propagation is independent of # understanding the subcommand. targetmask = args[0] real_command = args[1] if targetmask == '*' and real_command == 'KNOCK': channel = utils.toLower(self.irc, args[2]) text = args[3] return {'parse_as': real_command, 'channel': channel, 'text': text}
else: subprocess.Popen([ "python", "src/ui/app.py", "127.0.0.1", str(5000 + random.randint(0, 999)), "out/webui.pid", "out/teRunner.txt" ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) attacker = None try: # Import attacker. attackerClass = sanitizeClass(attackerName) logging.debug('Try to use attacker ' + attackerClass + ' from module attacker.' + toLower(attackerClass)) attackerModule = importlib.import_module('attacker.' + toLower(attackerClass), package=__name__) # Create attacker. attacker_ = getattr(attackerModule, attackerClass) attacker = attacker_(attackerConfig) logging.debug('Successfully created attacker ' + attackerClass + ' from module attacker.' + toLower(attackerClass) + ' [' + str(attacker) + ']') # Let attacker setup process. attacker.initializeProcess(processConfig) # Setup defender if needed.