2013-06-29 22:01:33 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
import threading
|
|
|
|
import time
|
|
|
|
import socket
|
|
|
|
import sys
|
|
|
|
|
|
|
|
import botcmd
|
|
|
|
|
|
|
|
class Channel:
|
|
|
|
def __init__(self):
|
2015-03-01 00:30:59 +00:00
|
|
|
self.lock = threading.Lock()
|
|
|
|
self.msg = []
|
|
|
|
|
|
|
|
def send(self, msg):
|
2013-06-29 22:01:33 +00:00
|
|
|
self.lock.acquire()
|
|
|
|
self.msg.append(msg)
|
|
|
|
self.lock.release()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
|
|
|
def recv(self, wait = True):
|
2013-06-29 22:01:33 +00:00
|
|
|
while True:
|
|
|
|
self.lock.acquire()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
|
|
|
if len(self.msg) > 0:
|
|
|
|
msg = self.msg.pop(0)
|
2013-06-29 22:01:33 +00:00
|
|
|
self.lock.release()
|
|
|
|
return msg
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
if not wait:
|
|
|
|
self.lock.release()
|
|
|
|
return None
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
self.lock.release()
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
2015-01-24 11:53:12 +00:00
|
|
|
class Irc:
|
|
|
|
def __init__(self, chan, nick, inpc):
|
|
|
|
self.chan = chan
|
|
|
|
self.nick = nick
|
|
|
|
self.inpc = inpc
|
|
|
|
|
|
|
|
def send(self, msg):
|
|
|
|
self.inpc.send(msg)
|
|
|
|
|
|
|
|
def recv(self, wait=True):
|
|
|
|
return self.inpc.recv(wait)
|
|
|
|
|
|
|
|
def msg(self, chan, msg):
|
|
|
|
self.inpc.send('PRIVMSG %s :%s' % (chan, msg))
|
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
class Connhandler(threading.Thread):
|
2015-03-01 00:30:59 +00:00
|
|
|
def __init__(self, server, port, chan, nick, botname, inpc, logc):
|
2013-06-29 22:01:33 +00:00
|
|
|
threading.Thread.__init__(self)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
|
|
|
self.server = server
|
|
|
|
self.port = port
|
|
|
|
self.nick = nick
|
|
|
|
self.name = botname
|
|
|
|
self.chan = chan
|
|
|
|
self.inpc = inpc
|
|
|
|
self.logc = logc
|
|
|
|
|
|
|
|
def send(self, s):
|
|
|
|
s = s.replace('\n', '\\n').replace('\r', '\\r') # Sanitize output
|
|
|
|
if len(s) > 512:
|
|
|
|
s = s[:512]
|
|
|
|
|
|
|
|
self.sock.send(s + '\r\n')
|
|
|
|
if s.split(' ')[0] != 'PONG':
|
|
|
|
self.logc.send(s + '\n')
|
|
|
|
|
|
|
|
def check(self, line):
|
|
|
|
args = line.split(' ')
|
|
|
|
if args[0] == 'PING':
|
2013-06-29 22:01:33 +00:00
|
|
|
self.send('PONG :hjdicks')
|
|
|
|
else:
|
2015-03-01 00:30:59 +00:00
|
|
|
self.logc.send(line + '\n')
|
|
|
|
Threadwrapper(botcmd.parse, (line, Irc(self.chan, self.nick, self.inpc))).start()
|
2013-06-29 22:01:33 +00:00
|
|
|
def run(self):
|
2015-03-01 00:30:59 +00:00
|
|
|
self.sock = None
|
|
|
|
for af, socktype, proto, canonname, sa in socket.getaddrinfo(self.server, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM):
|
2013-08-09 08:08:18 +00:00
|
|
|
try:
|
2015-03-01 00:30:59 +00:00
|
|
|
self.sock = socket.socket(af, socktype, proto)
|
2013-08-09 08:08:18 +00:00
|
|
|
except socket.error:
|
2015-03-01 00:30:59 +00:00
|
|
|
self.sock = None
|
2013-08-09 08:08:18 +00:00
|
|
|
conntinue
|
|
|
|
try:
|
|
|
|
self.sock.connect(sa)
|
|
|
|
except socket.error:
|
|
|
|
self.sock.close()
|
2015-03-01 00:30:59 +00:00
|
|
|
self.sock = None
|
2013-08-09 08:08:18 +00:00
|
|
|
continue
|
|
|
|
break
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-08-09 08:08:18 +00:00
|
|
|
if self.sock is None:
|
|
|
|
self.logc.send('QUIT');
|
|
|
|
sys.exit(1);
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
self.sock.settimeout(0.1)
|
|
|
|
|
2015-03-01 00:30:59 +00:00
|
|
|
self.send('NICK %s' % self.nick)
|
|
|
|
self.send('USER %s a a :%s' % (self.nick, self.name))
|
|
|
|
|
|
|
|
f = open('startcmd.txt', 'r')
|
2013-07-18 13:31:25 +00:00
|
|
|
for i in f:
|
2015-03-01 00:30:59 +00:00
|
|
|
if i[-1] == '\n':
|
|
|
|
i = i[:-1]
|
2013-07-18 13:31:25 +00:00
|
|
|
self.send(i)
|
|
|
|
f.close()
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-07-18 13:31:25 +00:00
|
|
|
for i in self.chan.split(' '):
|
2015-03-01 00:30:59 +00:00
|
|
|
self.send('JOIN %s' % i)
|
2013-06-29 22:01:33 +00:00
|
|
|
|
2015-03-01 00:30:59 +00:00
|
|
|
buf = ''
|
2013-06-29 22:01:33 +00:00
|
|
|
while True:
|
|
|
|
while True:
|
|
|
|
try:
|
2015-03-01 00:30:59 +00:00
|
|
|
data = self.sock.recv(4096)
|
2013-06-29 22:01:33 +00:00
|
|
|
break
|
|
|
|
except:
|
|
|
|
pass
|
2015-03-01 00:30:59 +00:00
|
|
|
|
|
|
|
cmd = self.inpc.recv(wait = False)
|
|
|
|
if cmd == 'QUIT':
|
|
|
|
data = None
|
2013-06-29 22:01:33 +00:00
|
|
|
self.logc.send('QUIT')
|
|
|
|
break
|
|
|
|
elif cmd:
|
|
|
|
self.send(cmd)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
time.sleep(0.1)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
|
|
|
if not data:
|
|
|
|
break
|
|
|
|
|
|
|
|
buf += data
|
|
|
|
buf = buf.split('\n')
|
2013-06-29 22:01:33 +00:00
|
|
|
for line in buf[:-1]:
|
2015-03-01 00:30:59 +00:00
|
|
|
if line[-1] == '\r':
|
|
|
|
line = line[:-1]
|
2013-06-29 22:01:33 +00:00
|
|
|
self.check(line)
|
2015-03-01 00:30:59 +00:00
|
|
|
buf = buf[-1]
|
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
self.sock.close()
|
|
|
|
|
|
|
|
class Keyhandler(threading.Thread):
|
2015-03-01 00:30:59 +00:00
|
|
|
def __init__(self, outc):
|
|
|
|
self.outc = outc
|
2013-06-29 22:01:33 +00:00
|
|
|
threading.Thread.__init__(self)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
def run(self):
|
|
|
|
while True:
|
2015-03-01 00:30:59 +00:00
|
|
|
line = raw_input()
|
|
|
|
if line == '':
|
2015-01-24 12:20:11 +00:00
|
|
|
continue
|
2015-03-01 00:30:59 +00:00
|
|
|
|
|
|
|
c = line.split(' ')
|
2013-07-07 12:43:33 +00:00
|
|
|
if c[0] in botcmd.concmd:
|
|
|
|
botcmd.execcmd(c)
|
2015-03-01 00:30:59 +00:00
|
|
|
if c[0] == '/j' and len(c) == 2:
|
|
|
|
self.outc.send('JOIN ' + c[1])
|
|
|
|
elif c[0] == '/m' and len(c) > 2:
|
|
|
|
self.outc.send('PRIVMSG %s :%s' % (c[1], ' '.join(c[2:])))
|
|
|
|
elif c[0] == '/q':
|
|
|
|
if len(c) > 1:
|
|
|
|
self.outc.send('QUIT :%s' % ' '.join(c[1:]))
|
2013-06-29 22:01:33 +00:00
|
|
|
self.outc.send('QUIT')
|
|
|
|
break
|
2015-03-01 00:30:59 +00:00
|
|
|
elif c[0][0] == '/' and c[0] not in botcmd.concmd:
|
|
|
|
self.outc.send(c[0][1:].upper() + ' ' + ' '.join(c[1:]))
|
2013-06-29 22:01:33 +00:00
|
|
|
|
|
|
|
class Loghandler(threading.Thread):
|
2015-03-01 00:30:59 +00:00
|
|
|
def __init__(self, inpc):
|
|
|
|
self.inpc = inpc
|
2013-06-29 22:01:33 +00:00
|
|
|
threading.Thread.__init__(self)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
def run(self):
|
|
|
|
while True:
|
2015-03-01 00:30:59 +00:00
|
|
|
s = self.inpc.recv()
|
|
|
|
if s == 'QUIT':
|
|
|
|
break
|
2014-03-18 16:10:02 +00:00
|
|
|
sys.stdout.write(''.join([i if ord(i)>=32 or i=='\n' else '^'+chr(ord(i)+64) for i in s]))
|
2013-06-29 22:01:33 +00:00
|
|
|
|
|
|
|
class Threadwrapper(threading.Thread):
|
2015-03-01 00:30:59 +00:00
|
|
|
def __init__(self, func, arg):
|
|
|
|
self.func = func
|
|
|
|
self.arg = arg
|
2013-06-29 22:01:33 +00:00
|
|
|
threading.Thread.__init__(self)
|
2015-03-01 00:30:59 +00:00
|
|
|
|
2013-06-29 22:01:33 +00:00
|
|
|
def run(self):
|
|
|
|
self.func(self.arg)
|
|
|
|
|
|
|
|
if len(sys.argv)!=5:
|
2015-03-01 00:30:59 +00:00
|
|
|
print 'Usage: ' + sys.argv[0] + ' server port channel nick'
|
2013-06-29 22:01:33 +00:00
|
|
|
else:
|
2015-03-01 00:30:59 +00:00
|
|
|
keych = Channel()
|
|
|
|
logch = Channel()
|
2013-06-29 22:01:33 +00:00
|
|
|
Keyhandler(keych).start()
|
|
|
|
Loghandler(logch).start()
|
2015-03-01 00:30:59 +00:00
|
|
|
Connhandler(sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4], sys.argv[4], keych, logch).start()
|