pychaos/bot.py

288 lines
13 KiB
Python
Raw Normal View History

2021-04-03 20:20:45 -05:00
#!/bin/python
import asyncio
import time
import sys
from irctokens import build, Line
from ircrobots import Bot as BaseBot
from ircrobots import Server as BaseServer
from ircrobots import ConnectionParams
from ircrobots.glob import compile as gcompile
SERVERS = [
("tilde", "localhost")
]
SPAMSERVERS = [
("0", "localhost"),
("1", "localhost"),
("2", "localhost"),
("3", "localhost"),
("4", "localhost"),
("5", "localhost"),
("6", "localhost"),
("7", "localhost"),
("8", "localhost"),
("9", "localhost"),
("10", "localhost"),
("11", "localhost"),
("12", "localhost"),
("13", "localhost"),
("14", "localhost"),
("15", "localhost"),
("16", "localhost"),
("17", "localhost"),
("18", "localhost"),
("19", "localhost"),
]
KICKEES = []
KICKEES_HOSTMASK = []
EXEMPT = []
MESSAGES = {
"revenge": "no u",
"kick": "error 418",
"quit": "bonk",
"kickadd": "user added to kicklist",
"kickadderr": "adding failed: user on exemption list",
"kicklist": "kickees: ",
"kickrm": "user removed from kicklist",
"kickrmerr": "error removing user from kicklist",
"exemptadd": "user added to exemptlist",
"exemptlist": "exempt: ",
"exemptrm": "user removed from exemptlist",
"exemptrmerr": "error removing user from exemptlist",
"writeexempt": "writing exempt data",
"writekickee": "writing kickee data",
"writekickeehostmask": "writing kickee_hostmask data",
"writedone": "done!",
"writeerr": "error writing files"
}
CHANNEL = "#chaos"
PASSWORD = "hellothereperson"
BOTNAME = "rndbot"
OWNER = "rndusr"
TOPIC = "rule one: you are now a duck. ・゜゜・。。・゜゜\\_o< QUACK!"
SPAMUSER = ""
LOGFILE = open(CHANNEL + ".log", "w")
class SpamServer(BaseServer):
async def line_read(self, line: Line):
print(f"{self.name} < {line.format()}")
if line.command == "001":
asyncio.create_task(self.send(build("JOIN", [CHANNEL])))
if line.command == "PRIVMSG" and line.params[0] == CHANNEL:
if "quit" in line.params[1] and line.hostmask.nickname == OWNER:
asyncio.create_task(self.send(build("PRIVMSG", [CHANNEL, "merp"])))
asyncio.create_task(self.send(build("PART", [CHANNEL, "merp"])))
asyncio.create_task(self.send(build("QUIT")))
else:
asyncio.create_task(self.send(build("PRIVMSG", [CHANNEL, "ALL HAIL IRES"])))
if line.command == "KICK":
if line.params[1] == BOTNAME:
time.sleep(1)
asyncio.create_task(self.send(build("JOIN", [CHANNEL])))
# asyncio.create_task(build('KICK', [CHANNEL, line.params[2], MESSAGES['revenge']]))
async def line_send(self, line: Line):
print(f"{self.name} > {line.format()}")
class Server(BaseServer):
async def line_read(self, line: Line):
print(f"{self.name} < {line.format()}")
LOGFILE.write(f"{self.name} < {line.format()}")
if line.command == "001":
await self.send(build("PRIVMSG", ["NickServ", "identify " + PASSWORD]))
await self.send(build("MODE", [BOTNAME, "+B"]))
await self.send(build("JOIN", [CHANNEL]))
if line.command == "474":
await self.send(build("PRIVMSG", ["ChanServ", "unban " + CHANNEL + " " + BOTNAME]))
await self.send(build("PRIVMSG", ["ChanServ", "owner " + CHANNEL + " " + BOTNAME]))
await self.send(build("PRIVMSG", ["ChanServ", "invite " + CHANNEL + " " + BOTNAME]))
await self.send(build("JOIN", [CHANNEL]))
if line.command == "PRIVMSG" and line.params[0] == CHANNEL:
if line.hostmask.nickname == OWNER:
if BOTNAME + ": quit" == line.params[1]:
await self.send(build('PART', [CHANNEL, MESSAGES['quit']]))
exit(100)
if BOTNAME + ": kickadd" in line.params[1]:
if gcompile("*!*@*").match(line.params[1].split(' ')[2]):
KICKEES_HOSTMASK.append(line.params[1].split(' ')[2])
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['kickadd']]))
else:
if not line.params[1].split(' ')[1] in EXEMPT:
KICKEES.append(line.params[1].split(' ')[2])
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['kickadd']]))
else:
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['kickadderr']]))
if BOTNAME + ": kicklist" in line.params[1]:
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['kicklist'] + ' '.join(KICKEES)]))
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['kicklist'] + ' '.join(KICKEES_HOSTMASK)]))
if BOTNAME + ": kickrm" in line.params[1]:
try:
if gcompile("*!*@*").match(line.params[1].split(' ')[2]):
KICKEES_HOSTMASK.remove(line.params[1].split(' ')[2])
else:
KICKEES.remove(line.params[1].split(' ')[2])
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['kickrm']]))
except ValueError:
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['kickrmerr']]))
if BOTNAME + ": exemptadd" in line.params[1]:
EXEMPT.append(line.params[1].split(' ')[2])
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['exemptadd']]))
if BOTNAME + ": exemptlist" in line.params[1]:
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['exemptlist'] + ' '.join(EXEMPT)]))
if BOTNAME + ": exemptrm" in line.params[1]:
try:
EXEMPT.remove(line.params[1].split(' ')[2])
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['exemptrm']]))
except ValueError:
await self.send(build('PRIVMSG', [CHANNEL, \
MESSAGES['exemptrmerr']]))
if BOTNAME + ": ping" in line.params[1]:
tmp = ""
for i in self.channels[CHANNEL].users.keys():
tmp += i
tmp += ' '
if len(tmp) > 100:
await self.send(build('PRIVMSG', [CHANNEL, \
tmp]))
tmp = ""
await self.send(build('PRIVMSG', [CHANNEL, \
tmp]))
if BOTNAME + ": savestate" in line.params[1]:
try:
fd = open("kickees", "w")
await self.send(build('PRIVMSG', [CHANNEL, MESSAGES['writekickee']]))
fd.writelines(i + '\n' for i in KICKEES)
fd.close()
fd = open("kickees_mask", "w")
await self.send(build('PRIVMSG', [CHANNEL, MESSAGES['writekickeehostmask']]))
fd.writelines(i + '\n' for i in KICKEES_HOSTMASK)
fd.close()
await self.send(build('PRIVMSG', [CHANNEL, MESSAGES['writeexempt']]))
fd = open("exempt", "w")
fd.writelines(i + '\n' for i in EXEMPT)
fd.close()
await self.send(build('PRIVMSG', [CHANNEL, MESSAGES['writedone']]))
except:
await self.send(build('PRIVMSG', [CHANNEL, MESSAGES['writeerr']]))
if BOTNAME + ": bots" in line.params[1]:
bot = SpamBot()
for name, host in SPAMSERVERS:
await bot.add_server(name, \
ConnectionParams(BOTNAME + name, host, 6667, False, BOTNAME))
asyncio.create_task(bot.run())
if BOTNAME + ": kick" in line.params[1]:
for i in self.channels[CHANNEL].users:
if i != OWNER:
asyncio.create_task(self.send(build('KICK', [CHANNEL, i, 'nope'])))
if line.command == "JOIN":
if line.hostmask.nickname in KICKEES:
await self.send(build('KICK', [CHANNEL, line.hostmask.nickname, MESSAGES['kick']]))
else:
for i in KICKEES_HOSTMASK:
if gcompile(i).match(str(line.hostmask)):
await self.send(build('KICK', [CHANNEL, line.hostmask.nickname, MESSAGES['kick']]))
break
if line.hostmask.nickname == "bot":
global TASKCACHE
TASKCACHE = asyncio.create_task(self.julian())
if line.command == "PART":
if line.hostmask.nickname == 'bot' and 'TASKCACHE' in globals():
TASKCACHE.cancel()
if line.command == "QUIT":
if line.hostmask.nickname == 'bot' and 'TASKCACHE' in globals():
TASKCACHE.cancel()
if line.command == "MODE":
try:
if 'l' in self.channels[CHANNEL].modes:
await self.send(build('MODE', [CHANNEL, '-l']))
if 'n' in self.channels[CHANNEL].modes:
await self.send(build('MODE', [CHANNEL, '-n']))
if 'm' in self.channels[CHANNEL].modes:
await self.send(build('MODE', [CHANNEL, '-m']))
if 's' in self.channels[CHANNEL].modes:
await self.send(build('MODE', [CHANNEL, '-s']))
if not 'q' in self.channels[CHANNEL].users[OWNER].modes:
await self.send(build('MODE', [CHANNEL, '+q', OWNER]))
if 'b' in self.channels[CHANNEL].users[BOTNAME].modes:
await self.send(build("PRIVMSG", ["ChanServ", "unban " + CHANNEL + " " + BOTNAME]))
if not 'q' in self.channels[CHANNEL].users[BOTNAME].modes:
await self.send(build("PRIVMSG", ["ChanServ", "owner " + CHANNEL + " " + BOTNAME]))
else:
print(self.channels[CHANNEL].modes)
except KeyError:
pass
if line.command == "KICK" and line.params[0] == CHANNEL:
if line.params[1] == OWNER:
await self.send(build('KICK', [CHANNEL, line.hostmask.nickname, MESSAGES['revenge']]))
await self.send(build('INVITE', [CHANNEL, line.params[1]]))
if line.params[1] == BOTNAME:
time.sleep(1)
await self.send(build('JOIN', [CHANNEL]))
time.sleep(0.5)
await self.send(build('KICK', [CHANNEL, line.hostmask.nickname, MESSAGES['revenge']]))
if line.command == "TOPIC" and line.params[0] == CHANNEL:
if line.hostmask.nickname != OWNER and \
line.hostmask.nickname != BOTNAME and \
not line.hostmask.nickname in EXEMPT:
await self.send(build('TOPIC', [CHANNEL, TOPIC]))
if line.command == "482":
await self.send(build('TOPIC', [CHANNEL, TOPIC]))
async def line_send(self, line: Line):
print(f"{self.name} > {line.format()}")
LOGFILE.write(f"{self.name} > {line.format()}")
async def julian(self):
while True:
self.send(build('PRIVMSG', [CHANNEL, "hi"]))
class Bot(BaseBot):
def create_server(self, name: str):
return Server(self, name)
class SpamBot(BaseBot):
def create_server(self, name: str):
return SpamServer(self, name)
async def main():
try:
fd = open("kickees", "r")
for i in fd.readlines():
if not i in EXEMPT:
KICKEES.append(i.rstrip('\n'))
fd.close()
fd = open("kickees_mask", "r")
for i in fd.readlines():
if not i in EXEMPT:
KICKEES_HOSTMASK.append(i.rstrip('\n'))
fd.close()
fd = open("exempt", "r")
for i in fd.readlines():
EXEMPT.append(i.rstrip('\n'))
fd.close()
except FileNotFoundError:
print("warning: save state files are missing")
print("proceeding without save state files")
bot = Bot()
for name, host in SERVERS:
params = ConnectionParams(BOTNAME, host, 6667, False, BOTNAME, "totally not rndusr's bot lol")
await bot.add_server(name, params)
await bot.run()
if __name__ == "__main__":
asyncio.run(main())