bot6/stuff.py

209 lines
9.0 KiB
Python
Executable File

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()