added ctcp and internal commands and escapes for \x00-\x1f bytes

This commit is contained in:
jan6 2021-10-04 18:49:05 +03:00
parent c25407dd33
commit a7eac6a0b0
4 changed files with 91 additions and 7 deletions

View File

@ -1,3 +1,6 @@
from functools import wraps
class Command:
def __init__(self, config):
self.config = config
@ -6,10 +9,14 @@ class Command:
def mesg(self, msg):
self.util.mesg(msg)
def send(self, msg):
self.util.send(msg)
def err_perm(self, level="admin"):
self.mesg(f"Error: insufficient privileges, you lack {level} access")
def adm(func, *args, **kwargs):
"""decorator for admin commands"""
global adm_cmds
try:
if func.__name__ not in adm_cmds and func.__name__ != "_":
@ -19,6 +26,7 @@ class Command:
if func.__name__ not in adm_cmds and func.__name__ != "_":
adm_cmds.append(func.__name__)
@wraps(func)
def _(self, *args, **kwargs):
if func.__name__ == "help":
self.admin_commands = adm_cmds
@ -40,6 +48,7 @@ class Command:
return _
def cmd(func, *args, **kwargs):
"""decorator for user commands"""
global cmds
try:
if func.__name__ not in cmds and func.__name__ != "_":
@ -49,6 +58,7 @@ class Command:
if func.__name__ not in cmds and func.__name__ != "_":
cmds.append(func.__name__)
@wraps(func)
def _(self, *args, **kwargs):
if func.__name__ == "help":
self.commands = cmds
@ -66,6 +76,13 @@ class Command:
return _
def internal(func, *args, **kwargs):
"""decorator for commands like ctcp which are for internal use, but use normal args template"""
global cmds
if func.__name__ in cmds:
cmds.remove(func.__name__)
return func
def preq_cmd(self): # command prequisites / triggers
cmd = self.line
if cmd == "help" or cmd.startswith("help "):
@ -76,11 +93,31 @@ class Command:
command = "dbg"
elif cmd == "dbg2" or cmd.startswith("dbg2 "):
command = "dbg2"
elif cmd.startswith("\x01"):
command = "ctcp"
else:
return
if command not in self.config.cmd.disabled:
eval(f"self.{command}()")
@internal
@cmd
def ctcp(self, prefix, cmd, pm, line, admin, mesg):
"""CTCP responses"""
ctcp = cmd[1:]
if ctcp.startswith("PING"):
if not ctcp.endswith("\x01"):
ctcp = ctcp + "\x01"
self.send(f"NOTICE {self.util.target} \x01" + ctcp)
elif ctcp.startswith("SOURCE"):
self.send(
f"NOTICE {self.util.target} \x01SOURCE "
+ self.config.self.source
+ "\x01"
)
elif ctcp.startswith("CLIENTINFO"):
self.send(f"NOTICE {self.util.target} \x01CLIENTINFO PING SOURCE\x01")
@adm
def quit(self, prefix, cmd, pm, line, admin, mesg):
if admin and (cmd == "q" or cmd == "quit"):
@ -88,10 +125,6 @@ class Command:
elif is_adm and (cmd.startswith("q ") or cmd.startswith("quit ")):
self.util.quit(cmd.split(" ", 1)[1])
@adm
def dbg2(self, prefix, cmd, pm, line, admin, mesg):
mesg(dir(self))
@adm
def dbg(self, prefix, cmd, pm, line, admin, mesg):
"""temporary debug command, subject to change A LOT"""

View File

@ -3,6 +3,7 @@ class config:
nick = "bot6"
username = "jan6_bot"
realname = "jan6's bot"
source = "https://tildegit.org/jan6/bot6"
class server:
name = "tilde.chat"

View File

@ -45,6 +45,7 @@ def stuff(bot, sock):
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(
@ -59,7 +60,11 @@ def stuff(bot, sock):
for line in recv_lines:
server.parse_tokens(line)
print(f"< {line.format()}")
stri = line.format()
for k, v in util.dict.items():
stri = stri.replace(k, v)
print(f"< {stri}")
del stri
if line.command == "PING":
send(f"PONG :{line.params[0]}")
@ -120,7 +125,10 @@ def stuff(bot, sock):
except IndexError:
continue # skip to next command
cmd = "echo IndexError or something"
prefix = prefix or None
try:
prefix = prefix or None
except UnboundLocalError:
prefix = None
cmd = cmd.strip()
try:
is_adm = (
@ -129,6 +137,8 @@ def stuff(bot, sock):
)
except KeyError:
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
@ -137,11 +147,13 @@ def stuff(bot, sock):
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
@ -149,6 +161,7 @@ def stuff(bot, sock):
command.config = config
command.self_nick = self_nick
command.prefix = prefix
command.util = util
command.util.target = target
mesg("reloaded")
elif (

39
util.py
View File

@ -6,9 +6,46 @@ class Util:
self.sock = sock
self.config = config
self.target = ""
self.dict = {
"\x00": "\\x00",
"\x01": "\\x01",
"\x02": "\\x02",
"\x03": "\\x03",
"\x04": "\\x04",
"\x05": "\\x05",
"\x06": "\\x06",
"\x07": "\\x07",
"\x08": "\\x08",
"\x09": "\\x09",
"\x0a": "\\x0a",
"\x0b": "\\x0b",
"\x0c": "\\x0c",
"\x0d": "\\x0d",
"\x0e": "\\x0e",
"\x0f": "\\x0f",
"\x10": "\\x10",
"\x11": "\\x11",
"\x12": "\\x12",
"\x13": "\\x13",
"\x14": "\\x14",
"\x15": "\\x15",
"\x16": "\\x16",
"\x17": "\\x17",
"\x18": "\\x18",
"\x19": "\\x19",
"\x1a": "\\x1a",
"\x1b": "\\x1b",
"\x1c": "\\x1c",
"\x1d": "\\x1d",
"\x1e": "\\x1e",
"\x1f": "\\x1f",
}
def send(self, raw: str):
print(f"> {raw}")
stri = raw
for k, v in self.dict.items():
stri = stri.replace(k, v)
print(f"> {stri}")
self.sock.sendall(f"{raw}\r\n".encode("utf8"))
def quit(self, msg=None):