# PyBot v1.2 - by Ikewise, with help from Adrian Malacoda # Based on code by chevloschelios: # http://ubuntuforums.org/showthread.php?t=1493702 import socket import datetime botversion = '1.2' server = '127.0.0.1' port = 6667 channel = '#lobby' botnick = 'PyBot' def say(sendtarget, sendmsg): time = datetime.datetime.now().strftime('[%H:%M:%S]') irc.send(bytes('PRIVMSG ' + sendtarget +' :'+ sendmsg +'\r\n', 'UTF-8')) if sendtarget.startswith('#'): print(sendtarget + ': ' + time + ' <' + botnick + '> ' + sendmsg) else: print('DIRECT (' + sendtarget + '): ' + time + ' <' + botnick + '> ' + sendmsg) def notice(sendtarget, sendmsg): time = datetime.datetime.now().strftime('[%H:%M:%S]') irc.send(bytes('NOTICE ' + sendtarget +' :'+ sendmsg +'\r\n', 'UTF-8')) if sendtarget.startswith('#'): print(sendtarget + ': ' + time + ' * NOTICE: -' + botnick + '- ' + sendmsg) else: print('DIRECT (' + sendtarget + '): ' + time + ' * NOTICE: -' + botnick + '- ' + sendmsg) def ctcp(sendtype, sendtarget, sendmsg): time = datetime.datetime.now().strftime('[%H:%M:%S]') irc.send(bytes(sendtype + ' ' + sendtarget +' :\x01'+ sendmsg +'\x01\r\n', 'UTF-8')) if sendtarget.startswith('#'): if sendtype == 'PRIVMSG': if sendmsg.startswith('ACTION'): print(sendtarget + ': ' + time + ' * ' + botnick + ' ' + sendmsg[7:]) else: print(sendtarget + ': ' + time + ' * CTCP SEND: [' + botnick + ' -> ' + sendtarget + '] ' + sendmsg) if sendtype == 'NOTICE': print(sendtarget + ': ' + time + ' * CTCP RESPOND: [' + botnick + ' -> ' + sendtarget + '] ' + sendmsg) else: if sendtype == 'PRIVMSG': if sendmsg.startswith('ACTION'): print('DIRECT (' +sendtarget + '): ' + time + ' * ' + botnick + ' ' + sendmsg[7:]) else: print('DIRECT (' + sendtarget + '): ' + time + ' * CTCP SEND: [' + botnick + ' -> ' + sendtarget + '] ' + sendmsg) if sendtype == 'NOTICE': print('DIRECT (' + sendtarget + '): ' + time + ' * CTCP RESPOND: [' + botnick + ' -> ' + sendtarget + '] ' + sendmsg) def join(chan): irc.send(bytes('JOIN :'+ chan +'\r\n', 'UTF-8')) #say(chan, 'Hello '+ chan +'!') def part(chan): irc.send(bytes('PART '+ chan +'\r\n', 'UTF-8')) def logoff(sendmsg): irc.send(bytes('QUIT :'+ sendmsg +'\r\n', 'UTF-8')) # Program begins print('Connecting to ' + server + ':' + str(port) + '...') print() irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) irc.connect((server, port)) irc.send(bytes('NICK '+ botnick +'\n', 'UTF-8')) irc.send(bytes('USER '+ botnick +' '+ botnick +' '+ botnick +' :Python IRC bot\r\n', 'UTF-8')) while True: sender, hostmask, datatype, target, data, kicktarget = ['','','','','',''] rawdata = str(irc.recv(4096)) if rawdata == "b''": # Detect connection loss break rawdata = rawdata[2:len(rawdata) - 5].split('\\r\\n:') for i in rawdata: timestamp = datetime.datetime.now().strftime('[%H:%M:%S]') if i.startswith('PING'): # Respond to server pings irc.send(bytes('PONG ' + i.split()[1] + '\r\n', 'UTF-8')) if 'End of /MOTD command' in i: join(channel) if i.startswith(':'): # Break the raw data down into something usable data = i.lstrip(':') sender = data[0:data.find('!')] hostmask = data[data.find('!') + 1:data.find(' ')] data = data[data.find(' ') + 1:] datatype = data[0:data.find(' ')] data = data[data.find(' ') + 1:] if not datatype in ['QUIT', 'NICK', 'JOIN', 'PART', 'KICK']: target = data[0:data.find(' ')] data = data[data.find(' ') + 1:] if datatype in ['QUIT', 'NICK']: target = '' if datatype == 'JOIN': target = data data = '' if datatype == 'PART': if ' ' in data: target = data[0:data.find(' ')] data = data[data.find(' ') + 2:] else: target = data data = '' if datatype == 'KICK': target = data[0:data.find(' ')] data = data[data.find(' ') + 1:] kicktarget = data[0:data.find(' ')] data = data[data.find(' ') + 1:] target = target.lstrip(':') if datatype in ['PRIVMSG', 'NOTICE', 'NICK', 'INVITE', 'TOPIC', 'KICK', 'JOIN', 'QUIT']: data = data[1:] msg = data.lower() # Print formatted data to console if datatype == 'QUIT': if len(data) > 0: print('GLOBAL: ' + timestamp + ' * Quits: ' + sender + ' (' + hostmask + ') (' + data + ')') else: print('GLOBAL: ' + timestamp + ' * Quits: ' + sender + ' (' + hostmask + ')') if datatype == 'JOIN': print(target + ': ' + timestamp + ' * Joins: ' + sender + ' (' + hostmask + ')') if datatype == 'PART': if len(data) > 0: print(target + ': ' + timestamp + ' * Parts: ' + sender + ' (' + hostmask + ') (' + data + ')') else: print(target + ': ' + timestamp + ' * Parts: ' + sender + ' (' + hostmask + ')') if datatype == 'KICK': print(target + ': ' + timestamp + ' * ' + kicktarget + ' was kicked by ' + sender + ' (' + data + ')') if kicktarget == botnick: # Auto-Rejoin when kicked join(target) if datatype == 'MODE': print(target + ': ' + timestamp + ' * ' + sender + ' sets mode: ' + data) if datatype == 'TOPIC': print(target + ': ' + timestamp + ' * ' + sender + ' changes topic to \'' + data + '\'') if datatype == 'INVITE': print('DIRECT (' + sender + '): ' + timestamp + ' * INVITE to join ' + data + ' from ' + sender + ' (' + hostmask + ')') join(data) if datatype == 'NICK': print('GLOBAL: ' + timestamp + ' * ' + sender + ' is now known as ' + data) if datatype == 'NOTICE': if not target.startswith('#'): target = sender print('DIRECT (' + sender + '): ' + timestamp + ' * NOTICE: -' + sender + '- ' + data) else: print(target + ': ' + timestamp + ' * NOTICE: -' + sender + '- ' + data) if datatype == 'PRIVMSG': # If a channel if target.startswith('#'): if data.startswith('\\x01'): if data.startswith('\\x01ACTION'): print(target + ': ' + timestamp + ' * ' + sender + ' ' + data[11:len(data) - 4]) else: if ' ' in data: print(target + ': ' + timestamp + ' * CTCP: [' + sender + ':' + target + ' ' + data[4:data.find(' ')] + '] ' + data[data.find(' ') + 1:len(data) - 4]) if data.startswith('\\x01PING'): ctcp('NOTICE', sender, data[4:len(data) - 4]) else: print(target + ': ' + timestamp + ' * CTCP: [' + sender + ':' + target + ' ' + data[4:len(data) - 4] + ']') if data.startswith('\\x01TIME'): ctcp('NOTICE', sender, datetime.datetime.now().strftime('TIME %a %b %d %H:%M:%S %Y')) if data.startswith('\\x01VERSION'): ctcp('NOTICE', sender, 'VERSION PyBot v' + botversion + ' by Ikewise') else: print(target + ': ' + timestamp + ' <' + sender + '> ' + data) # If not a channel else: target = sender if data.startswith('\\x01'): if data.startswith('\\x01ACTION'): print('DIRECT (' + sender + '): ' + timestamp + ' * ' + sender + ' ' + data[11:len(data) - 4]) else: if ' ' in data: print('DIRECT (' + sender + '): ' + timestamp + ' * CTCP: [' + sender + ' ' + data[4:data.find(' ')] + '] ' + data[data.find(' ') + 1:len(data) - 4]) if data.startswith('\\x01PING'): ctcp('NOTICE', sender, data[4:len(data) - 4]) else: print('DIRECT (' + sender + '): ' + timestamp + ' * CTCP: [' + sender + ' ' + data[4:len(data) - 4] + ']') if data.startswith('\\x01TIME'): ctcp('NOTICE', sender, datetime.datetime.now().strftime('TIME %a %b %d %H:%M:%S %Y')) if data.startswith('\\x01VERSION'): ctcp('NOTICE', sender, 'VERSION PyBot v' + botversion + ' by Ikewise') else: print('DIRECT (' + sender + '): ' + timestamp + ' <' + sender + '> ' + data) if datatype == 'PRIVMSG': # PyBot main commands begin here if (msg == '!quit') and (sender == 'Ikewise'): logoff('Shutdown command from ' + sender) if msg == '!part': part(target) if msg.startswith('!slap'): ctcp('PRIVMSG', target, 'ACTION slaps ' + sender + ' around a bit with a large trout') if msg == 'chk': say(target, sender + ': ack') if msg == '.': say(target, 'omg a meteor') if msg.startswith('hi '+ botnick.lower()): say(target, 'Hello, ' + sender + '!') if msg.startswith('hello '+ botnick.lower()): say(target, 'Greetings, ' + sender + '!') if ('slaps '+ botnick.lower()) in msg: say(target, 'This is the Trout Protection Agency. Please put the Trout Down and walk away with your hands in the air.') # End of program print() print('Connection terminated.')