monolith/threshold

869 lines
33 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python
from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.internet.ssl import DefaultOpenSSLContextFactory
from twisted.internet.protocol import Protocol, Factory
2017-11-23 20:37:00 +00:00
from twisted.internet.endpoints import SSL4ClientEndpoint, TCP4ClientEndpoint, connectProtocol
from twisted.words.protocols.irc import IRCClient
from json import load, dump, loads
from sys import exit
2017-12-03 18:34:56 +00:00
from subprocess import run, PIPE
listener = None
connections = {}
2017-11-23 20:37:00 +00:00
IRCPool = {}
def log(data):
print("[LOG]", data)
def debug(data):
print("[DEBUG]", data)
def warn(data):
print("[WARNING]", data)
def error(data):
print("[ERROR]", data)
exit(1)
def sendData(addr, data):
connections[addr].send(data)
def sendSuccess(addr, data):
sendData(addr, "[y] " + data)
def sendFailure(addr, data):
sendData(addr, "[n] " + data)
def sendInfo(addr, data):
sendData(addr, "[i] " + data)
2017-11-23 20:37:00 +00:00
class IRCBot(IRCClient):
def __init__(self, name):
self.connected = False
self.channels = []
2017-11-23 20:37:00 +00:00
self.name = name
instance = pool[name]
self.nickname = instance["nickname"]
self.realname = instance["realname"]
self.username = instance["username"]
self.userinfo = instance["userinfo"]
self.fingerReply = instance["finger"]
self.versionName = instance["version"]
self.versionNum = None
self.versionEnv = None
self.sourceURL = instance["source"]
2017-11-25 19:48:20 +00:00
self.autojoin = instance["autojoin"]
2017-11-23 20:37:00 +00:00
self._who = {}
self._getWho = {}
self.wholist = {}
self.authtype = instance["authtype"]
if self.authtype == "ns":
self.authpass = instance["password"]
self.authentity = instance["authentity"]
else:
self.password = instance["password"]
def refresh(self):
instance = pool[self.name]
2017-11-23 20:37:00 +00:00
if not instance["nickname"] == self.nickname:
self.nickname = instance["nickname"]
self.setNick(self.nickname)
self.userinfo = instance["userinfo"]
self.fingerReply = instance["finger"]
self.versionName = instance["version"]
self.versionNum = None
self.versionEnv = None
self.sourceURL = instance["source"]
def privmsg(self, user, channel, msg):
toSend = helper.isKeyword(msg)
if self.name == config["Master"][0] and channel == config["Master"][1]:
pass
else:
if config["HighlightNotifications"]:
msgLower = msg.lower()
2017-12-02 19:49:00 +00:00
nickLower = self.nickname.lower()
if nickLower in msgLower:
msgLower = msgLower.replace(nickLower, "{"+nickLower+"}")
helper.sendMaster("NICK PRV %s (T:%s): (%s/%s) %s" % (self.name, msgLower.count(nickLower), user, channel, msgLower))
if toSend:
helper.sendMaster("MATCH PRV %s (U:%s T:%s): (%s/%s) %s" % (self.name, toSend[1], toSend[2], user, channel, toSend[0]))
def noticed(self, user, channel, msg):
toSend = helper.isKeyword(msg)
if self.name == config["Master"][0] and channel == config["Master"][1]:
pass
else:
if config["HighlightNotifications"]:
msgLower = msg.lower()
2017-12-02 19:49:00 +00:00
nickLower = self.nickname.lower()
if nickLower in msgLower:
msgLower = msgLower.replace(nickLower, "{"+nickLower+"}")
helper.sendMaster("NICK NOT %s (T:%s): (%s/%s) %s" % (self.name, msgLower.count(nickLower), user, channel, msgLower))
if toSend:
helper.sendMaster("MATCH NOT %s (U:%s T:%s): (%s/%s) %s" % (self.name, toSend[1], toSend[2], user, channel, toSend[0]))
def action(self, user, channel, msg):
toSend = helper.isKeyword(msg)
if self.name == config["Master"][0] and channel == config["Master"][1]:
pass
else:
if config["HighlightNotifications"]:
msgLower = msg.lower()
2017-12-02 19:49:00 +00:00
nickLower = self.nickname.lower()
if nickLower in msgLower:
msgLower = msgLower.replace(nickLower, "{"+nickLower+"}")
helper.sendMaster("NICK ACT %s (T:%s): (%s/%s) %s" % (self.name, msgLower.count(nickLower), user, channel, msgLower))
if toSend:
helper.sendMaster("MATCH ACT %s (U:%s T:%s): (%s/%s) %s" % (self.name, toSend[1], toSend[2], user, channel, toSend[0]))
def get(self, var):
try:
result = getattr(self, var)
except AttributeError:
result = None
return result
2017-11-23 20:37:00 +00:00
def setNick(self, nickname):
self._attemptedNick = nickname
self.sendLine("NICK %s" % nickname)
self.nickname = nickname
def alterCollidedNick(self, nickname):
newnick = nickname + "_"
return newnick
def irc_ERR_NICKNAMEINUSE(self, prefix, params):
self._attemptedNick = self.alterCollidedNick(self._attemptedNick)
self.setNick(self._attemptedNick)
def irc_ERR_PASSWDMISMATCH(self, prefix, params):
log("%s: password mismatch" % self.name)
helper.sendAll("%s: password mismatch" % self.name)
2017-11-23 20:37:00 +00:00
def who(self, channel):
channel = channel
d = Deferred()
2017-11-23 20:37:00 +00:00
if channel not in self._who:
self._who[channel] = ([], {})
self._who[channel][0].append(d)
self.sendLine("WHO %s" % channel)
return d
def irc_RPL_WHOREPLY(self, prefix, params):
channel = params[1]
user = params[2]
host = params[3]
server = params[4]
nick = params[5]
status = params[6]
realname = params[7]
if channel not in self._who:
return
n = self._who[channel][1]
n[nick] = [nick, user, host, server, status, realname]
def irc_RPL_ENDOFWHO(self, prefix, params):
channel = params[1]
if channel not in self._who:
return
callbacks, info = self._who[channel]
for cb in callbacks:
cb.callback((channel, info))
del self._who[channel]
def got_who(self, whoinfo):
self.wholist[whoinfo[0]] = whoinfo[1]
def signedOn(self):
self.connected = True
2017-11-23 20:37:00 +00:00
if self.authtype == "ns":
self.msg(self.authentity, "IDENTIFY %s" % self.nspass)
2017-11-25 19:48:20 +00:00
for i in self.autojoin:
self.join(i)
2017-11-23 20:37:00 +00:00
def joined(self, channel):
if not channel in self.channels:
self.channels.append(channel)
2017-11-23 20:37:00 +00:00
self.who(channel).addCallback(self.got_who)
def left(self, channel):
if channel in self.channels:
self.channels.remove(channel)
def kickedFrom(self, channel, kicker, message):
if channel in self.channels:
self.channels.remove(channel)
2017-11-28 19:31:02 +00:00
helper.sendMaster("KICK %s: (%s/%s) %s" % (self.name, kicker, channel, message))
def connectionLost(self, reason):
self.connected = False
self.channels = []
error = reason.getErrorMessage()
log("%s: connection lost: %s" % (self.name, error))
helper.sendAll("%s: connection lost: %s" % (self.name, error))
def connectionFailed(self, reason):
self.connected = False
self.channels = []
error = reason.getErrorMessage()
log("%s: connection failed: %s" % (self.name, error))
helper.sendAll("%s: connection failed: %s" % (self.name, error))
class Base(Protocol):
def __init__(self, addr):
self.addr = addr
self.authed = False
if config["UsePassword"] == False:
self.authed = True
def send(self, data):
data += "\r\n"
data = data.encode("utf-8", "replace")
self.transport.write(data)
def dataReceived(self, data):
data = data.decode("utf-8", "replace")
2017-11-27 19:54:35 +00:00
#log("Data received from %s:%s -- %s" % (self.addr.host, self.addr.port, repr(data)))
2017-12-03 13:10:51 +00:00
if "\n" in data:
splitData = [x for x in data.split("\n") if x]
if "\n" in data:
#timePlus = 0.0
for i in splitData:
helper.parseCommand(self.addr, self.authed, i)
#reactor.callLater(timePlus, lambda: helper.parseCommand(self.addr, self.authed, i))
#timePlus += 0.01
return
helper.parseCommand(self.addr, self.authed, data)
def connectionMade(self):
log("Connection from %s:%s" % (self.addr.host, self.addr.port))
self.send("Hello.")
def connectionLost(self, reason):
global connections
self.authed = False
log("Connection lost from %s:%s -- %s" % (self.addr.host, self.addr.port, reason.getErrorMessage()))
if not listener == None:
if self.addr in connections.keys():
del connections[self.addr]
else:
warn("Tried to remove a non-existant connection.")
else:
warn("Tried to remove a connection from a listener that wasn't running.")
class BaseFactory(Factory):
def buildProtocol(self, addr):
global connections
entry = Base(addr)
connections[addr] = entry
return entry
def send(self, addr, data):
global connections
if addr in connections.keys():
connection = connections[addr]
connection.send(data)
else:
return
2017-11-20 19:53:25 +00:00
class Helper(object):
def getConfig(self):
with open("config.json", "r") as f:
config = load(f)
if set(["Port", "BindAddress", "UseSSL", "UsePassword"]).issubset(set(config.keys())):
if config["UseSSL"] == True:
if not set(["ListenerKey", "ListenerCertificate"]).issubset(set(config.keys())):
2017-11-20 19:53:25 +00:00
error("SSL is on but certificate or key is not defined")
if config["UsePassword"] == True:
if not "Password" in config.keys():
error("Password authentication is on but password is not defined")
2017-11-20 19:53:25 +00:00
return config
else:
error("Mandatory values missing from config")
2017-12-03 13:10:51 +00:00
def saveConfig(self):
global config
with open("config.json", "w") as f:
dump(config, f, indent=4)
return
2017-12-03 13:10:51 +00:00
def getKeywordConfig(self):
with open("keyword.json", "r") as f:
keyconf = load(f)
return keyconf
def saveKeywordConfig(self):
global keyconf
with open("keyword.json", "w") as f:
dump(keyconf, f, indent=4)
return
def getPool(self):
with open("pool.json", "r") as f:
data = f.read()
if not data == "":
pool = loads(data.strip())
return pool
else:
return {}
def savePool(self):
global pool
with open("pool.json", "w") as f:
dump(pool, f, indent=4)
return
def getHelp(self):
with open("help.json", "r") as f:
help = load(f)
return help
def incorrectUsage(self, addr, mode):
if mode == None:
sendFailure(addr, "Incorrect usage")
return
if mode in help.keys():
sendFailure(addr, "Usage: " + help[mode])
return
def sendAll(self, data):
global connections
for i in connections:
connections[i].send(data)
return
def sendMaster(self, data):
if config["Master"][0] in IRCPool.keys():
IRCPool[config["Master"][0]].msg(config["Master"][1], data)
def isKeyword(self, msg):
message = msg.lower()
messageDuplicate = message
2017-11-27 19:54:35 +00:00
toUndo = False
uniqueNum = 0
totalNum = 0
2017-12-03 13:10:51 +00:00
for i in keyconf["Keywords"]:
if i in message:
2017-12-03 13:10:51 +00:00
if i in keyconf["KeywordsExcept"].keys():
for x in keyconf["KeywordsExcept"][i]:
2017-11-27 19:54:35 +00:00
if x in message:
toUndo = True
messageDuplicate = messageDuplicate.replace(x, "\0\r\n\n\0")
2017-12-03 13:10:51 +00:00
for y in keyconf["Keywords"]:
if i in messageDuplicate:
totalNum += messageDuplicate.count(i)
message = messageDuplicate.replace(i, "{"+i+"}")
message = message.replace("\0\r\n\n\0", x)
uniqueNum += 1
if toUndo == False:
totalNum += message.count(i)
message = message.replace(i, "{"+i+"}")
uniqueNum += 1
2017-11-27 19:54:35 +00:00
toUndo = False
if totalNum == 0:
return False
else:
return [message, uniqueNum, totalNum]
2017-11-23 20:37:00 +00:00
def addBot(self, name):
global IRCPool
instance = pool[name]
log("Started bot %s to %s:%s protocol %s nickname %s" % (name, instance["host"], instance["port"], instance["protocol"], instance["nickname"]))
2017-11-23 20:37:00 +00:00
if instance["protocol"] == "plain":
if instance["bind"] == None:
point = TCP4ClientEndpoint(reactor, instance["host"], int(instance["port"]), timeout=int(instance["timeout"]))
bot = IRCBot(name)
IRCPool[name] = bot
d = connectProtocol(point, bot)
return
else:
point = TCP4ClientEndpoint(reactor, instance["host"], int(instance["port"]), timeout=int(instance["timeout"]), bindAddress=instance["bind"])
bot = IRCBot(name)
IRCPool[name] = bot
d = connectProtocol(point, bot)
return
elif instance["protocol"] == "ssl":
contextFactory = DefaultOpenSSLContextFactory(instance["key"].encode("utf-8", "replace"), instance["certificate"].encode("utf-8", "replace"))
if instance["bind"] == None:
point = SSL4ClientEndpoint(reactor, instance["host"], int(instance["port"]), contextFactory, timeout=int(instance["timeout"]))
bot = IRCBot(name)
IRCPool[name] = bot
d = connectProtocol(point, bot)
return
else:
point = SSL4ClientEndpoint(reactor, instance["host"], int(instance["port"]), contextFactory, timeout=int(instance["timeout"]), bindAddress=instance["bind"])
bot = IRCBot(name)
IRCPool[name] = bot
d = connectProtocol(point, bot)
return
def addKeyword(self, keyword):
2017-12-03 13:10:51 +00:00
if keyword in keyconf["Keywords"]:
return "EXISTS"
else:
2017-12-03 13:10:51 +00:00
for i in keyconf["Keywords"]:
if i in keyword or keyword in i:
return "ISIN"
2017-12-03 13:10:51 +00:00
keyconf["Keywords"].append(keyword)
helper.saveKeywordConfig()
return True
def delKeyword(self, keyword):
2017-12-03 13:10:51 +00:00
if not keyword in keyconf["Keywords"]:
return "NOKEY"
2017-12-03 13:10:51 +00:00
keyconf["Keywords"].remove(keyword)
helper.saveKeywordConfig()
return True
def parseCommand(self, addr, authed, data):
global pool
spl = data.split()
2017-12-03 13:10:51 +00:00
if addr in connections.keys():
obj = connections[addr]
else:
warning("Got connection object with no instance in the address pool")
return
success = lambda data: sendSuccess(addr, data)
failure = lambda data: sendFailure(addr, data)
info = lambda data: sendInfo(addr, data)
incUsage = lambda mode: self.incorrectUsage(addr, mode)
length = len(spl)
if len(spl) > 0:
cmd = spl[0]
else:
failure("No text was sent")
return
if authed == True:
if cmd == "help":
helpMap = []
for i in help.keys():
helpMap.append("%s: %s" % (i, help[i]))
info("\n".join(helpMap))
return
elif cmd == "rehash":
global config
config = helper.getConfig()
2017-12-03 13:10:51 +00:00
log("Configuration rehashed")
success("Configuration rehashed successfully")
2017-12-03 13:10:51 +00:00
elif cmd == "rekey":
global keyconf
keyconf = helper.getKeywordConfig()
log("Keyword configuration rehashed")
success("Keyword configuration rehashed successfully")
2017-12-03 18:34:56 +00:00
elif cmd == "dist":
if config["DistEnabled"]:
rtrn = run(["./dist.sh"], shell=True, stdout=PIPE)
info("Exit code: %s -- Stdout: %s" % (rtrn.returncode, rtrn.stdout))
else:
failure("The dist command is not enabled")
return
elif cmd == "pass":
info("You are already authenticated")
return
elif cmd == "logout":
obj.authed = False
success("Logged out")
return
elif cmd == "list":
poolMap = []
for i in pool.keys():
2017-11-23 19:11:29 +00:00
poolMap.append("Server: %s" % i)
for x in pool[i].keys():
poolMap.append("%s: %s" % (x, pool[i][x]))
poolMap.append("\n")
info("\n".join(poolMap))
return
2017-11-23 20:37:00 +00:00
elif cmd == "enable":
if length == 2:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
pool[spl[1]]["enabled"] = True
helper.savePool()
2017-11-25 19:44:03 +00:00
if not spl[1] in IRCPool.keys():
self.addBot(spl[1])
else:
pass
2017-11-23 20:37:00 +00:00
success("Successfully enabled bot %s" % spl[1])
return
else:
incUsage("enable")
return
elif cmd == "disable":
if length == 2:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
pool[spl[1]]["enabled"] = False
helper.savePool()
2017-11-23 20:37:00 +00:00
if spl[1] in IRCPool.keys():
if IRCPool[spl[1]].connected == True:
IRCPool[spl[1]].transport.loseConnection()
2017-11-25 20:26:56 +00:00
del IRCPool[spl[1]]
2017-11-23 20:37:00 +00:00
success("Successfully disabled bot %s" % spl[1])
return
else:
incUsage("disable")
return
elif cmd == "join":
if length == 3:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[1] in IRCPool.keys():
failure("Name has no instance: %s" % spl[1])
return
IRCPool[spl[1]].join(spl[2])
success("Joined %s" % spl[2])
return
elif length == 4:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[1] in IRCPool.keys():
failure("Name has no instance: %s" % spl[1])
return
IRCPool[spl[1]].join(spl[2], spl[3])
success("Joined %s with key %s" % (spl[2], spl[3]))
return
else:
incUsage("join")
return
elif cmd == "part":
if length == 3:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[1] in IRCPool.keys():
failure("Name has no instance: %s" % spl[1])
return
IRCPool[spl[1]].part(spl[2])
success("Left %s" % spl[2])
return
else:
incUsage("part")
return
elif cmd == "get":
if length == 3:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[1] in IRCPool.keys():
failure("Name has no instance: %s" % spl[1])
return
info(str(IRCPool[spl[1]].get(spl[2])))
return
else:
incUsage("get")
return
elif cmd == "key":
if data.startswith("key add"):
2017-11-27 19:54:35 +00:00
if not data in ["key add ", "key add"] and data[3] == " ":
keywordsToAdd = data[8:]
keywords = keywordsToAdd.split(",")
for keyword in keywords:
rtrn = self.addKeyword(keyword)
if rtrn == "EXISTS":
failure("Keyword already exists: %s" % keyword)
elif rtrn == "ISIN":
failure("Keyword already matched: %s" % keyword)
elif rtrn == True:
success("Keyword added: %s" % keyword)
return
else:
incUsage("key")
return
elif data.startswith("key del"):
2017-11-27 19:54:35 +00:00
if not data in ["key del ", "key del"] and data[3] == " ":
keywordsToDel = data[8:]
keywords = keywordsToDel.split(",")
for keyword in keywords:
rtrn = self.delKeyword(keyword)
if rtrn == "NOKEY":
failure("Keyword does not exist: %s" % keyword)
elif rtrn == True:
success("Keyword deleted: %s" % keyword)
return
else:
incUsage("key")
return
2017-11-27 19:54:35 +00:00
if length == 4:
if spl[1] == "except":
2017-12-03 13:10:51 +00:00
if not spl[2] in keyconf["Keywords"]:
2017-11-27 19:54:35 +00:00
failure("No such keyword: %s" % spl[2])
return
2017-12-03 13:10:51 +00:00
if spl[2] in keyconf["KeywordsExcept"].keys():
if spl[3] in keyconf["KeywordsExcept"][spl[2]]:
2017-11-27 19:54:35 +00:00
failure("Exception exists: %s" % spl[3])
return
else:
if not spl[2] in spl[3]:
failure("Keyword %s not in exception %s. This won't work" % (spl[2], spl[3]))
return
2017-12-03 13:10:51 +00:00
keyconf["KeywordsExcept"][spl[2]] = []
2017-11-27 19:54:35 +00:00
2017-12-03 13:10:51 +00:00
keyconf["KeywordsExcept"][spl[2]].append(spl[3])
helper.saveKeywordConfig()
2017-11-27 19:54:35 +00:00
success("Successfully added exception %s for keyword %s" % (spl[3], spl[2]))
return
2017-12-03 19:11:06 +00:00
elif spl[1] == "master":
if not spl[2] in pool.keys():
failure("Name does not exist: %s" % spl[2])
return
if spl[2] in IRCPool.keys():
if not spl[3] in IRCPool[spl[2]].channels:
info("Bot not on channel: %s" % spl[3])
config["Master"] = [spl[2], spl[3]]
helper.saveConfig()
success("Master set to %s on %s" % (spl[3], spl[2]))
return
2017-11-27 19:54:35 +00:00
elif spl[1] == "unexcept":
2017-12-03 13:10:51 +00:00
if not spl[2] in keyconf["KeywordsExcept"].keys():
2017-11-27 19:54:35 +00:00
failure("No such exception: %s" % spl[2])
return
2017-12-03 13:10:51 +00:00
if not spl[3] in keyconf["KeywordsExcept"][spl[2]]:
2017-11-27 19:54:35 +00:00
failure("Exception %s has no attribute %s" % (spl[2], spl[3]))
return
2017-12-03 13:10:51 +00:00
keyconf["KeywordsExcept"][spl[2]].remove(spl[3])
if keyconf["KeywordsExcept"][spl[2]] == []:
del keyconf["KeywordsExcept"][spl[2]]
helper.saveKeywordConfig()
2017-11-27 19:54:35 +00:00
success("Successfully removed exception %s for keyword %s" % (spl[3], spl[2]))
return
else:
incUsage("key")
return
2017-12-03 19:11:06 +00:00
elif length == 3:
2017-11-27 19:54:35 +00:00
if spl[1] == "unexcept":
2017-12-03 13:10:51 +00:00
if not spl[2] in keyconf["KeywordsExcept"].keys():
2017-11-27 19:54:35 +00:00
failure("No such exception: %s" % spl[2])
return
2017-12-03 13:10:51 +00:00
del keyconf["KeywordsExcept"][spl[2]]
helper.saveKeywordConfig()
2017-11-27 19:54:35 +00:00
success("Successfully removed exception list of %s" % spl[2])
return
2017-12-03 19:11:06 +00:00
else:
incUsage("key")
elif length == 2:
2017-11-27 19:54:35 +00:00
if spl[1] == "show":
2017-12-03 13:10:51 +00:00
info(",".join(keyconf["Keywords"]))
2017-11-27 19:54:35 +00:00
return
elif spl[1] == "showexcept":
exceptMap = []
2017-12-03 13:10:51 +00:00
for i in keyconf["KeywordsExcept"].keys():
2017-11-27 19:54:35 +00:00
exceptMap.append("Key: %s" % i)
2017-12-03 13:10:51 +00:00
exceptMap.append("%s: %s" % (i, ",".join(keyconf["KeywordsExcept"][i])))
2017-11-27 19:54:35 +00:00
exceptMap.append("\n")
info("\n".join(exceptMap))
return
2017-12-03 19:11:06 +00:00
elif spl[1] == "master":
info(" - ".join(config["Master"]))
return
else:
incUsage("key")
return
elif cmd == "add":
if length == 6:
if spl[1] in pool.keys():
failure("Name already exists: %s" % spl[1])
return
protocol = spl[4].lower()
if not protocol in ["ssl", "plain"]:
incUsage("connect")
return
2017-11-23 19:19:48 +00:00
try:
int(spl[3])
except:
failure("Port must be an integer, not %s" % spl[3])
return
2017-11-23 20:37:00 +00:00
pool[spl[1]] = { "host": spl[2],
"port": spl[3],
"protocol": protocol,
2017-11-23 20:37:00 +00:00
"bind": None,
"timeout": 30,
"nickname": spl[5],
2017-11-25 19:20:23 +00:00
"username": config["Default"]["username"],
2017-11-23 19:11:29 +00:00
"realname": None,
"userinfo": None,
"finger": None,
"version": None,
"source": None,
2017-11-25 19:48:20 +00:00
"autojoin": [],
2017-11-25 19:20:23 +00:00
"authtype": config["Default"]["authtype"],
"password": config["Default"]["password"],
2017-11-23 20:37:00 +00:00
"authentity": "NickServ",
"key": config["ListenerKey"],
"certificate": config["ListenerCertificate"],
"enabled": config["ConnectOnCreate"],
}
2017-11-23 20:37:00 +00:00
if config["ConnectOnCreate"] == True:
self.addBot(spl[1])
success("Successfully created bot")
self.savePool()
return
else:
incUsage("add")
return
elif cmd == "del":
if length == 2:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
del pool[spl[1]]
2017-11-23 20:37:00 +00:00
if spl[1] in IRCPool.keys():
if IRCPool[spl[1]].connected == True:
IRCPool[spl[1]].transport.loseConnection()
2017-11-23 20:37:00 +00:00
del IRCPool[spl[1]]
success("Successfully removed bot")
self.savePool()
return
else:
incUsage("del")
return
2017-11-23 19:11:29 +00:00
elif cmd == "mod":
2017-11-23 20:37:00 +00:00
toUnset = False
2017-11-23 19:11:29 +00:00
if length == 2:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
optionMap = ["Viewing options for %s" % spl[1]]
for i in pool[spl[1]].keys():
optionMap.append("%s: %s" % (i, pool[spl[1]][i]))
info("\n".join(optionMap))
return
elif length == 3:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[2] in pool[spl[1]].keys():
failure("No such key: %s" % spl[2])
return
info("%s: %s" % (spl[2], pool[spl[1]][spl[2]]))
return
elif length == 4:
if not spl[1] in pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[2] in pool[spl[1]].keys():
failure("No such key: %s" % spl[2])
return
2017-11-23 20:37:00 +00:00
if spl[2] in ["port", "timeout"]:
2017-11-23 19:19:48 +00:00
try:
int(spl[3])
except:
2017-11-23 20:37:00 +00:00
failure("Value must be an integer, not %s" % spl[3])
2017-11-23 19:19:48 +00:00
return
if spl[2] == "protocol":
if not spl[3] in ["ssl", "plain"]:
failure("Protocol must be ssl or plain, not %s" % spl[3])
return
2017-11-23 19:11:29 +00:00
if spl[3] == pool[spl[1]][spl[2]]:
failure("Value already exists: %s" % spl[3])
return
2017-11-23 20:37:00 +00:00
if spl[3].lower() in ["none", "nil"]:
spl[3] = None
toUnset = True
if spl[2] == "authtype":
2017-11-25 19:29:48 +00:00
if not toUnset:
if not spl[3] in ["sp", "ns"]:
failure("Authtype must be sp or ns, not %s" % spl[3])
return
2017-11-23 20:37:00 +00:00
if spl[2] == "enabled":
failure("Use the enable and disable commands to manage this")
return
2017-11-25 19:48:20 +00:00
if spl[2] == "autojoin":
spl[3] = spl[3].split(",")
2017-11-23 20:37:00 +00:00
2017-11-23 19:11:29 +00:00
pool[spl[1]][spl[2]] = spl[3]
if spl[1] in IRCPool.keys():
IRCPool[spl[1]].refresh()
2017-11-23 20:37:00 +00:00
self.savePool()
if toUnset:
success("Successfully unset key %s on %s" % (spl[2], spl[1]))
2017-11-23 20:37:00 +00:00
else:
success("Successfully set key %s to %s on %s" % (spl[2], spl[3], spl[1]))
2017-11-23 19:11:29 +00:00
return
else:
incUsage("mod")
return
2017-11-23 19:11:29 +00:00
else:
incUsage(None)
return
else:
if cmd == "pass" and length == 2:
if spl[1] == config["Password"]:
success("Authenticated successfully")
obj.authed = True
return
else:
failure("Password incorrect")
obj.transport.loseConnection()
return
else:
incUsage(None)
return
if __name__ == "__main__":
2017-11-20 19:53:25 +00:00
helper = Helper()
config = helper.getConfig()
2017-12-03 13:10:51 +00:00
keyconf = helper.getKeywordConfig()
pool = helper.getPool()
help = helper.getHelp()
2017-11-23 20:37:00 +00:00
for i in pool.keys():
if pool[i]["enabled"] == True:
helper.addBot(i)
listener = BaseFactory()
if config["UseSSL"] == True:
reactor.listenSSL(config["Port"], listener, DefaultOpenSSLContextFactory(config["ListenerKey"], config["ListenerCertificate"]), interface=config["BindAddress"])
log("Threshold running with SSL on %s:%s" % (config["BindAddress"], config["Port"]))
else:
reactor.listenTCP(config["Port"], listener, interface=config["BindAddress"])
log("Threshold running on %s:%s" % (config["BindAddress"], config["Port"]))
reactor.run()