Compare commits

...

3 commits

Author SHA1 Message Date
a886b95db6 make enmul stepping smaller 2022-03-09 16:45:50 -07:00
7348ef0354 noun count should not be used to end sentances
what in the world was i thinking, and how did i not notice this sooner?
2022-03-09 14:00:51 -07:00
7af2f8f675 reformat with black 2022-01-26 21:26:57 -05:00
6 changed files with 377 additions and 285 deletions

58
bot.py
View file

@ -10,14 +10,22 @@ from ircrobots import ConnectionParams, SASLUserPass, SASLSCRAM
from auth import username, password, channel
import shared
def is_admin(func):
async def decorator(self, channel, nick, msg):
if nick.lower() in self.users and self.users[nick.lower()].account in self.admins:
if (
nick.lower() in self.users
and self.users[nick.lower()].account in self.admins
):
await func(self, channel, nick, msg)
else:
await message(self,'core',channel,'you do not have permission to do that')
await message(
self, "core", channel, "you do not have permission to do that"
)
return decorator
# def is_chanop(func):
@ -25,50 +33,54 @@ def command(commandname):
def decorator(func):
shared.commands[commandname] = func
return func
return decorator
def listener(listenername):
def decorator(func):
shared.listeners.append((listenername, func))
return func
return decorator
def rawm(rname):
def decorator(func):
shared.rawm[rname] = func
return func
return decorator
return decorator
async def message(self, channel, msg):
modname = os.path.splittext(os.path.basename(inspect.stack()[1].filename))[0]
await self.send(build("PRIVMSG",[channel,f'[\x036{modname}\x0f] {msg}']))
await self.send(build("PRIVMSG", [channel, f"[\x036{modname}\x0f] {msg}"]))
class Server(BaseServer):
async def line_read(self, line: Line):
if 'on_'+line.command.lower() in dir(self):
asyncio.create_task(self.__getattribute__('on_'+line.command.lower())(line))
if "on_" + line.command.lower() in dir(self):
asyncio.create_task(
self.__getattribute__("on_" + line.command.lower())(line)
)
for listener in shared.listeners:
if listener[0] == line.command:
asyncio.create_task(listener[1](self, line))
def line_preread(self, line: Line):
print(f"{self.name} < {line.format()}")
def line_presend(self, line: Line):
print(f"{self.name} > {line.format()}")
async def on_001(self, line):
asyncio.create_task(self.load_modules())
async def load_modules(self):
for i in [s for s in os.listdir('modules') if '.py' in s and '.swp' not in s]:
for i in [s for s in os.listdir("modules") if ".py" in s and ".swp" not in s]:
i = i[:-3]
m = importlib.import_module('modules.' + i)
m = importlib.import_module("modules." + i)
asyncio.create_task(m.init(self))
shared.modules[i] = m
@ -76,14 +88,12 @@ class Server(BaseServer):
async def message(self, channel, msg):
await self.send(build("PRIVMSG", [channel, msg]))
async def on_privmsg(self, line):
if line.tags and "batch" in line.tags and line.tags["batch"] == '1':
if line.tags and "batch" in line.tags and line.tags["batch"] == "1":
return
channel = line.params[0]
nick = line.source.split('!')[0]
nick = line.source.split("!")[0]
msg = line.params[1]
if nick == self.nickname:
@ -93,13 +103,15 @@ class Server(BaseServer):
await self.handle_rawm(channel, nick, msg)
await self.handle_command(channel, nick, msg)
async def handle_rawm(self, channel, nick, msg):
for i in shared.rawm:
await shared.rawm[i](self, channel, nick, msg)
async def handle_command(self, channel, nick, msg):
if msg[: len(shared.prefix)] == shared.prefix:
msg = msg[len(shared.prefix) :]
cmd = msg.split(' ')[0]
cmd = msg.split(" ")[0]
msg = msg[len(cmd) + 1 :]
if len(cmd) < 1:
return
@ -128,20 +140,18 @@ async def main():
port=6697,
tls=True,
sasl=sasl_params,
autojoin = channel)
autojoin=channel,
)
await bot.add_server("libera", params)
params = ConnectionParams(
"min",
host = "manonet.lumey.dev",
port = 6697,
tls = True,
autojoin = ['#manonet'])
"min", host="manonet.lumey.dev", port=6697, tls=True, autojoin=["#manonet"]
)
await bot.add_server("manonet", params)
await bot.run()
if __name__ == "__main__":
asyncio.run(main())

View file

@ -1,26 +1,25 @@
import importlib, time, asyncio, random
from bot import *
quitmessages = [
"time to die",
'you can hide, but you can not run!',
"you can hide, but you can not run!",
"you're next",
'bye',
'the balun has been popped.',
"bye",
"the balun has been popped.",
]
async def commit(self, chan, source, msg):
await self.quit('{} told me to commit {}'.format(source,msg))
await self.quit("{} told me to commit {}".format(source, msg))
async def quit(self, chan, source, msg):
await self.send(build("QUIT", [random.choice(quitmessages)]))
async def reloadmods(self, chan, source, msg):
await self.message(chan, '[\x036admin\x0f] reloading modules...')
await self.message(chan, "[\x036admin\x0f] reloading modules...")
shared.oldcmd = shared.commands
shared.commands = {}
shared.rawm = {}
@ -31,63 +30,77 @@ async def reloadmods(self, chan, source, msg):
importlib.reload(shared.modules[i])
await shared.modules[i].init(self)
# await self.message(chan, '[\x036admin\x0f] load {} sucess!'.format(i))
await self.message(chan, '[\x036admin\x0f] done! {} modules reloaded!'.format(len(shared.modules)))
await self.message(
chan,
"[\x036admin\x0f] done! {} modules reloaded!".format(len(shared.modules)),
)
except:
await self.message(chan, '[\x036admin\x0f] reload failed... attempting to recover...')
await self.message(
chan, "[\x036admin\x0f] reload failed... attempting to recover..."
)
shared.commands = shared.oldcmd
async def rawcmd(self, chan, source, msg):
await self.send_raw(msg)
async def joins(self, chan, source, msg):
await self.message(chan, '[\x036admin\x0f] joining slowly as to not flood...')
await self.message(chan, "[\x036admin\x0f] joining slowly as to not flood...")
for i in self.chandb.all():
await self.send(build("JOIN",[i['name']]))
await self.send(build("JOIN", [i["name"]]))
await asyncio.sleep(1)
print('joined {}'.format(i['name']))
await self.message(chan, '[\x036admin\x0f] Sucess! i may be laggy for a bit while i sort through all these channels...')
print("joined {}".format(i["name"]))
await self.message(
chan,
"[\x036admin\x0f] Sucess! i may be laggy for a bit while i sort through all these channels...",
)
async def aexec(self, code):
# Make an async function with the code and `exec` it
exec(
f'async def __ex(self): ' +
''.join(f'\n {l}' for l in code.split('\n'))
)
exec(f"async def __ex(self): " + "".join(f"\n {l}" for l in code.split("\n")))
# Get `__ex` from local variables, call it and return the result
return await locals()['__ex'](self)
return await locals()["__ex"](self)
async def ev(self, chan, source, msg):
msg = msg.split(' ')
msg = msg.split(" ")
try:
await self.message(chan, '[\x036admin\x0f] ok, output: {}'.format(
str(await aexec(self, ' '.join(msg)))[:400]
))
await self.message(
chan,
"[\x036admin\x0f] ok, output: {}".format(
str(await aexec(self, " ".join(msg)))[:400]
),
)
except:
await self.message(chan, '[\x036admin\x0f] exception in eval!')
await self.message(chan, "[\x036admin\x0f] exception in eval!")
async def send(self, c, n, m):
msg = m.split(' ')
await self.message(msg.pop(0), ' '.join(msg))
await self.message(c, '[\x036admin\x0f] sent')
msg = m.split(" ")
await self.message(msg.pop(0), " ".join(msg))
await self.message(c, "[\x036admin\x0f] sent")
async def shut(self, c, n, m):
shared.qtime[c] = time.time() + (60 * 10)
await self.message(c, '[\x036admin\x0f] Ok, il be back in 10 minutes')
await self.message(c, "[\x036admin\x0f] Ok, il be back in 10 minutes")
async def schans(self, c, n, m):
self.chandb.delete()
for i in self.channels:
self.chandb.insert(dict(name=i))
await self.message(c, '[\x036admin\x0f] Ok')
await self.message(c, "[\x036admin\x0f] Ok")
async def addalias(self, c, n, m):
al = m.split(' ')[0]
al = m.split(" ")[0]
m = m[len(al) + 1 :] # dont use the list since i want trailing spaces
if al in self.cmd:
await self.message(c,'[\x036admin\x0f] no dont overwrite a command dummy')
await self.message(c, "[\x036admin\x0f] no dont overwrite a command dummy")
return
self.cmd[al] = Alias(m).alias
@ -95,10 +108,10 @@ async def addalias(self,c,n,m):
async def addot(self, c, n, m):
al = m.split(' ')[0]
al = m.split(" ")[0]
m = m[len(al) + 1 :] # dont use the list since i want trailing spaces
if al in shared.rawm:
await self.message(c,'[\x036admin\x0f] no dont overwrite a command dummy')
await self.message(c, "[\x036admin\x0f] no dont overwrite a command dummy")
return
shared.rawm[al] = Ot(m, al).ot
@ -106,108 +119,142 @@ async def addot(self,c,n,m):
async def addspook(self, c, n, m):
al = m.split(' ')[0]
al = m.split(" ")[0]
m = m[len(al) + 1 :] # dont use the list since i want trailing spaces
if al in shared.rawm:
await self.message(c,'[\x036admin\x0f] no dont overwrite a command dummy')
await self.message(c, "[\x036admin\x0f] no dont overwrite a command dummy")
return
shared.rawm[al] = Spook(m, al).spook
await self.message(c, '[\x036admin\x0f] added "{}" trigger for "{}"'.format(al, m))
async def addtrigger(self, c, n, m):
al = m.split(' ')[0]
al = m.split(" ")[0]
m = m[len(al) + 1 :] # dont use the list since i want trailing spaces
if al in shared.rawm:
await self.message(c,'[\x036admin\x0f] no dont overwrite a command dummy')
await self.message(c, "[\x036admin\x0f] no dont overwrite a command dummy")
return
shared.rawm[al] = Trigger(m, al).trigger
await self.message(c, '[\x036admin\x0f] added "{}" trigger for "{}"'.format(al, m))
class Ot():
class Ot:
def __init__(self, ms, al):
self.ms = str(ms)
self.al = str(al)
async def ot(alself, self, c, n, m):
if alself.al in m and n != self.nickname:
asyncio.create_task(self.on_privmsg(build("PRIVMSG",[c,alself.ms.format(m)],n+'!spoof@spoof')))
asyncio.create_task(
self.on_privmsg(
build("PRIVMSG", [c, alself.ms.format(m)], n + "!spoof@spoof")
)
)
shared.rawm.pop(alself.al)
class Spook():
class Spook:
def __init__(self, ms, al):
self.ms = str(ms)
self.al = str(al)
async def spook(alself, self, c, n, m):
if alself.al in m and n != self.nickname:
asyncio.create_task(self.message(c, alself.ms.format(m)))
shared.rawm.pop(alself.al)
class Trigger():
class Trigger:
def __init__(self, ms, al):
self.ms = str(ms)
self.al = str(al)
async def trigger(alself, self, c, n, m):
if alself.al in m:
asyncio.create_task(self.on_privmsg(build("PRIVMSG",[c,alself.ms.format(m)],n+'!spoof@spoof')))
asyncio.create_task(
self.on_privmsg(
build("PRIVMSG", [c, alself.ms.format(m)], n + "!spoof@spoof")
)
)
class Alias():
class Alias:
def __init__(self, ms):
self.ms = str(ms)
async def alias(alself,self,c,n,m):
asyncio.create_task(self.on_privmsg(build("PRIVMSG",[c,alself.ms.format(m)],n+'!spoof@spoof')))
async def alias(alself, self, c, n, m):
asyncio.create_task(
self.on_privmsg(
build("PRIVMSG", [c, alself.ms.format(m)], n + "!spoof@spoof")
)
)
commands = {
'quit': quit,
'reload': reloadmods,
'commit': commit,
'raw': rawcmd,
'eval': ev,
'send': send,
'joins': joins,
'shut': shut,
'schans': schans,
'addalias': addalias,
'addtrigger': addtrigger,
'addot': addot,
'addspook': addspook,
"quit": quit,
"reload": reloadmods,
"commit": commit,
"raw": rawcmd,
"eval": ev,
"send": send,
"joins": joins,
"shut": shut,
"schans": schans,
"addalias": addalias,
"addtrigger": addtrigger,
"addot": addot,
"addspook": addspook,
}
@command('admin')
@command("admin")
@is_admin
async def adminHandle(self, chan, source, msg):
msg = msg.split(' ')
msg = msg.split(" ")
if len(msg) < 1 or not msg[0] in commands:
await self.message(chan, '[\x036admin\x0f] Invalid command')
await self.message(chan, "[\x036admin\x0f] Invalid command")
return
print('[ADMIN MODULE] {} told me to {}!!!'.format(source,msg[0]))
asyncio.create_task(commands[msg.pop(0)](self, chan, source, ' '.join(msg)))
print("[ADMIN MODULE] {} told me to {}!!!".format(source, msg[0]))
asyncio.create_task(commands[msg.pop(0)](self, chan, source, " ".join(msg)))
async def init(self):
self.chandb = shared.db['chan']
self.chandb = shared.db["chan"]
self.admins = ['xfnw']
self.admins = ["xfnw"]
return
self.cmd['admin'] = adminHandle
self.help['admin'] = ['admin - various bot owner commands (more for subcommands)', 'sub-commands of admin, for more info do help admin <command>: quit reload commit part join joins eval send']
self.help['admin quit'] = ['admin quit <message> - make the bot disconnect','no']
self.help['admin reload'] = ['admin reload - reload the modules and configs', 'nothing to see here']
self.help['admin commit'] = ['admin commit <action> - oh no (more)', 'suggested with <3 by khux']
self.help['admin part'] = ['admin part <channel> - leave a channel', ':o']
self.help['admin join'] = ['admin join <channel> - make the bot join a channel','...']
self.help['admin joins'] = ['admin joins - join more channels', 'dont reconnect to a bunch of chans when the bots crashing etc']
self.help['admin eval'] = ['admin eval <command> - absolute power corrupts absolutely', 'lmao']
self.help['admin send'] = ['admin send <channel> <message> - send a message', 'lmao']
self.help['admin schans'] = ['admin schans - save the commands to join',';p;']
self.cmd["admin"] = adminHandle
self.help["admin"] = [
"admin - various bot owner commands (more for subcommands)",
"sub-commands of admin, for more info do help admin <command>: quit reload commit part join joins eval send",
]
self.help["admin quit"] = ["admin quit <message> - make the bot disconnect", "no"]
self.help["admin reload"] = [
"admin reload - reload the modules and configs",
"nothing to see here",
]
self.help["admin commit"] = [
"admin commit <action> - oh no (more)",
"suggested with <3 by khux",
]
self.help["admin part"] = ["admin part <channel> - leave a channel", ":o"]
self.help["admin join"] = [
"admin join <channel> - make the bot join a channel",
"...",
]
self.help["admin joins"] = [
"admin joins - join more channels",
"dont reconnect to a bunch of chans when the bots crashing etc",
]
self.help["admin eval"] = [
"admin eval <command> - absolute power corrupts absolutely",
"lmao",
]
self.help["admin send"] = [
"admin send <channel> <message> - send a message",
"lmao",
]
self.help["admin schans"] = ["admin schans - save the commands to join", ";p;"]

View file

@ -1,9 +1,10 @@
from bot import *
@listener('INVITE')
@listener("INVITE")
async def on_invite(self, line):
self.send(build("JOIN", [line.params[1]]))
async def init(self):
pass

View file

@ -2,24 +2,26 @@ from bot import *
import dataset, random, time, re
def get(l, i):
try:
if i <= len(l) and i >= 0:
return l[i]
else:
return ''
return ""
except IndexError:
return ''
return ""
async def rec(self, m):
prew = shared.db['prew']
noch = shared.db['noun']
beg = shared.db['beg']
end = shared.db['end']
prew = shared.db["prew"]
noch = shared.db["noun"]
beg = shared.db["beg"]
end = shared.db["end"]
words = m.split()
if words[0] == 'admin' or len(words) < 2:
if words[0] == "admin" or len(words) < 2:
return
beg.insert(dict(word=words[0]))
@ -27,73 +29,103 @@ async def rec(self, m):
for w in range(len(words)):
if w > 0:
prew.insert_ignore(dict(pre3=get(words,w-3), pre2=get(words,w-2), pre=get(words,w-1), pro=get(words,w), pro2=get(words,w+1), pro3=get(words,w+2)),['id'])
prew.insert_ignore(
dict(
pre3=get(words, w - 3),
pre2=get(words, w - 2),
pre=get(words, w - 1),
pro=get(words, w),
pro2=get(words, w + 1),
pro3=get(words, w + 2),
),
["id"],
)
noch.insert(dict(word=w))
async def getNoun(self, words, c):
if c in shared.cstate:
oldnoun = shared.cstate[c]
else:
oldnoun = None
nouns = shared.db['noun']
nouns = shared.db["noun"]
out = {}
for i in words:
out[i] = nouns.count(word=i)
noun = min(out, key=out.get)
conversation = shared.db['conver']
conversation = shared.db["conver"]
if oldnoun != None:
print("adding", [oldnoun, noun])
conversation.insert_ignore(dict(pre=oldnoun,pro=noun),['id'])
conversation.insert_ignore(dict(pre=oldnoun, pro=noun), ["id"])
nextnoun = [i['pro'] for i in conversation.find(pre=noun)]
nextnoun = [i["pro"] for i in conversation.find(pre=noun)]
print("nextnoun:", nextnoun)
if len(nextnoun) > 0:
noun = random.choice(nextnoun)
shared.cstate[c] = noun
return noun
async def genOut(self, noun):
prew = shared.db['prew']
beg = shared.db['beg']
end = shared.db['end']
nouns = shared.db['noun']
prew = shared.db["prew"]
beg = shared.db["beg"]
end = shared.db["end"]
nouns = shared.db["noun"]
iter = 0
coun = 0
out = [noun]
while (beg.find_one(word=out[0]) is None or nouns.count(word=out[0])-1 > iter * shared.enmul) and iter < shared.maxiter:
while (
beg.find_one(word=out[0]) is None
or beg.count(word=out[0]) - 1 > iter * shared.enmul
) and iter < shared.maxiter:
try:
out = [ random.choice(list(prew.find(pro=out[0],pro2=out[1],pro3=out[2])))['pre'] ] + out
out = [
random.choice(list(prew.find(pro=out[0], pro2=out[1], pro3=out[2])))[
"pre"
]
] + out
except IndexError:
try:
out = [ random.choice(list(prew.find(pro=out[0],pro2=out[1])))['pre'] ] + out
out = [
random.choice(list(prew.find(pro=out[0], pro2=out[1])))["pre"]
] + out
except IndexError:
try:
out = [ random.choice(list(prew.find(pro=out[0])))['pre'] ] + out
out = [random.choice(list(prew.find(pro=out[0])))["pre"]] + out
except IndexError:
iter += 69
iter += 1
coun += 1
iter = 0
while (end.find_one(word=out[-1]) is None or nouns.count(word=out[-1])-1 > iter * shared.enmul) and iter < shared.maxiter:
while (
end.find_one(word=out[-1]) is None
or end.count(word=out[-1]) - 1 > iter * shared.enmul
) and iter < shared.maxiter:
try:
out.append(random.choice(list(prew.find(pre3=out[-3],pre2=out[-2],pre=out[-1])))['pro'])
out.append(
random.choice(list(prew.find(pre3=out[-3], pre2=out[-2], pre=out[-1])))[
"pro"
]
)
except IndexError:
try:
out.append(random.choice(list(prew.find(pre2=out[-2],pre=out[-1])))['pro'])
out.append(
random.choice(list(prew.find(pre2=out[-2], pre=out[-1])))["pro"]
)
except IndexError:
try:
out.append(random.choice(list(prew.find(pre=out[-1])))['pro'])
out.append(random.choice(list(prew.find(pre=out[-1])))["pro"])
except IndexError:
iter += 69
iter += 1
coun += 1
if coun <= 3:
shared.enmul -= 1
if coun <= 4:
shared.enmul -= 0.1
elif coun >= shared.maxiter:
shared.enmul += 1
shared.enmul += 0.1
return out
@ -104,10 +136,10 @@ async def filter(self, c, n, m):
if m[: len(shared.prefix)] == shared.prefix:
m = m[len(shared.prefix) :]
await go(self, c, n, m)
elif m[:len(self.nickname)+1] == self.nickname+' ':
elif m[: len(self.nickname) + 1] == self.nickname + " ":
m = m[len(self.nickname) + 1 :]
await go(self, c, n, m)
elif '#' not in c and n != self.nickname:
elif "#" not in c and n != self.nickname:
await go(self, c, n, m)
else:
if len(m.split()) > 1:
@ -115,16 +147,22 @@ async def filter(self, c, n, m):
await rec(self, m)
shared.learntime = time.time()
async def go(self, c, n, m):
await rec(self, m)
words = re.sub(r'([\.,\?!])', r' \1', m).split()
if words[0] == 'admin':
words = re.sub(r"([\.,\?!])", r" \1", m).split()
if words[0] == "admin":
return
msg = re.sub(r' ([\.,\?!])', r'\1', ' '.join(await genOut(self, await getNoun(self, words, c))))
msg = re.sub(
r" ([\.,\?!])",
r"\1",
" ".join(await genOut(self, await getNoun(self, words, c))),
)
if msg[-1] == "\x01" and msg[0] != "\x01":
msg = msg[:-1]
await self.message(c, msg)
async def init(self):
shared.qtime = {}
@ -136,8 +174,8 @@ async def init(self):
# sentance ending weight, lower means longer sentances,
# higher means shorter sentances. this will need to slowly
# get larger as the database grows
shared.enmul = 9
shared.enmul = 2
shared.maxiter = 14
shared.rawm['nlp'] = filter
shared.rawm["nlp"] = filter
shared.cstate = {}

View file

@ -2,13 +2,11 @@ import asyncio
import bot
@bot.command('test')
@bot.command("test")
@bot.is_admin
async def testy(self, channel, nick, msg):
await bot.message(self,channel,'hi there')
await bot.message(self, channel, "hi there")
async def init(self):
pass

View file

@ -1,12 +1,10 @@
import dataset
prefix = 'min: '
prefix = "min: "
modules = {}
listeners = []
commands = {}
rawm = {}
db = dataset.connect('sqlite:///database.db')
db = dataset.connect("sqlite:///database.db")
qtime = {}