archive

- Random tools & helpful resources for IRC
git clone git://git.acid.vegas/archive.git
Log | Files | Refs | Archive

phalanx.py (7127B)

      1 #!/usr/bin/env python
      2 # phalanx localhost bot - developed by acidvegas in python (https://git.acid.vegas/archive)
      3 
      4 import asyncio
      5 import random
      6 import re
      7 import sys
      8 import time
      9 
     10 class settings:
     11 	admin     = 'acidvegas!~stillfree@most.dangerous.motherfuck' # Can use wildcards (Must be in nick!user@host format)
     12 	access    = [admin,]
     13 	oper_user = 'phalanx'
     14 	oper_pass = 'simps0nsfAn420'
     15 
     16 # Formatting Control Characters / Color Codes
     17 bold        = '\x02'
     18 reset       = '\x0f'
     19 green       = '03'
     20 red         = '04'
     21 purple      = '06'
     22 orange      = '07'
     23 yellow      = '08'
     24 light_green = '09'
     25 cyan        = '10'
     26 light_cyan  = '11'
     27 light_blue  = '12'
     28 pink        = '13'
     29 grey        = '14'
     30 
     31 def color(msg, foreground, background=None):
     32 	return f'\x03{foreground},{background}{msg}{reset}' if background else f'\x03{foreground}{msg}{reset}'
     33 
     34 def is_access(ident):
     35 	result = False
     36 	for item in settings.access:
     37 		if re.compile(item.replace('*','.*')).search(ident):
     38 			result = True
     39 	return result
     40 
     41 def is_admin(ident):
     42 	return re.compile(settings.admin.replace('*','.*')).search(ident)
     43 
     44 def rndip():
     45 	host = ''
     46 	for i in range(3):
     47 		host = host + ''.join([random.choice('0123456789ABCDEF') for n in range(8)]) + '.'
     48 	return host + 'IP'
     49 
     50 def rndnick():
     51 	prefix = random.choice(['st','sn','cr','pl','pr','fr','fl','qu','br','gr','sh','sk','tr','kl','wr','bl']+list('bcdfgklmnprstvwz'))
     52 	midfix = random.choice(('aeiou'))+random.choice(('aeiou'))+random.choice(('bcdfgklmnprstvwz'))
     53 	suffix = random.choice(['ed','est','er','le','ly','y','ies','iest','ian','ion','est','ing','led','inger']+list('abcdfgklmnprstvwz'))
     54 	return prefix+midfix+suffix
     55 
     56 class clone:
     57 	def __init__(self, identity={'chan':'#phalanx','nick':'phalanx','user':'W','host':'R','real':'\x0304ROMAN WAR PHALANX\x03'}):
     58 		self.identity  = identity
     59 		self.clones    = dict()
     60 		self.destroy   = False
     61 		self.reader    = None
     62 		self.write     = None
     63 
     64 	async def sendmsg(self, target, msg):
     65 		await self.raw(f'PRIVMSG {target} :{msg}')
     66 
     67 	async def error(self, chan, data, reason=None):
     68 		await self.sendmsg(chan, '[{0}] {1}'.format(color('error', red), data, color(f'({reason})', grey))) if reason else await self.sendmsg(chan, '[{0}] {1}'.format(color('error', red), data))
     69 
     70 	async def run(self):
     71 		await self.connect()
     72 
     73 	async def raw(self, data):
     74 		self.writer.write(data[:510].encode('utf-8') + b'\r\n')
     75 		await self.writer.drain()
     76 
     77 	async def connect(self):
     78 		while not self.destroy:
     79 			try:
     80 				options = {'host':'127.0.0.1', 'port':6667, 'limit':1024, 'ssl':None, 'family':2}
     81 				self.reader, self.writer = await asyncio.wait_for(asyncio.open_connection(**options), 5)
     82 				del options
     83 				await self.raw('USER {0} 0 * :{1}'.format(self.identity['user'], self.identity['real']))
     84 				await self.raw('NICK ' + self.identity['nick'])
     85 				await self.listen()
     86 			except Exception as ex:
     87 				if self.identity['nick'] == 'phalanx':
     88 					for item in self.clones:
     89 						if self.clones[item]:
     90 							self.clones[item].cancel()
     91 					self.clones = dict()
     92 				print('[!] - error occured (' + str(ex) + ')')
     93 				await asyncio.sleep(random.randint(60,300))
     94 
     95 	async def listen(self):
     96 		while True:
     97 			try:
     98 				data = await asyncio.wait_for(self.reader.readuntil(b'\r\n'), 600)
     99 				line = data.decode('utf-8').strip()
    100 				if self.identity['nick'] == 'phalanx':
    101 					print('[~] - ' + line)
    102 				args = line.split()
    103 				if args[0] == 'PING':
    104 					await self.raw('PONG ' + args[1][1:])
    105 				elif args[1] == '001':
    106 					await self.raw('MODE ' + self.identity['nick'] + ' +dD')
    107 					await self.raw(f'OPER {settings.oper_user} {settings.oper_pass}')
    108 					await asyncio.sleep(1)
    109 					await self.raw('SETHOST ' + self.identity['host'])
    110 					await self.raw('JOIN #phalanx')
    111 					if self.identity['chan'] != '#phalanx':
    112 						await self.raw('JOIN ' + self.identity['chan'])
    113 				elif args[1] == '433':
    114 					self.identity['nick'] = rndnick()
    115 					await self.raw('NICK ' + self.identity['nick'])
    116 				elif args[1] == 'KICK' and len(args) >= 4:
    117 					chan = args[2]
    118 					nick = args[3]
    119 					if nick == self.identity['nick']:
    120 						await asyncio.sleep(3)
    121 						await self.raw('JOIN ' + chan)
    122 				elif args[1] == 'NICK' and len(args) == 3:
    123 					nick = args[0][1:]
    124 					new  = ' '.join(args[2:])[1:]
    125 					if nick == self.identity['nick']:
    126 						self.identity['nick'] = new
    127 				elif args[1] == 'PRIVMSG' and len(args) >= 4:
    128 					ident  = args[0][1:]
    129 					nick   = args[0].split('!')[0][1:]
    130 					target = args[2]
    131 					msg    = ' '.join(args[3:])[1:]
    132 					args   = msg.split()
    133 					if is_admin(ident):
    134 						if args[0] == '.access' and self.identity['nick'] == 'phalanx' and len(args) == 2:
    135 							action = args[1][:1]
    136 							host   = args[1][1:]
    137 							if action == '+':
    138 								if host not in settings.access:
    139 									settings.access.append(host)
    140 									await self.sendmsg(target, color('added', green))
    141 							elif action == '-':
    142 								if host in settings.access:
    143 									settings.access.remove(host)
    144 									await self.sendmsg(target, color('removed', red))
    145 							elif action == '?':
    146 								for item in settings.access:
    147 									await self.sendmsg(target, color(item, yellow))
    148 							else:
    149 								await self.error(chan, 'invalid command', 'usage: .access <+/-><host>')
    150 					if is_access(ident):
    151 						if args[0] == '.create' and self.identity['nick'] == 'phalanx' and len(args) >= 2:
    152 							if len(self.clones) < 500:
    153 								chan = args[1]
    154 								if len(args) >= 6:
    155 									nick = rndnick() if args[2] == '%r' else args[2]
    156 									user = rndnick() if args[3] == '%r' else args[3]
    157 									host = rndip()   if args[4] == '%r' else args[4]
    158 									real = rndnick() if args[5] == '%r' else ' '.join(args[5:])
    159 								elif len(args) == 2:
    160 									ident = random.choice(idents).split()
    161 									nick = ident[0]
    162 									user = ident[1]
    163 									host = ident[2]
    164 									real = ' '.join(ident[3:])
    165 								if nick != 'phalanx':
    166 									options = {'chan':chan,'nick':nick,'user':user,'host':host,'real':real}
    167 									self.clones[random.randint(1000,9999)] = asyncio.create_task(clone(identity=options).run())
    168 							else:
    169 								self.error(target, 'max clones', 'for now...')
    170 						elif args[0] == '.destroy' and self.identity['nick'] != 'phalanx' and len(args) == 2:
    171 							target = args[1]
    172 							if target == self.identity['nick'] or (target == '*' and is_admin(ident)):
    173 								self.destroy = True
    174 								await self.raw('QUIT :' + random.choice(('*.net *.split', f'Ping timeout: {random.randint(180,300)} seconds', 'Connection closed', 'G-line: User has been permanently banned from this network.')))
    175 						elif args[0] == '.raw' and len(args) >= 3:
    176 							target = args[1]
    177 							if target == 'phalanx' and not is_admin(ident):
    178 								self.error(chan 'yeah right...')
    179 							data   = ' '.join(args[2:])
    180 							if '#5000' not in data:
    181 								if target == self.identity['nick'] or (target == '*' and is_admin(ident)):
    182 									if args[1] == '*':
    183 										await asyncio.sleep(float('0.0'+str(random.randint(1111,9999))))
    184 									await self.raw(data)
    185 			except (UnicodeDecodeError, UnicodeEncodeError):
    186 				pass
    187 
    188 # Main
    189 idents = open('idents.txt').readlines()
    190 asyncio.run(clone().run())