bot6/stuff.py

288 lines
12 KiB
Python
Raw Permalink Normal View History

2021-09-16 17:35:06 +00:00
import irctokens
2021-09-19 16:56:17 +00:00
from config import config as Config
2021-09-16 17:35:06 +00:00
from util import Util
2021-09-19 16:56:17 +00:00
from commands import Command
from youtube import YouTube
2021-10-07 19:36:09 +00:00
import sys, importlib, time
2021-10-04 12:48:10 +00:00
2021-10-04 12:48:10 +00:00
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
2021-11-07 10:38:04 +00:00
chan = config.server.channel # main channel
autojoin_done = False
is_ctcp = False
2021-10-04 12:48:10 +00:00
is_pm = False
mode = "init"
2022-09-14 14:10:04 +00:00
nick_override = False
2021-10-04 12:48:10 +00:00
def auth(
nick=config.self.nick,
passwd=config.server.nickserv_pass,
auth="nickserv",
nickserv_auth=config.server.nickserv_auth,
):
2022-09-12 11:33:37 +00:00
# TODO: handle auth that isn't nickserv
if auth.lower() == "nickserv": # line.source.split("!")[0]
# TODO: on most network can probably do "PRIVMSG NickServ@services. :help"
# TODO: support actually checking the nickserv mask properly
if nickserv_auth:
nick_override = True
2022-10-22 18:13:58 +00:00
if config.server.nickserv_squery:
util.send(
irctokens.build(
"SQUERY", ["NickServ", f"IDENTIFY {nick} {passwd}"]
).format()
)
util.send(
irctokens.build(
"SQUERY",
["NickServ", f"{config.server.nickserv_recover} {nick}"],
).format()
)
else:
util.mesg(f"IDENTIFY {nick} {passwd}", config.server.nickserv_path)
util.mesg(
f"{config.server.nickserv_recover} {nick}",
config.server.nickserv_path,
)
# attempt to re-nick just in case
send(irctokens.build("NICK", [config.self.nick]).format())
def configure():
2021-10-04 12:48:10 +00:00
config = importlib.reload(sys.modules["config"]).config
util = Util(config, sock)
command = importlib.reload(sys.modules["commands"]).Command(config)
command.YouTube = importlib.reload(sys.modules["youtube"]).YouTube
2021-10-04 12:48:10 +00:00
command.util = util
command.YouTube.util = util
2021-10-04 12:48:10 +00:00
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
2021-09-16 17:35:06 +00:00
send(irctokens.build("NICK", [config.self.nick]).format())
2021-10-04 12:48:10 +00:00
send(
irctokens.build(
"USER", [config.self.username, "0", "*", config.self.realname]
).format()
)
2021-09-16 17:35:06 +00:00
while True:
self_nick = server.nickname
2021-10-04 12:48:10 +00:00
recv_data = sock.recv(1024)
2021-09-16 17:35:06 +00:00
recv_lines = server.recv(recv_data)
for line in recv_lines:
try:
server.parse_tokens(line)
except IndexError:
print("\x1b[31;1mNGIRCD SUCKS\x1b[0m ", line)
continue
stri = line.format()
for k, v in util.dict.items():
stri = stri.replace(k, v)
2021-10-07 19:36:09 +00:00
print(f"{time.strftime('%H:%M:%S')} < {stri}")
del stri
2021-09-16 17:35:06 +00:00
if line.command == "PING":
send(f"PONG :{line.params[0]}")
2021-10-04 12:48:10 +00:00
if mode == "init":
2022-10-22 18:13:58 +00:00
if line.command == "NOTICE" and line.source != None:
if util.maskmatch(line.source, config.server.nickserv_mask):
2022-02-07 16:28:19 +00:00
if config.server.nickserv_auth == True:
auth()
if line.command == "433": # 433 is ERR_NICKNAMEINUSE
2021-10-04 12:48:10 +00:00
util.nick(config.self.nick + "_")
if (
line.command == "376" or line.command == "422"
): # 376 is RPL_ENDOFMOTD and 422 is ERR_NOMOTD
if config.server.nickserv_auth == True:
auth()
2021-10-04 12:48:10 +00:00
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:
2021-09-16 17:35:06 +00:00
# send(irctokens.build("CAP", ["REQ",i]).format())
send(irctokens.build("CAP", ["END"]).format())
2021-10-04 12:48:10 +00:00
mode = "boot"
elif mode == "boot":
2021-09-16 17:35:06 +00:00
send(irctokens.build("JOIN", [chan]).format())
2021-10-04 12:48:10 +00:00
mode = "normal"
elif mode == "normal" and autojoin_done == False:
2021-11-07 10:38:04 +00:00
try:
for channel in config.server.autojoin:
send("JOIN " + channel)
2021-11-07 10:38:04 +00:00
time.sleep(0.25)
except Exception:
True
autojoin_done = True
2021-10-04 12:48:10 +00:00
elif mode == "normal":
2022-09-14 14:10:04 +00:00
if line.command == "433" and nick_override != False:
2021-10-04 12:48:10 +00:00
mesg("nick in use!", chan)
util.nick(config.self.nick)
2022-09-14 14:10:04 +00:00
nick_override = False
else:
nick_override = False
2021-09-16 17:35:06 +00:00
if line.command == "INVITE":
send(irctokens.build("JOIN", [line.params[1]]).format()) if line.params[1] not in config.server.blacklisted_channels else None
2021-09-16 17:35:06 +00:00
elif line.command == "PRIVMSG":
if line.tags == None or "batch" not in line.tags:
2021-10-04 12:48:10 +00:00
is_pm = False
is_ctcp = False
2021-10-04 12:48:10 +00:00
target = line.params[0]
if target == self_nick:
target = line.source.split("!")[0]
is_pm = True
util.target = target
command.util.target = target
cmd = line.params[1]
2022-09-14 14:54:53 +00:00
if cmd != "" and (
2022-09-14 14:14:43 +00:00
is_pm
or cmd.startswith(self_nick)
or cmd[0] in prefixes
or "https://" in cmd
or "http://" in cmd
2021-10-04 12:48:10 +00:00
):
# TODO: allow ignoring hostmasks
2022-10-05 02:24:25 +00:00
if line.hostmask.nickname in config.cmd.ignored_nicks:
continue
2021-09-21 17:41:31 +00:00
try:
2021-10-04 12:48:10 +00:00
# if message in a channel, remove prefixes
2021-10-05 13:18:25 +00:00
if is_pm:
command.prefix = None
else:
2021-09-21 17:41:31 +00:00
if cmd[0] in prefixes:
2021-10-04 12:48:10 +00:00
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
2021-09-21 17:41:31 +00:00
elif cmd.startswith(self_nick):
2021-10-04 12:48:10 +00:00
cmd = cmd.replace(self_nick, "", 1)
command.prefix = self_nick
2021-10-05 13:18:25 +00:00
else:
command.prefix = None
2021-09-21 17:41:31 +00:00
except IndexError:
2021-10-04 12:48:10 +00:00
continue # skip to next command
cmd = "echo IndexError or something"
try:
2021-10-05 13:18:25 +00:00
prefix = command.prefix or None
except UnboundLocalError or AttributeError:
prefix = None
2021-10-05 13:18:25 +00:00
command.prefix = prefix
2021-10-04 12:48:10 +00:00
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
2021-10-04 12:48:10 +00:00
is_adm = line.source in admin_users
# update command module's info dynamically for line info
2021-10-04 12:48:10 +00:00
command.util.target = target
command._line = line
command.is_ctcp = is_ctcp
2021-10-04 12:48:10 +00:00
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()
2021-10-04 12:48:10 +00:00
util.target = target
send = util.send
2021-10-04 12:48:10 +00:00
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
2021-10-04 12:48:10 +00:00
command.util.target = target
2021-09-19 16:56:17 +00:00
mesg("reloaded")
2021-10-04 12:48:10 +00:00
elif (
cmd.startswith("eval ")
and "eval" not in config.cmd.disabled
):
if is_adm:
2021-09-16 17:35:06 +00:00
try:
2021-10-04 12:48:10 +00:00
result = eval(
cmd[len("eval ") :].strip() or "None"
)
2021-09-16 17:35:06 +00:00
except Exception as e:
2021-10-04 12:48:10 +00:00
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:
2021-10-04 12:48:10 +00:00
result = exec(
cmd[len("exec ") :].strip() or "None"
)
except Exception as e:
2021-10-04 12:48:10 +00:00
mesg("Error: " + str(e))
else:
mesg("Error: you're not authorized to exec")
2021-10-04 12:48:10 +00:00
# handle normal commands
else:
command.preq_cmd()