2023-05-25 22:01:17 -07:00
#!/usr/bin/env python3
# Initially 'jupiter' by acidvegas
# Furthered by delorean
#
# irc.supernets.org #superbowl
import random
import re
import socket
import ssl
import time
import threading
# Servers
servers = (
{ ' server ' : ' efnet.deic.eu ' , ' ssl ' : 6697 , ' ipv6 ' : True } ,
{ ' server ' : ' efnet.port80.se ' , ' ssl ' : 6697 , ' ipv6 ' : True } ,
#{'server':'efnet.portlane.se', 'ssl':6697, 'ipv6': True}, # Removed (efnet.portlane.se is an alias for irc.efnet.org)
{ ' server ' : ' irc.choopa.net ' , ' ssl ' : 9000 , ' ipv6 ' : True } ,
{ ' server ' : ' irc.colosolutions.net ' , ' ssl ' : None , ' ipv6 ' : False } , # error: SSL handshake failed: unsafe legacy renegotiation disabled
{ ' server ' : ' irc.du.se ' , ' ssl ' : None , ' ipv6 ' : False } , # error: handshake failed: dh key too small
#{'server':'irc.efnet.fr', 'ssl':6697, 'ipv6': True}, # Removed (irc.efnet.fr is an alias for irc.efnet.nl)
{ ' server ' : ' irc.efnet.nl ' , ' ssl ' : 6697 , ' ipv6 ' : True } ,
{ ' server ' : ' irc.homelien.no ' , ' ssl ' : 6697 , ' ipv6 ' : True } ,
{ ' server ' : ' irc.mzima.net ' , ' ssl ' : 6697 , ' ipv6 ' : True } ,
#{'server':'irc.nordunet.se', 'ssl':6697, 'ipv6': True}, # Removed (irc.nordunet.se is an alias for irc.swepipe.se)
{ ' server ' : ' irc.prison.net ' , ' ssl ' : None , ' ipv6 ' : False } ,
{ ' server ' : ' irc.swepipe.se ' , ' ssl ' : 6697 , ' ipv6 ' : True } ,
{ ' server ' : ' irc.underworld.no ' , ' ssl ' : 6697 , ' ipv6 ' : True } ,
{ ' server ' : ' irc.servercentral.net ' , ' ssl ' : 9999 , ' ipv6 ' : False }
)
ipv6 = True # Set to False if your system does not have an IPv6 address
2023-05-25 22:22:13 -07:00
channel = " #superbowl "
key = " "
2023-05-25 22:01:17 -07:00
# Settings
2023-05-25 22:22:13 -07:00
admin = [ " *!*@*drugcar.tel " ] # Can use wildcards (Must be in nick!user@host format)
concurrency = 3 # Number of clones to load per server
2023-05-25 22:01:17 -07:00
id = " dev " # Unique ID so you can tell which bots belong what server
# Formatting Control Characters / Color Codes
bold = " \x02 "
reset = " \x0f "
green = " 03 "
red = " 04 "
purple = " 06 "
orange = " 07 "
yellow = " 08 "
light_green = " 09 "
cyan = " 10 "
light_cyan = " 11 "
light_blue = " 12 "
pink = " 13 "
grey = " 14 "
# Globals
bots = list ( )
def botlist ( nick ) :
global bots
if nick [ : 1 ] == " + " :
bots . append ( nick [ 1 : ] )
elif nick [ : 1 ] == " - " :
bots . remove ( nick [ 1 : ] )
def color ( msg , foreground , background = None ) :
return ( f " \x03 { foreground } , { background } { msg } { reset } "
if background
else f " \x03 { foreground } { msg } { reset } "
)
def debug ( msg ) :
print ( f " { get_time ( ) } | [~] - { msg } " )
def error ( msg , reason = None ) :
print ( f " { get_time ( ) } | [!] - { msg } ( { reason } ) " ) if reason else print ( f " { get_time ( ) } | [!] - { msg } " )
def get_time ( ) :
return time . strftime ( " % I: % M: % S " )
def is_admin ( ident ) :
for i in admin :
if re . compile ( i . replace ( ' * ' , ' .* ' ) ) . search ( ident ) :
return True
return False
def random_nick ( ) :
prefix = random . choice ( [ ' st ' , ' sn ' , ' cr ' , ' pl ' , ' pr ' , ' fr ' , ' fl ' , ' qu ' , ' br ' , ' gr ' , ' sh ' , ' sk ' , ' tr ' , ' kl ' , ' wr ' , ' bl ' ] + list ( ' bcdfgklmnprstvwz ' ) )
midfix = random . choice ( ( ' aeiou ' ) ) + random . choice ( ( ' aeiou ' ) ) + random . choice ( ( ' bcdfgklmnprstvwz ' ) )
suffix = random . choice ( [ ' ed ' , ' est ' , ' er ' , ' le ' , ' ly ' , ' y ' , ' ies ' , ' iest ' , ' ian ' , ' ion ' , ' est ' , ' ing ' , ' led ' , ' inger ' ] + list ( ' abcdfgklmnprstvwz ' ) )
return prefix + midfix + suffix
def unicode ( ) :
msg = ' \u202e \u0007 \x03 ' + str ( random . randint ( 2 , 14 ) )
for i in range ( random . randint ( 150 , 200 ) ) :
msg + = chr ( random . randint ( 0x1000 , 0x3000 ) )
return msg
class clone ( threading . Thread ) :
def __init__ ( self , server , addr_type ) :
self . addr_type = addr_type
self . landmine = None
self . nickname = random_nick ( )
self . monlist = list ( )
self . relaylist = list ( )
self . coverlist = list ( )
self . autoop = False
self . server = server
self . port = 6667
self . sock = None
self . ssl_status = None
threading . Thread . __init__ ( self )
def run ( self ) :
time . sleep ( random . randint ( 300 , 900 ) )
self . connect ( )
def connect ( self ) :
try :
self . create_socket ( )
self . sock . connect ( ( self . server [ " server " ] , self . port ) )
self . raw ( f " USER { random_nick ( ) } 0 * : { random_nick ( ) } " )
self . nick ( self . nickname )
except socket . error as ex :
error ( " Failed to connect to ' {0} ' IRC server. " . format ( self . server [ " server " ] ) , ex )
self . event_disconnect ( )
except ssl . SSLError as ex :
error ( " Failed to connect to ' {0} ' IRC server using SSL/TLS. " . format ( self . server [ " server " ] ) , ex )
self . ssl_status = False
self . event_disconnect ( )
else :
self . listen ( )
def create_socket ( self ) :
self . sock = socket . socket ( self . addr_type )
if self . server [ " ssl " ] :
if self . ssl_status :
self . port = self . server [ " ssl " ]
self . sock = ssl . wrap_socket ( self . sock )
else :
self . port = 6667
self . ssl_status = True
def event_connect ( self ) :
if self . nickname not in bots :
botlist ( " + " + self . nickname )
if self . monlist :
self . monitor ( " + " , self . monlist )
self . join_channel ( channel , key )
def event_ctcp ( self , nick , target , msg ) :
if target == self . nickname :
2023-05-25 22:22:13 -07:00
if ' VERSION ' in msg :
2023-05-25 22:01:17 -07:00
version = random . choice ( ' Wal-Mart IRC Client ' , ' mIRC v6.35 Khaled Mardam-Bey ' , ' xchat 0.24.1 Linux 2.6.27-8-eeepc i686 ' , ' rZNC Version 1.0 [02/01/11] - Built from ZNC ' , ' thelounge v3.0.0 -- https://thelounge.chat/ ' )
self . raw ( f ' NOTICE { nick } \001 VERSION { version } \001 ' )
else :
self . sendmsg ( channel , ' [ {0} ] {1} {2} {3} {4} ' . format ( color ( ' CTCP ' , green ) , color ( ' < ' , grey ) , color ( nick , yellow ) , color ( ' > ' , grey ) , msg ) )
def event_disconnect ( self ) :
if self . nickname in bots :
botlist ( " - " + self . nickname )
self . sock . close ( )
time . sleep ( 86400 + random . randint ( 1800 , 3600 ) )
self . connect ( )
def event_join ( self , ident , nick , chan ) :
if is_admin ( ident ) and self . autoop :
self . raw ( " MODE {0} +o {1} " . format ( chan , nick ) )
if chan == self . landmine :
for x in range ( 0 , 6 ) :
self . sendmsg ( chan , f " { unicode ( ) } oh god { nick } what is happening { unicode ( ) } " )
self . sendmsg ( nick , f " { unicode ( ) } oh god { nick } what is happening { unicode ( ) } " )
def event_nick ( self , nick , new_nick ) :
if nick == self . nickname :
self . nickname = new_nick
if new_nick in self . monlist :
self . monitor ( " C " )
self . monlist = list ( )
elif nick in self . monlist :
self . nick ( nick )
def event_nick_in_use ( self , nick , target_nick ) :
if nick == " * " :
self . nickname = random_nick ( )
self . nick ( self . nickname )
def event_notice ( self , nick , target , msg ) :
2023-05-25 22:22:13 -07:00
# if target == self.nickname:
# self.sendmsg(channel, '[{0}] {1}{2}{3} {4}'.format(color('NOTICE', purple), color('<', grey), color(nick, yellow), color('>', grey), msg))
pass
2023-05-25 22:01:17 -07:00
def event_message ( self , ident , nick , target , msg ) :
if target . lower ( ) in self . relaylist :
self . sendmsg ( channel , " [ {0} ] < {1} > {2} " . format ( color ( target , light_cyan ) , color ( nick , purple ) , msg ) )
if is_admin ( ident ) :
args = msg . split ( )
if args [ 0 ] in ( " @all " , self . nickname ) and len ( args ) > = 2 :
if len ( args ) == 2 :
if args [ 1 ] == " id " :
self . sendmsg ( target , id )
elif len ( args ) == 3 :
if args [ 1 ] == " 5000 " :
chan = args [ 2 ]
if chan == " stop " :
self . landmine = None
self . sendmsg ( target , " 5000 mode turned off " )
elif chan [ : 1 ] == " # " :
self . landmine = chan
self . sendmsg ( target , " 5000 mode actived on " + color ( chan , cyan ) )
elif args [ 1 ] == ' migrate ' :
if args [ 2 ] [ : 1 ] == ' # ' :
channel = args [ 2 ]
self . sendmsg ( target , ' hub migrated to {0} ' . format ( color ( args [ 2 ] , light_green ) ) )
elif args [ 1 ] == ' auto-op ' :
if args [ 2 ] [ : 2 ] . lower ( ) == ' on ' :
self . autoop = True
self . sendmsg ( channel , ' auto opping {0} ' . format ( color ( " enabled " , light_green ) ) )
elif args [ 2 ] [ : 3 ] . lower ( ) == ' off ' :
self . autoop = False
self . sendmsg ( channel , ' auto opping {0} ' . format ( color ( args [ 2 ] [ 1 : ] , red ) ) )
elif args [ 1 ] == ' admin ' :
adstr = args [ 2 ] [ 1 : ] + " !*@* "
if args [ 2 ] [ : 1 ] == ' + ' :
if adstr in admin :
self . sendmsg ( target , ' {0} ' . format ( color ( ' user is already an admin ' , red ) ) )
else :
admin . append ( adstr )
self . sendmsg ( target , ' {0} promoted to {1} ' . format ( color ( args [ 2 ] [ 1 : ] , light_green ) , color ( " admin " , light_green ) ) )
elif args [ 2 ] [ : 1 ] == ' - ' :
if adstr not in admin :
self . sendmsg ( target , ' {0} ' . format ( color ( ' user was not an admin ' , red ) ) )
else :
admin . remove ( adstr )
self . sendmsg ( target , ' {0} admin {1} ' . format ( color ( ' removed ' , red ) , color ( args [ 2 ] [ 1 : ] , red ) ) )
elif args [ 1 ] == ' monitor ' :
if args [ 2 ] == ' list ' and self . monlist :
self . sendmsg ( target , ' [ {0} ] {1} ' . format ( color ( ' Monitor ' , light_blue ) , ' , ' . join ( self . monlist ) ) )
elif args [ 2 ] == ' reset ' and self . monlist :
self . monitor ( ' C ' )
self . monlist = list ( )
self . sendmsg ( target , ' {0} nick(s) have been {1} from the monitor list. ' . format ( color ( str ( len ( self . monlist ) ) , cyan ) , color ( ' removed ' , red ) ) )
elif args [ 2 ] [ : 1 ] == ' + ' :
nicks = [ mon_nick for mon_nick in set ( args [ 2 ] [ 1 : ] . split ( ' , ' ) ) if mon_nick not in self . monlist ]
if nicks :
self . monitor ( ' + ' , nicks )
self . monlist + = nicks
self . sendmsg ( target , ' {0} nick(s) have been {1} to the monitor list. ' . format ( color ( str ( len ( nicks ) ) , cyan ) , color ( ' added ' , green ) ) )
elif args [ 2 ] [ : 1 ] == ' - ' :
nicks = [ mon_nick for mon_nick in set ( args [ 2 ] [ 1 : ] . split ( ' , ' ) ) if mon_nick in self . monlist ]
if nicks :
self . monitor ( ' - ' , nicks )
for mon_nick in nicks :
self . monlist . remove ( mon_nick )
self . sendmsg ( target , ' {0} nick(s) have been {1} from the monitor list. ' . format ( color ( str ( len ( nicks ) ) , cyan ) , color ( ' removed ' , red ) ) )
elif args [ 1 ] == ' relay ' :
if args [ 2 ] [ : 1 ] == ' + ' :
if args [ 2 ] [ 1 : ] . lower ( ) in self . relaylist :
self . sendmsg ( channel , ' {0} ' . format ( color ( ' already snitching on that channel ' , red ) ) )
else :
self . relaylist . append ( args [ 2 ] [ 1 : ] . lower ( ) )
self . sendmsg ( channel , ' {0} on {1} ' . format ( color ( ' snitching ' , red ) , color ( args [ 2 ] [ 1 : ] , red ) ) )
elif args [ 2 ] [ : 1 ] == ' - ' :
if args [ 2 ] [ 1 : ] . lower ( ) == ' all ' :
self . sendmsg ( channel , ' {0} on {1} {2} ' . format ( color ( ' ceased snitching ' , red ) , color ( ' all ' , yellow ) , color ( ' channels ' , red ) ) )
self . relaylist . clear ( )
elif args [ 2 ] [ 1 : ] . lower ( ) not in self . relaylist :
self . sendmsg ( channel , ' {0} ' . format ( color ( ' channel was not being snitched on ' , red ) ) )
else :
self . relaylist . remove ( args [ 2 ] [ 1 : ] . lower ( ) )
self . sendmsg ( channel , ' {0} on {1} ' . format ( color ( ' ceased all snitching ' , red ) , color ( args [ 2 ] [ 1 : ] , red ) ) )
elif args [ 1 ] == ' cover ' :
if args [ 2 ] [ : 1 ] == ' + ' :
if args [ 2 ] [ 1 : ] . lower ( ) in self . coverlist :
self . sendmsg ( channel , ' {0} ' . format ( color ( ' already watching that nigga \' s back ' , red ) ) )
else :
self . coverlist . append ( args [ 2 ] [ 1 : ] . lower ( ) )
self . sendmsg ( channel , ' got your back, {0} ' . format ( color ( args [ 2 ] [ 1 : ] , light_green ) ) )
elif args [ 2 ] [ : 1 ] == ' - ' :
if args [ 2 ] [ 1 : ] . lower ( ) == ' all ' :
self . sendmsg ( channel , ' {0} {1} {2} ' . format ( color ( ' ceased covering ' , red ) , color ( ' all ' , grey ) , color ( ' muhfuckas ' , red ) ) )
self . coverlist . clear ( )
elif args [ 2 ] [ 1 : ] . lower ( ) not in self . coverlist :
self . sendmsg ( channel , ' {0} ' . format ( color ( ' didnt have their back in the first place ' , red ) ) )
else :
self . coverlist . remove ( args [ 2 ] [ 1 : ] . lower ( ) )
self . sendmsg ( channel , ' no longer watching {0} \' s back ' . format ( color ( args [ 2 ] [ 1 : ] , light_green ) ) )
elif len ( args ) > = 4 and args [ 1 ] == " raw " :
if args [ 2 ] == " -d " :
data = " " . join ( args [ 3 : ] )
threading . Thread ( target = self . raw , args = ( data , True ) ) . start ( )
else :
data = " " . join ( args [ 2 : ] )
self . raw ( data )
elif target == self . nickname :
if msg . startswith ( ' \x01 ACTION ' ) :
self . sendmsg ( channel , ' [ {0} ] {1} {2} {3} * {4} ' . format ( color ( ' PM ' , red ) , color ( ' < ' , grey ) , color ( nick , yellow ) , color ( ' > ' , grey ) , msg [ 8 : ] [ : - 1 ] ) )
else :
self . sendmsg ( channel , ' [ {0} ] {1} {2} {3} {4} ' . format ( color ( ' PM ' , red ) , color ( ' < ' , grey ) , color ( nick , yellow ) , color ( ' > ' , grey ) , msg ) )
def event_kick ( self , ident , nick , chan , target ) :
if target == self . nickname :
self . sendmsg ( channel , " {0} from {1} by {2} {3} " . format ( color ( " kicked " , yellow ) , color ( chan , red ) , color ( nick , yellow ) , color ( " ;( " , white ) ) )
elif target . lower ( ) in self . coverlist and not is_admin ( ident ) :
self . raw ( " KICK {0} {1} :that shit outta here " . format ( chan , nick ) )
def event_mode ( self , nick , chan , modes ) :
# Todo: takeover mode to automatically jupe a channel upon +o
pass
def event_quit ( self , nick ) :
if nick in self . monlist :
self . nick ( nick )
def handle_events ( self , data ) :
args = data . split ( )
if data . startswith ( " ERROR :Closing Link: " ) :
raise Exception ( " Connection has closed. " )
elif data . startswith ( " ERROR :Reconnecting too fast " ) :
raise Exception ( " Connection has closed. (throttled) " )
elif args [ 0 ] == " PING " :
self . raw ( " PONG " + args [ 1 ] [ 1 : ] )
elif args [ 1 ] == " 001 " : # RPL_WELCOME
self . event_connect ( )
elif args [ 1 ] == " 433 " and len ( args ) > = 4 : # ERR_NICKNAMEINUSE
nick = args [ 2 ]
target_nick = args [ 3 ]
self . event_nick_in_use ( nick , target_nick )
elif args [ 1 ] == " 731 " and len ( args ) > = 4 : # RPL_MONOFFLINE
nick = args [ 3 ] [ 1 : ]
self . nick ( nick )
elif args [ 1 ] == " JOIN " and len ( args ) == 3 :
ident = args [ 0 ] [ 1 : ]
nick = args [ 0 ] . split ( " ! " ) [ 0 ] [ 1 : ]
chan = args [ 2 ] [ 1 : ]
self . event_join ( ident , nick , chan )
elif args [ 1 ] == " MODE " and len ( args ) > = 4 :
nick = args [ 0 ] . split ( " ! " ) [ 0 ] [ 1 : ]
chan = args [ 2 ]
modes = " " . join ( args [ : 3 ] )
self . event_mode ( nick , chan , modes )
elif args [ 1 ] == " NICK " and len ( args ) == 3 :
nick = args [ 0 ] . split ( " ! " ) [ 0 ] [ 1 : ]
new_nick = args [ 2 ] [ 1 : ]
self . event_nick ( nick , new_nick )
elif args [ 1 ] == " NOTICE " :
nick = args [ 0 ] . split ( " ! " ) [ 0 ] [ 1 : ]
target = args [ 2 ]
msg = " " . join ( args [ 3 : ] ) [ 1 : ]
self . event_notice ( nick , target , msg )
elif args [ 1 ] == " PRIVMSG " and len ( args ) > = 4 :
ident = args [ 0 ] [ 1 : ]
nick = args [ 0 ] . split ( " ! " ) [ 0 ] [ 1 : ]
target = args [ 2 ]
msg = " " . join ( args [ 3 : ] ) [ 1 : ]
if msg [ : 1 ] == " \001 " :
msg = msg [ 1 : ]
self . event_ctcp ( nick , target , msg )
else :
self . event_message ( ident , nick , target , msg )
elif args [ 1 ] == " QUIT " :
nick = args [ 0 ] . split ( " ! " ) [ 0 ] [ 1 : ]
self . event_quit ( nick )
elif args [ 1 ] == " KICK " :
ident = args [ 0 ] [ 1 : ]
nick = args [ 0 ] . split ( " ! " ) [ 0 ] [ 1 : ]
chan = args [ 2 ]
target = args [ 3 ]
self . event_kick ( ident , nick , chan , target )
def join_channel ( self , chan , key = None ) :
self . raw ( f " JOIN { chan } { key } " ) if key else self . raw ( " JOIN " + chan )
def listen ( self ) :
while True :
try :
data = self . sock . recv ( 1024 ) . decode ( " utf-8 " )
for line in ( line for line in data . split ( " \r \n " ) if len ( line . split ( ) ) > = 2 ) :
# debug(line)
self . handle_events ( line )
except ( UnicodeDecodeError , UnicodeEncodeError ) :
pass
except Exception as ex :
error ( " Unexpected error occured on ' {0} ' server. " . format ( self . server [ " server " ] ) , ex )
break
self . event_disconnect ( )
def mode ( self , target , mode ) :
self . raw ( f " MODE { target } { mode } " )
def monitor ( self , action , nicks = list ( ) ) :
self . raw ( f " MONITOR { action } " + " , " . join ( nicks ) )
def nick ( self , nick ) :
self . raw ( " NICK " + nick )
def raw ( self , data , delay = False ) :
if delay :
time . sleep ( random . randint ( 300 , 900 ) )
self . sock . send ( bytes ( data + " \r \n " , " utf-8 " ) )
def sendmsg ( self , target , msg ) :
self . raw ( f " PRIVMSG { target } : { msg } " )
# Main
for i in range ( concurrency ) :
for server in servers :
clone ( server , socket . AF_INET ) . start ( )
if ipv6 :
if set (
[
ip [ 4 ] [ 0 ]
for ip in socket . getaddrinfo ( server [ " server " ] , 6667 )
if " : " in ip [ 4 ] [ 0 ]
]
) :
clone ( server , socket . AF_INET6 ) . start ( )
while True :
input ( " " )