2013-06-29 22:18:56 +00:00
|
|
|
import eliza
|
2013-07-06 21:21:27 +00:00
|
|
|
import threading
|
2013-09-03 12:50:54 +00:00
|
|
|
import random
|
2014-04-01 19:25:16 +00:00
|
|
|
import re
|
2015-02-22 14:29:46 +00:00
|
|
|
import time
|
2013-06-29 22:18:56 +00:00
|
|
|
|
2015-03-01 00:30:59 +00:00
|
|
|
concmd=['/q', '/lt', '/st', '/lg']
|
2013-07-07 12:43:33 +00:00
|
|
|
|
2015-03-01 00:30:59 +00:00
|
|
|
blacklist = ['bslsk05']
|
2014-12-06 20:31:17 +00:00
|
|
|
|
2015-03-01 00:30:59 +00:00
|
|
|
doctor = eliza.eliza()
|
|
|
|
|
2015-03-03 15:46:19 +00:00
|
|
|
trusted = {}
|
2015-03-01 00:30:59 +00:00
|
|
|
trustedlock = threading.Lock()
|
2015-03-03 15:46:19 +00:00
|
|
|
gods = {}
|
2015-03-01 00:30:59 +00:00
|
|
|
godslock = threading.Lock()
|
|
|
|
|
|
|
|
msgs = {}
|
|
|
|
msgslock = threading.Lock()
|
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
accountcheck = {}
|
|
|
|
accountchecklock = threading.Lock()
|
2013-06-29 22:01:33 +00:00
|
|
|
|
2014-04-01 19:25:16 +00:00
|
|
|
die_expr=re.compile("#[0-9]*d([0-9]+|%)")
|
|
|
|
|
2015-02-22 14:29:46 +00:00
|
|
|
class Cron(threading.Thread):
|
|
|
|
def __init__(self):
|
2015-03-01 00:30:59 +00:00
|
|
|
self.timedjobs = []
|
|
|
|
self.timedjobslock = threading.Lock()
|
|
|
|
self.cronctrl = []
|
|
|
|
self.cronctrllock = threading.Lock()
|
2015-02-22 14:29:46 +00:00
|
|
|
threading.Thread.__init__(self)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-02-22 14:29:46 +00:00
|
|
|
def queuejob(self, time, fn):
|
|
|
|
self.timedjobslock.acquire()
|
|
|
|
self.timedjobs.append((time, fn))
|
|
|
|
self.timedjobslock.release()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-02-22 14:29:46 +00:00
|
|
|
def ctrl(self, cmd):
|
|
|
|
self.cronctrllock.acquire()
|
|
|
|
self.cronctrl.append(cmd)
|
|
|
|
self.cronctrllock.release()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-02-22 14:29:46 +00:00
|
|
|
def run(self):
|
2015-03-01 00:30:59 +00:00
|
|
|
run = True
|
2015-02-22 14:29:46 +00:00
|
|
|
while run:
|
|
|
|
time.sleep(1) # Accuracy doesn't need to be high
|
|
|
|
|
|
|
|
self.cronctrllock.acquire()
|
|
|
|
for cmd in self.cronctrl:
|
2015-03-01 00:30:59 +00:00
|
|
|
if cmd == 'QUIT':
|
|
|
|
run = False
|
2015-02-22 14:29:46 +00:00
|
|
|
self.cronctrl=[]
|
|
|
|
self.cronctrllock.release()
|
|
|
|
|
|
|
|
self.timedjobslock.acquire()
|
2015-03-01 00:30:59 +00:00
|
|
|
self.timedjobs = map((lambda (time, fn): (time-1, fn)), self.timedjobs)
|
|
|
|
torun = map((lambda (time, fn): fn), filter((lambda (time, fn): time<=0), self.timedjobs))
|
|
|
|
self.timedjobs = filter((lambda (time, fn): time>0), self.timedjobs)
|
2015-02-22 14:29:46 +00:00
|
|
|
self.timedjobslock.release()
|
|
|
|
|
|
|
|
for fn in torun:
|
|
|
|
fn()
|
|
|
|
|
|
|
|
cron=Cron()
|
|
|
|
cron.start()
|
|
|
|
|
2015-03-01 00:30:59 +00:00
|
|
|
def loadmessages():
|
|
|
|
global msgs, msgslock
|
|
|
|
|
|
|
|
msgslock.acquire()
|
|
|
|
f = open('msgs.txt', 'r')
|
|
|
|
|
|
|
|
for line in f:
|
|
|
|
while len(line) > 0 and line[-1] == '\n':
|
|
|
|
line = line[:-1]
|
|
|
|
if len(line) > 0:
|
|
|
|
receiver, sender, msg = line.split('\t')
|
|
|
|
if receiver not in msgs:
|
|
|
|
msgs[receiver] = []
|
|
|
|
msgs[receiver].append((sender, msg))
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
msgslock.release()
|
|
|
|
|
|
|
|
def savemessages():
|
|
|
|
global msgs, msgslock
|
|
|
|
|
|
|
|
msgslock.acquire()
|
|
|
|
f=open('msgs.txt', 'w')
|
|
|
|
|
|
|
|
for receiver in msgs:
|
|
|
|
for sender, msg in msgs[receiver]:
|
|
|
|
f.write('%s\t%s\t%s\n' % (receiver, sender, msg))
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
msgslock.release()
|
|
|
|
|
|
|
|
loadmessages()
|
|
|
|
|
2015-03-03 15:46:19 +00:00
|
|
|
def addtrusted(chan, account):
|
2015-03-01 00:30:59 +00:00
|
|
|
global trusted, trustedlock
|
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
trustedlock.acquire()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-03-03 15:46:19 +00:00
|
|
|
if chan not in trusted:
|
|
|
|
trusted[chan] = []
|
|
|
|
|
|
|
|
if account not in trusted[chan]:
|
|
|
|
trusted[chan].append(account)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
trustedlock.release()
|
|
|
|
|
2015-03-03 15:46:19 +00:00
|
|
|
def rmtrusted(chan, account):
|
2015-03-01 00:30:59 +00:00
|
|
|
global trusted, trustedlock
|
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
trustedlock.acquire()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-03-03 15:46:19 +00:00
|
|
|
if chan in trusted and account in trusted[chan]:
|
|
|
|
trusted[chan].remove(account)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
trustedlock.release()
|
|
|
|
|
2013-07-08 17:37:00 +00:00
|
|
|
def loadtrusted():
|
2015-03-01 00:30:59 +00:00
|
|
|
global trusted, trustedlock
|
|
|
|
|
2013-07-08 17:37:00 +00:00
|
|
|
trustedlock.acquire()
|
2015-03-03 15:46:19 +00:00
|
|
|
trusted = {}
|
2013-09-25 15:23:38 +00:00
|
|
|
trustedlock.release()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
|
|
|
f=open('trusted.txt', 'r')
|
|
|
|
|
2013-07-08 17:37:00 +00:00
|
|
|
for line in f:
|
2015-03-01 00:30:59 +00:00
|
|
|
while len(line) > 0 and line[-1] == '\n':
|
|
|
|
line = line[:-1]
|
|
|
|
if len(line) > 0:
|
2015-03-03 15:46:19 +00:00
|
|
|
chan, account = line.split()
|
|
|
|
addtrusted(chan, account)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-07-08 17:37:00 +00:00
|
|
|
f.close()
|
2013-09-25 15:23:38 +00:00
|
|
|
|
|
|
|
def loadgods():
|
2015-03-01 00:30:59 +00:00
|
|
|
global gods, godslock
|
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
godslock.acquire()
|
2015-03-03 15:46:19 +00:00
|
|
|
gods = {}
|
2015-03-01 00:30:59 +00:00
|
|
|
f=open('gods.txt', 'r')
|
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
for line in f:
|
2015-03-01 00:30:59 +00:00
|
|
|
while len(line) > 0 and line[-1] == '\n':
|
|
|
|
line = line[:-1]
|
|
|
|
if len(line) > 0:
|
2015-03-03 15:46:19 +00:00
|
|
|
chan, account = line.split()
|
|
|
|
|
|
|
|
if chan not in gods:
|
|
|
|
gods[chan] = []
|
|
|
|
|
|
|
|
gods[chan].append(account)
|
|
|
|
addtrusted(chan, account)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
f.close()
|
|
|
|
godslock.release()
|
|
|
|
|
|
|
|
def savetrusted():
|
2015-03-01 00:30:59 +00:00
|
|
|
global trusted, trustedlock
|
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
trustedlock.acquire()
|
2015-03-01 00:30:59 +00:00
|
|
|
f=open('trusted.txt', 'w')
|
|
|
|
|
2015-03-03 15:46:19 +00:00
|
|
|
for chan in trusted:
|
|
|
|
for account in trusted[chan]:
|
|
|
|
f.write('%s %s\n' % (chan, account))
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-09-25 15:23:38 +00:00
|
|
|
f.close
|
2013-07-08 17:37:00 +00:00
|
|
|
trustedlock.release()
|
|
|
|
|
|
|
|
loadtrusted()
|
2013-09-25 15:23:38 +00:00
|
|
|
loadgods()
|
2013-07-08 17:37:00 +00:00
|
|
|
|
2015-02-22 18:24:57 +00:00
|
|
|
def chmode(irc, chan, nick, mode, args):
|
2015-02-28 13:58:40 +00:00
|
|
|
if args == ['']:
|
2015-03-03 15:46:19 +00:00
|
|
|
if isauthorized(irc, chan, nick):
|
2015-03-01 00:30:59 +00:00
|
|
|
irc.send('MODE %s %s %s' % (chan, mode, nick))
|
2013-07-21 16:56:44 +00:00
|
|
|
else:
|
|
|
|
for name in args:
|
2015-03-03 15:46:19 +00:00
|
|
|
if isauthorized(irc, chan, nick):
|
2015-03-01 00:30:59 +00:00
|
|
|
irc.send('MODE %s %s %s' % (chan, mode, name))
|
2015-02-22 15:25:51 +00:00
|
|
|
|
2015-03-03 15:46:19 +00:00
|
|
|
def istrusted(chan, account):
|
2015-02-22 15:25:51 +00:00
|
|
|
trustedlock.acquire()
|
2015-03-03 15:46:19 +00:00
|
|
|
if chan in trusted and account in trusted[chan]:
|
2015-02-22 15:25:51 +00:00
|
|
|
trustedlock.release()
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
trustedlock.release()
|
|
|
|
return False
|
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
def initaccountcheck(nick):
|
|
|
|
global accountcheck, accountchecklock
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
accountchecklock.acquire()
|
|
|
|
accountcheck[nick] = None
|
|
|
|
accountchecklock.release()
|
2015-02-22 15:25:51 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
def setaccountcheckvalue(nick, value):
|
|
|
|
global accountcheck, accountchecklock
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
accountchecklock.acquire()
|
|
|
|
if nick in accountcheck:
|
|
|
|
accountcheck[nick] = value
|
|
|
|
accountchecklock.release()
|
2015-02-22 15:25:51 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
def getaccountcheckvalue(nick):
|
|
|
|
global accountcheck, accountchecklock
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
accountchecklock.acquire()
|
|
|
|
if nick in accountcheck:
|
|
|
|
value = accountcheck[nick]
|
|
|
|
accountchecklock.release()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
return value
|
2015-02-22 15:25:51 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
def removeaccountcheck(nick):
|
|
|
|
global accountcheck, accountchecklock
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
accountchecklock.acquire()
|
|
|
|
if nick in accountcheck:
|
|
|
|
del accountcheck[nick]
|
|
|
|
accountchecklock.release()
|
2015-02-22 15:25:51 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
def getaccount(irc, nick):
|
|
|
|
initaccountcheck(nick)
|
|
|
|
irc.send('WHOIS ' + nick)
|
|
|
|
cron.queuejob(5, (lambda : setaccountcheckvalue(nick, '')))
|
|
|
|
|
|
|
|
account = None
|
|
|
|
while account == None:
|
|
|
|
account = getaccountcheckvalue(nick)
|
2015-02-22 15:25:51 +00:00
|
|
|
time.sleep(0.1)
|
2015-03-01 12:19:57 +00:00
|
|
|
removeaccountcheck(nick)
|
2015-02-22 15:25:51 +00:00
|
|
|
|
2015-03-01 12:19:57 +00:00
|
|
|
if account == '': # '' Signifies failure
|
|
|
|
return None
|
|
|
|
else:
|
|
|
|
return account
|
|
|
|
|
2015-03-03 15:46:19 +00:00
|
|
|
def isauthorized(irc, chan, nick):
|
2015-03-01 12:19:57 +00:00
|
|
|
account = getaccount(irc, nick)
|
|
|
|
if account:
|
2015-03-03 15:46:19 +00:00
|
|
|
return istrusted(chan, account)
|
2015-03-01 12:19:57 +00:00
|
|
|
else:
|
|
|
|
irc.msg(nick, 'Identify with NickServ')
|
2013-07-08 17:37:00 +00:00
|
|
|
|
2015-02-22 18:24:57 +00:00
|
|
|
class ArgsfmtError(Exception):
|
|
|
|
def __init__(self, msg):
|
|
|
|
self.msg = msg
|
|
|
|
def __str__(self):
|
2015-03-01 00:30:59 +00:00
|
|
|
return 'Error with argument format: ' + msg
|
2015-02-22 18:24:57 +00:00
|
|
|
|
|
|
|
ARG_STD = 0
|
|
|
|
ARG_OPT = 1
|
|
|
|
ARG_UNL = 2
|
|
|
|
|
|
|
|
def parseargsfmt(args):
|
|
|
|
# parses the argument format used by matchcmd and parsecmd
|
|
|
|
# e.g. parseargsfmt("foo [bar] {baz} ) -> [ARG_STD, ARG_OPT, ARG_UNL]
|
|
|
|
|
|
|
|
args = args.split(' ')
|
|
|
|
out = []
|
|
|
|
for arg in args:
|
|
|
|
if len(arg) >= 2 and arg[0] == '[' and arg[-1] == ']': # Optional (0-1) argument: [bar]
|
|
|
|
out.append(ARG_OPT)
|
|
|
|
elif len(arg) >= 2 and arg[0] == '{' and arg[-1] == '}': # Unlimited (0-) number of arguments: {baz}
|
|
|
|
out.append(ARG_UNL)
|
|
|
|
else: # Normal argument: foo
|
|
|
|
out.append(ARG_STD)
|
|
|
|
|
|
|
|
return out
|
|
|
|
|
|
|
|
def getargnums(argtypes):
|
|
|
|
min = 0
|
|
|
|
max = 0 # max = None if number of arguments is unlimited
|
|
|
|
|
|
|
|
for argtype in argtypes:
|
|
|
|
if argtype == ARG_STD:
|
|
|
|
min += 1
|
|
|
|
if max != None: # Don't try to increment if max is unlimited
|
|
|
|
max += 1
|
|
|
|
elif argtype == ARG_OPT:
|
|
|
|
if max != None: # Don't try to increment if max is unlimited
|
|
|
|
max += 1
|
|
|
|
elif argtype == ARG_UNL:
|
|
|
|
max = None
|
|
|
|
|
|
|
|
return min, max
|
|
|
|
|
|
|
|
def matchcmd(line, cmd, args=None):
|
|
|
|
# matchcmd(line, cmd) matched if the command cmd is used, matchcmd(line, cmd, args) checks whether the args match too
|
|
|
|
|
|
|
|
if len(line) == 0:
|
|
|
|
return False
|
|
|
|
if line[0] != cmd:
|
|
|
|
return False
|
|
|
|
|
|
|
|
if not args:
|
|
|
|
return True
|
|
|
|
|
|
|
|
min, max = getargnums(parseargsfmt(args))
|
|
|
|
|
|
|
|
if max and len(line)-1 >= min and len(line)-1 <= max:
|
|
|
|
return True
|
|
|
|
elif not max and len(line)-1 >= min:
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
|
|
|
def parsecmd(line, args):
|
|
|
|
# Returns a tuple containing the arguments. An optional argument that didn't get a value will be assigned ''
|
|
|
|
argtypes = parseargsfmt(args)
|
|
|
|
|
|
|
|
if len(argtypes) >= 1 and ARG_UNL in argtypes[:-1]: # Disallow non-final unlimited arguments
|
|
|
|
raise ArgsfmtError('Non-final unlimited argument')
|
|
|
|
if len(filter((lambda type: type == ARG_OPT or type == ARG_UNL), argtypes)) > 1: # Disallow more than one optional or unlimited argument per argument string
|
|
|
|
raise ArgsfmtError('Ambiguous argument format')
|
|
|
|
|
|
|
|
# Remove the command
|
|
|
|
if len(line) == 0:
|
|
|
|
raise ArgsfmtError('No command given')
|
|
|
|
line = line[1:]
|
|
|
|
|
|
|
|
min, max = getargnums(argtypes)
|
|
|
|
if len(line) == min:
|
|
|
|
# Only standard arguments given
|
|
|
|
out = []
|
|
|
|
for type in argtypes:
|
|
|
|
if type == ARG_STD:
|
|
|
|
out.append(line[0])
|
|
|
|
line = line[1:]
|
|
|
|
else:
|
|
|
|
out.append('')
|
|
|
|
elif max and len(line) == max:
|
|
|
|
# Optional argument given
|
|
|
|
out = []
|
|
|
|
for type in argtypes:
|
|
|
|
if type == ARG_STD or type == ARG_OPT:
|
|
|
|
out.append(line[0])
|
|
|
|
line = line[1:]
|
|
|
|
else:
|
|
|
|
out.append('')
|
|
|
|
elif not max and len(line) > min:
|
|
|
|
# Unlimited argument given
|
|
|
|
out = []
|
|
|
|
for type in argtypes:
|
|
|
|
if type == ARG_STD or type == ARG_OPT:
|
|
|
|
out.append(line[0])
|
|
|
|
line = line[1:]
|
|
|
|
elif type == ARG_UNL:
|
|
|
|
out.append(' '.join(line))
|
|
|
|
line = []
|
|
|
|
else:
|
|
|
|
raise ArgsfmtError('Number of given arguments not possible for given format string')
|
|
|
|
|
|
|
|
if len(out) == 1:
|
|
|
|
return out[0]
|
|
|
|
else:
|
|
|
|
return out
|
|
|
|
|
2015-03-01 00:30:59 +00:00
|
|
|
def parse((line, irc)):
|
|
|
|
global blacklist
|
|
|
|
global msgs, msgslock
|
|
|
|
global trusted, trustedlock, gods, godslock
|
|
|
|
global doctor, die_expr
|
|
|
|
|
|
|
|
line = line.split(' ')
|
|
|
|
nick = line[0].split('!')[0][1:]
|
|
|
|
chan = line[2] if line[2][0] == '#' else nick
|
2014-12-06 20:31:17 +00:00
|
|
|
|
2015-02-22 18:24:57 +00:00
|
|
|
zwsp = '\xe2\x80\x8b'
|
|
|
|
|
2014-12-06 20:31:17 +00:00
|
|
|
if nick in blacklist:
|
|
|
|
return
|
2015-02-22 18:24:57 +00:00
|
|
|
elif len(line) >= 4 and len(line[3]) >= 4 and line[3][:len(zwsp)+1] == ':'+zwsp: # If line begins with ZWSP
|
2015-02-13 15:52:15 +00:00
|
|
|
return
|
2014-12-06 20:31:17 +00:00
|
|
|
|
2013-06-29 22:18:56 +00:00
|
|
|
if line[1]=='PRIVMSG':
|
2015-03-04 22:25:06 +00:00
|
|
|
reply = chan
|
|
|
|
|
2015-02-22 18:24:57 +00:00
|
|
|
cmdline = [line[3][1:]] + line[4:]
|
|
|
|
while '' in cmdline:
|
|
|
|
cmdline.remove('')
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2015-03-04 22:25:06 +00:00
|
|
|
# #chan: channel override prefix
|
|
|
|
if matchcmd(cmdline, '#chan'):
|
|
|
|
if matchcmd(cmdline, '#chan', 'channel {command}'):
|
|
|
|
newchan, newcmdline = parsecmd(cmdline, 'channel {command}')
|
|
|
|
newcmdline = newcmdline.split(' ')
|
|
|
|
if isauthorized(irc, newchan, nick):
|
|
|
|
chan = newchan
|
|
|
|
cmdline = newcmdline
|
|
|
|
else:
|
|
|
|
irc.msg(chan, 'Usage #chan channel command')
|
|
|
|
|
2015-02-22 18:24:57 +00:00
|
|
|
if matchcmd(cmdline, '#echo'):
|
|
|
|
text = parsecmd(cmdline, '{text}')
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, zwsp+text)
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#op'):
|
|
|
|
args = parsecmd(cmdline, '{args}')
|
|
|
|
chmode(irc, chan, nick, '+o', args.split(' '))
|
|
|
|
elif matchcmd(cmdline, '#deop'):
|
|
|
|
args = parsecmd(cmdline, '{args}')
|
|
|
|
chmode(irc, chan, nick, '-o', args.split(' '))
|
|
|
|
elif matchcmd(cmdline, '#voice'):
|
|
|
|
args = parsecmd(cmdline, '{args}')
|
|
|
|
chmode(irc, chan, nick, '+v', args.split(' '))
|
|
|
|
elif matchcmd(cmdline, '#devoice'):
|
|
|
|
args = parsecmd(cmdline, '{args}')
|
|
|
|
chmode(irc, chan, nick, '-v', args.split(' '))
|
|
|
|
elif matchcmd(cmdline, '#kick'):
|
|
|
|
if matchcmd(cmdline, '#kick', 'nick {reason}'):
|
|
|
|
kicknick, kickreason = parsecmd(cmdline, 'nick {reason}')
|
|
|
|
if kicknick.lower() == irc.nick:
|
|
|
|
irc.send('KICK %s %s :Fuck you' % (chan, nick))
|
|
|
|
elif random.randint(0,9) == 0 and len(line) == 5:
|
|
|
|
irc.send('KICK %s %s :Bam' % (chan, nick))
|
2013-09-03 12:50:54 +00:00
|
|
|
else:
|
2015-03-03 15:46:19 +00:00
|
|
|
if isauthorized(irc, chan, nick):
|
2015-02-22 18:24:57 +00:00
|
|
|
irc.send('KICK %s %s :%s'%(chan, kicknick, kickreason))
|
2013-07-08 16:57:42 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Usage #kick nick reason')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#src'):
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'https://github.com/JuEeHa/oonbotti2')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#prefix') and chan == '#osdev-offtopic':
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'gopher://smar.fi:7070/0/hash-prefix')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#msg'):
|
|
|
|
if matchcmd(cmdline, '#msg', 'nick {message}'):
|
|
|
|
msgnick, message = parsecmd(cmdline, 'nick {message}')
|
2015-03-01 00:30:59 +00:00
|
|
|
msgslock.acquire()
|
2015-02-22 18:24:57 +00:00
|
|
|
if msgnick not in msgs:
|
|
|
|
msgs[msgnick] = []
|
|
|
|
msgs[msgnick].append((nick, message))
|
2015-03-01 00:30:59 +00:00
|
|
|
msgslock.release()
|
2013-07-06 19:10:46 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Usage: #msg nick message')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#trusted?'):
|
|
|
|
if matchcmd(cmdline, '#trusted?', '[nick]'):
|
|
|
|
trustnick = parsecmd(cmdline, '[nick]')
|
|
|
|
if trustnick == '':
|
2015-03-01 12:19:57 +00:00
|
|
|
trustnick = nick
|
|
|
|
account = getaccount(irc, trustnick)
|
|
|
|
if account:
|
2015-03-03 15:46:19 +00:00
|
|
|
if istrusted(chan, account):
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, '%s is trusted' % trustnick)
|
2015-03-01 12:19:57 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, '%s is not trusted' % trustnick)
|
2015-02-22 18:24:57 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Failed to get account for %s' % trustnick)
|
2015-02-22 15:25:51 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Usage: #trusted? [nick]')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#trust'):
|
|
|
|
if matchcmd(cmdline, '#trust', 'nick'):
|
|
|
|
trustnick = parsecmd(cmdline, 'nick')
|
2015-03-03 15:46:19 +00:00
|
|
|
if isauthorized(irc, chan, nick):
|
2015-03-01 12:19:57 +00:00
|
|
|
account = getaccount(irc, trustnick)
|
|
|
|
if account:
|
2015-03-03 15:46:19 +00:00
|
|
|
addtrusted(chan, account)
|
2015-03-01 12:19:57 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Failed to get account for %s' % trustnick)
|
2013-09-25 15:23:38 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Usage #trust nick')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#untrust'):
|
|
|
|
if matchcmd(cmdline, '#untrust', 'nick'):
|
|
|
|
untrustnick = parsecmd(cmdline, 'nick')
|
2015-03-03 15:46:19 +00:00
|
|
|
if isauthorized(irc, chan, nick):
|
2015-03-01 12:19:57 +00:00
|
|
|
account = getaccount(irc, untrustnick)
|
|
|
|
if account:
|
|
|
|
godslock.acquire()
|
2015-03-03 15:46:19 +00:00
|
|
|
if chan not in gods or account not in gods[chan]:
|
|
|
|
rmtrusted(chan, untrustnick)
|
2015-03-01 12:19:57 +00:00
|
|
|
godslock.release()
|
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Failed to get account for %s' % untrustnick)
|
2013-09-25 15:23:38 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Usage #untrust nick')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#ls-trusted'):
|
2013-09-25 15:23:38 +00:00
|
|
|
trustedlock.acquire()
|
2015-03-03 15:46:19 +00:00
|
|
|
if chan in trusted:
|
|
|
|
irc.msg(nick, '%s: %s' % (chan, ', '.join(trusted[chan])))
|
2013-09-25 15:23:38 +00:00
|
|
|
trustedlock.release()
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#invite'):
|
|
|
|
if matchcmd(cmdline, '#invite', 'nick'):
|
|
|
|
invitenick = parsecmd(cmdline, 'nick')
|
2015-03-03 15:46:19 +00:00
|
|
|
if isauthorized(irc, chan, nick):
|
2015-02-22 18:24:57 +00:00
|
|
|
irc.send('INVITE %s %s' % (invitenick, chan))
|
2014-01-04 18:25:09 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, 'Usage #invite nick')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif matchcmd(cmdline, '#help'):
|
|
|
|
if matchcmd(cmdline, '#help', '[command]'):
|
|
|
|
command = parsecmd(cmdline, '[command]')
|
|
|
|
helptext = help(command)
|
|
|
|
if helptext:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, zwsp+helptext)
|
|
|
|
elif matchcmd(cmdline, '#esoteric') and chan == '#esoteric':
|
|
|
|
irc.msg(reply, 'Nothing here')
|
2015-02-22 18:24:57 +00:00
|
|
|
elif cmdline[0] in [irc.nick, irc.nick+',', irc.nick+':']:
|
|
|
|
question = parsecmd(cmdline, '{question}')
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, '%s: %s' % (nick, doctor.respond(question)))
|
2015-02-22 18:24:57 +00:00
|
|
|
elif die_expr.match(cmdline[0]):
|
2015-03-04 22:25:06 +00:00
|
|
|
die = cmdline[0][1:].split('d')
|
|
|
|
times = int(die[0]) if die[0] else 1
|
|
|
|
die = '%' if die[1] == '%' else int(die[1])
|
|
|
|
if die == '%':
|
|
|
|
if times != 1:
|
|
|
|
irc.msg(reply, 'Not supported')
|
2014-04-12 14:16:36 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, '%s%s' % (random.randint(0,9), random.randint(0,9)))
|
|
|
|
elif die < 2:
|
|
|
|
irc.msg(reply, 'This die is not available in your space-time region.')
|
|
|
|
elif times < 1:
|
|
|
|
irc.msg(reply, 'What exactly do you want me to do?')
|
|
|
|
elif times > 128:
|
|
|
|
irc.msg(reply, 'Sorry, I don\'t have that many. Can I borrow yours?')
|
2014-04-01 19:25:16 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
rolls = [random.randint(1, die) for i in xrange(times)]
|
|
|
|
result = reduce((lambda x, y: x + y), rolls)
|
|
|
|
if times > 1:
|
|
|
|
irc.msg(reply, '%s (%s)' % (str(result), ', '.join([str(i) for i in rolls])))
|
2014-04-01 19:25:16 +00:00
|
|
|
else:
|
2015-03-04 22:25:06 +00:00
|
|
|
irc.msg(reply, str(result))
|
2015-03-01 12:19:57 +00:00
|
|
|
elif line[1] == '330': # WHOIS: is logged in as
|
|
|
|
whoisnick = line[3]
|
|
|
|
account = line[4]
|
|
|
|
setaccountcheckvalue(whoisnick, account)
|
|
|
|
elif line[1] == '318': # WHOIS: End of /WHOIS list.
|
|
|
|
whoisnick = line[3]
|
|
|
|
if getaccountcheckvalue(whoisnick) == None:
|
|
|
|
setaccountcheckvalue(whoisnick, '') # Mark as failed, '' is used because None is already reserved
|
2015-03-01 00:30:59 +00:00
|
|
|
elif line[1] == 'INVITE' and line[2] == irc.nick and line[3][1:] in irc.chan.split(' '):
|
2015-03-03 15:46:19 +00:00
|
|
|
if isauthorized(irc, line[3], nick):
|
2015-03-01 00:30:59 +00:00
|
|
|
irc.send('JOIN ' + line[3])
|
|
|
|
elif line[1] == '482':
|
2015-01-24 12:21:06 +00:00
|
|
|
irc.msg(line[3], 'Not op')
|
2015-03-01 00:30:59 +00:00
|
|
|
|
|
|
|
msgslock.acquire()
|
|
|
|
if (line[1] == 'PRIVMSG' or line[1] == 'JOIN') and nick in msgs:
|
|
|
|
for sender, msg in msgs.pop(nick):
|
2015-01-24 12:21:06 +00:00
|
|
|
irc.msg(nick, '<%s> %s' % (sender, msg))
|
2015-03-01 00:30:59 +00:00
|
|
|
msgslock.release()
|
2013-07-07 12:43:33 +00:00
|
|
|
|
|
|
|
def execcmd(cmdline):
|
2015-03-01 00:30:59 +00:00
|
|
|
if cmdline[0] == '/q':
|
|
|
|
savemessages()
|
2013-09-26 16:37:54 +00:00
|
|
|
savetrusted()
|
2015-02-22 14:29:46 +00:00
|
|
|
|
|
|
|
cron.ctrl('QUIT')
|
2015-03-01 00:30:59 +00:00
|
|
|
elif cmdline[0] == '/lt':
|
2013-07-08 17:37:00 +00:00
|
|
|
loadtrusted()
|
2015-03-01 00:30:59 +00:00
|
|
|
elif cmdline[0] == '/st':
|
2013-09-25 15:23:38 +00:00
|
|
|
savetrusted()
|
2015-03-01 00:30:59 +00:00
|
|
|
elif cmdline[0] == '/lg':
|
2013-09-25 15:23:38 +00:00
|
|
|
loadgods()
|
2013-07-08 15:09:18 +00:00
|
|
|
|
2015-03-01 00:30:59 +00:00
|
|
|
def usage(cmd, message = True):
|
|
|
|
usage = {'#echo': 'text',
|
|
|
|
'#op': '[nick]',
|
|
|
|
'#deop': '[nick]',
|
|
|
|
'#voice': '[nick]',
|
|
|
|
'#devoice': '[nick]',
|
|
|
|
'#kick': 'nick [reason]',
|
|
|
|
'#src': '',
|
|
|
|
'#msg': 'nick message',
|
2015-03-03 15:49:32 +00:00
|
|
|
'#trusted?': '[nick]',
|
2015-03-01 00:30:59 +00:00
|
|
|
'#trust': 'nick',
|
|
|
|
'#untrust': 'nick',
|
|
|
|
'#ls-trusted': '',
|
|
|
|
'#invite': 'nick',
|
2015-03-04 22:25:06 +00:00
|
|
|
'#chan': 'channel command',
|
2015-03-01 00:30:59 +00:00
|
|
|
'#help': '[command]'}
|
|
|
|
|
|
|
|
if cmd in usage:
|
|
|
|
if message:
|
|
|
|
return 'Usage: %s %s' % (cmd, usage[cmd])
|
|
|
|
else:
|
|
|
|
return usage[cmd]
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
2013-07-08 15:09:18 +00:00
|
|
|
def help(cmd):
|
2015-03-01 00:30:59 +00:00
|
|
|
helptext = {'#echo': '#echo text back',
|
|
|
|
'#op': 'give nick or yourself op rights in case you are trusted by oonbotti2 and identified with NickServ',
|
|
|
|
'#deop': 'remove your/nick\'s op rights',
|
|
|
|
'#voice': 'give nick or yourself voice in case you are trusted by oonbotti2 and identified with NickServ',
|
|
|
|
'#devoice': 'remove your or nick\'s voice in case you are trusted by oonbotti2 and identified with NickServ',
|
|
|
|
'#kick': 'kicks nick with specified reason',
|
|
|
|
'#src': 'paste a link to oonbotti2\'s git repo',
|
|
|
|
'#msg': 'send a message to nick',
|
|
|
|
'#trusted?': 'tell you if nick or yourself is trusted by oonbotti2',
|
|
|
|
'#trust': 'add nick to trusted list',
|
|
|
|
'#untrust': 'remove nick from trusted list',
|
|
|
|
'#ls-trusted': 'list nicks that are trusted. use only in a query',
|
|
|
|
'#invite': 'invites nick to channel',
|
2015-03-04 22:25:06 +00:00
|
|
|
'#chan': 'Runs the command as if it was sent on the specified channel. Requires user to be trusted',
|
2015-03-01 00:30:59 +00:00
|
|
|
'#help': 'give short info of command or list commands'}
|
|
|
|
|
2013-07-08 15:09:18 +00:00
|
|
|
if cmd=='':
|
2015-03-04 22:25:06 +00:00
|
|
|
return '#echo #op #deop #voice #devoice #kick #src #msg #trusted? #trust #untrust #ls-trusted #invite #chan #help'
|
2014-03-11 19:05:17 +00:00
|
|
|
elif cmd=='me':
|
|
|
|
return 'I shall.'
|
2015-03-01 00:30:59 +00:00
|
|
|
elif cmd in helptext:
|
|
|
|
if helptext[cmd]:
|
|
|
|
return '%s %s %s' % (cmd, usage(cmd, False), helptext[cmd])
|
|
|
|
else:
|
|
|
|
return '%s %s' % (cmd, usage(cmd, False))
|
2013-07-08 15:09:18 +00:00
|
|
|
else:
|
2014-04-03 18:35:46 +00:00
|
|
|
return None
|