diff --git a/help.json b/help.json index e69d776..98cd1b4 100644 --- a/help.json +++ b/help.json @@ -4,6 +4,8 @@ "add": "add
", "del": "del ", "mod": "mod [] []", + "get": "get ", + "join": "join []", "enable": "enable ", "list": "list", diff --git a/threshold b/threshold index 0ae261b..8253a77 100755 --- a/threshold +++ b/threshold @@ -1,5 +1,6 @@ #!/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 from twisted.internet.endpoints import SSL4ClientEndpoint, TCP4ClientEndpoint, connectProtocol @@ -39,6 +40,9 @@ def sendInfo(addr, data): class IRCBot(IRCClient): def __init__(self, name): + self.connected = False + self.channels = [] + self.name = name instance = pool[name] @@ -64,7 +68,7 @@ class IRCBot(IRCClient): self.password = instance["password"] def refresh(self): - instance = pool[name] + instance = pool[self.name] if not instance["nickname"] == self.nickname: self.nickname = instance["nickname"] self.setNick(self.nickname) @@ -76,6 +80,13 @@ class IRCBot(IRCClient): self.versionEnv = None self.sourceURL = instance["source"] + def get(self, var): + try: + result = getattr(self, var) + except AttributeError: + result = None + return result + def sanitize(self, user): user = user.replace("!", "") user = user.replace("~", "") @@ -99,36 +110,12 @@ class IRCBot(IRCClient): self.setNick(self._attemptedNick) def irc_ERR_PASSWDMISMATCH(self, prefix, params): - ircLog(self.ident, "Password mismatch") - manager.handleWrongPassword(self.ident, prefix, params) - - def irc_RPL_NAMREPLY(self, prefix, params): - channel = params[2] - nicklist = params[3].split(' ') - - if channel not in self._names: - return - n = self._names[channel][1] - n += nicklist - - def irc_RPL_ENDOFNAMES(self, prefix, params): - channel = params[1] - if channel not in self._names: - return - callbacks, namelist = self._names[channel] - for cb in callbacks: - cb.callback((channel, namelist)) - del self._names[channel] - - def got_names(self, nicklist): - ncklist = [] - for i in nicklist[1]: - ncklist.append(self.sanitize(i)) - self.nameslist[nicklist[0]] = ncklist + log("%s: password mismatch" % self.name) + helper.sendAll("%s: password mismatch" % self.name) def who(self, channel): channel = channel - d = defer.Deferred() + d = Deferred() if channel not in self._who: self._who[channel] = ([], {}) self._who[channel][0].append(d) @@ -161,12 +148,37 @@ class IRCBot(IRCClient): self.wholist[whoinfo[0]] = whoinfo[1] def signedOn(self): + self.connected = True if self.authtype == "ns": self.msg(self.authentity, "IDENTIFY %s" % self.nspass) def joined(self, channel): + if not channel in self.channels: + self.channels.append(channel) 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) + + 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 @@ -258,9 +270,16 @@ class Helper(object): sendFailure(addr, "Usage: " + help[mode]) return + def sendAll(self, data): + global connections + for i in connections: + connections[i].send(data) + return + 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"])) if instance["protocol"] == "plain": if instance["bind"] == None: point = TCP4ClientEndpoint(reactor, instance["host"], int(instance["port"]), timeout=int(instance["timeout"])) @@ -345,6 +364,7 @@ class Helper(object): failure("Name does not exist: %s" % spl[1]) return pool[spl[1]]["enabled"] = True + helper.savePool() self.addBot(spl[1]) success("Successfully enabled bot %s" % spl[1]) return @@ -358,14 +378,67 @@ class Helper(object): failure("Name does not exist: %s" % spl[1]) return pool[spl[1]]["enabled"] = False + helper.savePool() if spl[1] in IRCPool.keys(): - IRCPool[spl[1]].transport.loseConnection() + if IRCPool[spl[1]].connected == True: + IRCPool[spl[1]].transport.loseConnection() 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") + + 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") + + 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") + elif cmd == "add": if length == 6: @@ -421,7 +494,8 @@ class Helper(object): return del pool[spl[1]] if spl[1] in IRCPool.keys(): - IRCPool[spl[1]].transport.loseConnection() + if IRCPool[spl[1]].connected == True: + IRCPool[spl[1]].transport.loseConnection() del IRCPool[spl[1]] success("Successfully removed bot") self.savePool() @@ -486,6 +560,8 @@ class Helper(object): return pool[spl[1]][spl[2]] = spl[3] + if spl[1] in IRCPool.keys(): + IRCPool[spl[1]].refresh() self.savePool() if toUnset: success("Successfully unset key %s on %s" % (spl[2], spl[3], spl[1]))