IRCUFC/irc/irc.py

179 lines
5.3 KiB
Python
Raw Normal View History

2018-06-28 08:00:12 +00:00
#!/usr/bin/python3
import sys, socket, ssl, time, os, re
2018-07-03 09:15:38 +00:00
sys.dont_write_bytecode = True
os.chdir(sys.path[0] or ".")
sys.path += ("..", "../IRCUFC")
import ircEvents
2018-06-28 08:00:12 +00:00
from log import Colors, Log
from mircformat import MIRCFormat
from ircReload import recompile
from ircCommands import IrcCommands
2018-06-29 09:33:32 +00:00
server = 'irc.underworld.no'
2018-06-28 08:00:12 +00:00
port = 9999
2018-06-28 10:24:40 +00:00
channel = ('#IRCUFC', None) # (chan, key)
2018-06-28 08:00:12 +00:00
use_ssl = True
2018-06-28 10:24:40 +00:00
nickname = 'IRCUFC'
username = 'McBuffer'
realname = '** WE FIGHTIN **'
2018-06-28 08:00:12 +00:00
optkey= "!"
DEBUG = True
2018-07-03 09:15:38 +00:00
class IrcBot(object):
2018-06-28 08:00:12 +00:00
def __init__(self):
self.sock = None
self.lag = False
2018-06-28 08:00:12 +00:00
self.last_cmd = {}
self.flood_flag = {}
self.flood_count = {}
self.timeouts = {}
2018-06-28 08:00:12 +00:00
self.mirc = MIRCFormat()
self.log = Log(DEBUG)
self.cmds = IrcCommands(self)
2018-06-28 08:00:12 +00:00
self.server = server
self.port = port
self.ssl = use_ssl
2018-06-28 08:00:12 +00:00
self.nick = nickname
self.user = username
self.real = realname
2018-06-28 08:00:12 +00:00
self.optkey = optkey
2018-06-28 08:00:12 +00:00
self.channel,self.chankey = channel
2018-06-28 08:00:12 +00:00
def connect(self):
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if use_ssl:
self.sock = ssl.wrap_socket(self.sock)
self.sock.connect((server, port))
except Exception as e:
self.log.error("Connexion failed", e)
return
def run(self):
self.connect()
self.register()
self.listen()
def register(self):
self.raw("USER {} 0 * :{}".format(self.user, self.real))
self.raw("NICK {}".format(self.nick))
def updateNick(self):
self.raw("NICK {}".format(self.nick))
def listen(self):
while True:
2018-06-29 12:16:26 +00:00
try:
if self.lag:
self.lag=False
data += self.sock.recv(1024).decode('utf-8', 'ignore')
else:
data = self.sock.recv(1024).decode('utf-8', 'ignore')
for line in [x.split() for x in data.split("\r\n") if len(x.split()) > 1]:
self.log.info("<< {}".format(' '.join(line)))
if line[0][1:] == 'ING':
2018-07-03 09:15:38 +00:00
ircEvents.eventPING(self, line)
2018-06-29 12:16:26 +00:00
2018-07-03 09:15:38 +00:00
else:
try:
2018-07-03 15:20:29 +00:00
if hasattr(ircEvents, "event{}".format(line[1].upper())):
getattr(ircEvents, "event{}".format(line[1].upper()))(self, line)
except Exception as e:
self.log.error("Error in getattr()", e)
2018-07-03 09:15:38 +00:00
pass
2018-06-29 12:16:26 +00:00
except (UnicodeDecodeError, UnicodeEncodeError):
pass
except KeyboardInterrupt:
self.log.warn("^C, Exiting...")
return
except Exception as e:
self.log.error("Exception in listen()", e)
pass
2018-06-28 08:00:12 +00:00
def join(self):
self.raw("JOIN {} {}".format(self.channel, self.chankey)) if self.chankey else self.raw("JOIN {}".format(self.channel))
def raw(self, msg, timeout=None):
msg = msg.replace("\r", "")
msg = msg.replace("\n", "")
self.log.info(">> " + msg)
self.sock.send(bytes(msg + "\r\n", 'utf-8'))
if timeout:
time.sleep(timeout)
def isAdmin(self, ident):
ret = False
2018-07-03 09:15:38 +00:00
for line in [line.strip() for line in open('assets/admins', 'r').readlines() if line]:
2018-06-28 08:00:12 +00:00
if re.compile(line.replace('*', '.*')).search(ident):
ret = True
return ret
def handle_msg(self, chan, admin, nick, user, host, msg):
args = msg.split()
if admin:
if args[0] == '{}reload'.format(self.optkey):
ret = recompile(args[1]) # Let you add new code to the bot without restarting it
if ret == True:
2018-06-28 10:24:40 +00:00
self.privmsg(chan, "{} recompiled successfully!".format(self.mirc.color(args[1], self.mirc.colors.GREEN)))
2018-06-28 08:00:12 +00:00
return
else:
2018-06-28 10:24:40 +00:00
self.privmsg(chan, "Man we had a issue while recompiling {}".format(self.mirc.color(args[1], self.mirc.colors.GREEN)))
2018-06-28 08:00:12 +00:00
self.log.error(ret)
return
self.cmds.handle_msg(chan, admin, nick, user, host, msg)
def privmsg(self, chan, msg):
if chan not in self.timeouts:
self.timeouts[chan] = {'last_cmd': time.time(), 'burst': 0, 'timeout': 0}
self.raw("PRIVMSG {} :{}".format(chan, msg), self.timeouts[chan]['timeout'])
2018-06-28 10:24:40 +00:00
self.editTimeouts(chan)
2018-06-28 08:00:12 +00:00
2018-06-28 10:24:40 +00:00
def editTimeouts(self, chan):
2018-06-28 08:00:12 +00:00
if (time.time() - self.timeouts[chan]['last_cmd']) < 3:
self.timeouts[chan]['burst'] += 1
else:
self.timeouts[chan]['burst'] = 0
if self.timeouts[chan]['burst'] > 3:
self.timeouts[chan]['timeout'] += 0.075
else:
self.timeouts[chan]['timeout'] = 0
if self.timeouts[chan]['timeout'] > 0.4:
self.timeouts[chan]['timeout'] = 0.4
self.timeouts[chan]['last_cmd'] = time.time()
def action(self, chan, msg):
self.privmsg(chan, "\x01ACTION {}\x01".format(msg))