import irctokens from config import config as Config from util import Util from commands import Command import sys, importlib, time def stuff(bot, sock): config = Config util = Util(config, sock) command = Command(config) server = bot.server send = util.send def mesg(msg: str, t=None): util.mesg(msg, t) # mesg=util.mesg server_caps = [] wanted_caps = config.capabilities chan = config.server.channel # main channel autojoin_done=False is_pm = False mode = "init" def configure(): config = importlib.reload(sys.modules["config"]).config util = Util(config, sock) command = importlib.reload(sys.modules["commands"]).Command(config) command.util = util prefixes = config.cmd.prefixes admin_accounts = config.admin.accounts admin_users = config.admin.hostmasks admin_only = config.cmd.admin_only return ( command, command.util, config, util, prefixes, admin_accounts, admin_users, admin_only, ) command, command.util, config, util, prefixes, admin_accounts, admin_users, admin_only = ( configure() ) send = util.send send(irctokens.build("NICK", [config.self.nick]).format()) send( irctokens.build( "USER", [config.self.username, "0", "*", config.self.realname] ).format() ) while True: self_nick = server.nickname recv_data = sock.recv(1024) recv_lines = server.recv(recv_data) for line in recv_lines: server.parse_tokens(line) stri = line.format() for k, v in util.dict.items(): stri = stri.replace(k, v) print(f"{time.strftime('%H:%M:%S')} < {stri}") del stri if line.command == "PING": send(f"PONG :{line.params[0]}") if mode == "init": if line.command == "433": util.nick(config.self.nick + "_") if line.command == "376": send(irctokens.build("CAP", ["LS", "302"]).format()) elif line.command == "CAP" and line.params[1] == "LS": if server_caps == []: server_caps = line.params[2].split() caps = [value for value in wanted_caps if value in server_caps] # single-send is more efficient # BUT a single invalid cap == no caps enabled at all!!! send(irctokens.build("CAP", ["REQ", " ".join(caps)]).format()) # for i in caps: # send(irctokens.build("CAP", ["REQ",i]).format()) send(irctokens.build("CAP", ["END"]).format()) mode = "boot" elif mode == "boot": send(irctokens.build("JOIN", [chan]).format()) mode = "normal" elif mode == "normal" and autojoin_done==False: try: for channel in config.server.autojoin: send("JOIN "+channel) time.sleep(0.25) except Exception: True autojoin_done=True elif mode == "normal": if line.command == "433": mesg("nick in use!", chan) util.nick(config.self.nick) if line.command == "INVITE": send(irctokens.build("JOIN", [line.params[1]]).format()) elif line.command == "PRIVMSG": if line.tags == None or "batch" not in line.tags: is_pm = False target = line.params[0] if target == self_nick: target = line.source.split("!")[0] is_pm = True util.target = target command.util.target = target if ( is_pm or line.params[1].startswith(self_nick) or line.params[1][0] in prefixes or line.params[1].startswith("https://") ): try: cmd = line.params[1] # if message in a channel, remove prefixes if is_pm: command.prefix = None else: if cmd[0] in prefixes: cmd = cmd.replace(cmd[0], "", 1) command.prefix = cmd[0] elif cmd.startswith(self_nick + ":"): cmd = cmd.replace(self_nick + ":", "", 1) command.prefix = self_nick elif cmd.startswith(self_nick): cmd = cmd.replace(self_nick, "", 1) command.prefix = self_nick else: command.prefix = None except IndexError: continue # skip to next command cmd = "echo IndexError or something" try: prefix = command.prefix or None except UnboundLocalError or AttributeError: prefix = None command.prefix = prefix cmd = cmd.strip() try: is_adm = ( line.tags["account"] in admin_accounts or line.source in admin_users ) except (KeyError, TypeError): #either no account tag, or no tags at all is_adm = line.source in admin_users # update command module's info dynamically for line info command.util.target = target command._line = line command.pm = is_pm command.line = cmd command.admin = is_adm command.config = config command.self_nick = self_nick command.prefix = prefix if is_adm and cmd.startswith("reload"): command, command.util, config, util, prefixes, admin_accounts, admin_users, admin_only = ( configure() ) util.target = target send = util.send command._line = line command.pm = is_pm command.line = cmd command.admin = is_adm command.config = config command.self_nick = self_nick command.prefix = prefix command.util = util command.util.target = target mesg("reloaded") elif ( cmd.startswith("eval ") and "eval" not in config.cmd.disabled ): if is_adm: try: result = eval( cmd[len("eval ") :].strip() or "None" ) except Exception as e: mesg("Error: " + str(e)) else: mesg("Error: you're not authorized to eval") elif ( cmd.startswith("exec ") and "exec" not in config.cmd.disabled ): if is_adm: try: result = exec( cmd[len("exec ") :].strip() or "None" ) except Exception as e: mesg("Error: " + str(e)) else: mesg("Error: you're not authorized to exec") # handle normal commands else: command.preq_cmd()