|
|
|
@ -3,7 +3,12 @@ from twisted.words.protocols.irc import IRCClient
|
|
|
|
|
from twisted.internet.defer import Deferred
|
|
|
|
|
from twisted.internet.task import LoopingCall
|
|
|
|
|
from twisted.internet import reactor, task
|
|
|
|
|
from twisted.words.protocols.irc import symbolic_to_numeric, numeric_to_symbolic, lowDequote, IRCBadMessage
|
|
|
|
|
from twisted.words.protocols.irc import (
|
|
|
|
|
symbolic_to_numeric,
|
|
|
|
|
numeric_to_symbolic,
|
|
|
|
|
lowDequote,
|
|
|
|
|
IRCBadMessage,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
from string import digits
|
|
|
|
@ -29,16 +34,15 @@ from utils.parsing import parsen
|
|
|
|
|
|
|
|
|
|
from twisted.internet.ssl import DefaultOpenSSLContextFactory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def deliverRelayCommands(num, relayCommands, user=None, stage2=None):
|
|
|
|
|
keyFN = main.certPath+main.config["Key"]
|
|
|
|
|
certFN = main.certPath+main.config["Certificate"]
|
|
|
|
|
contextFactory = DefaultOpenSSLContextFactory(keyFN.encode("utf-8", "replace"),
|
|
|
|
|
certFN.encode("utf-8", "replace"))
|
|
|
|
|
keyFN = main.certPath + main.config["Key"]
|
|
|
|
|
certFN = main.certPath + main.config["Certificate"]
|
|
|
|
|
contextFactory = DefaultOpenSSLContextFactory(keyFN.encode("utf-8", "replace"), certFN.encode("utf-8", "replace"))
|
|
|
|
|
bot = IRCBotFactory(net=None, num=num, relayCommands=relayCommands, user=user, stage2=stage2)
|
|
|
|
|
host, port = getRelay(num)
|
|
|
|
|
rct = reactor.connectSSL(host,
|
|
|
|
|
port,
|
|
|
|
|
bot, contextFactory)
|
|
|
|
|
rct = reactor.connectSSL(host, port, bot, contextFactory)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Copied from the Twisted source so we can fix a bug
|
|
|
|
|
def parsemsg(s):
|
|
|
|
@ -50,21 +54,22 @@ def parsemsg(s):
|
|
|
|
|
@return: A tuple of (prefix, command, args).
|
|
|
|
|
@rtype: L{tuple}
|
|
|
|
|
"""
|
|
|
|
|
prefix = ''
|
|
|
|
|
prefix = ""
|
|
|
|
|
trailing = []
|
|
|
|
|
if not s:
|
|
|
|
|
raise IRCBadMessage("Empty line.")
|
|
|
|
|
if s[0:1] == ':':
|
|
|
|
|
prefix, s = s[1:].split(' ', 1)
|
|
|
|
|
if s.find(' :') != -1:
|
|
|
|
|
s, trailing = s.split(' :', 1)
|
|
|
|
|
args = s.split(' ') # Twisted bug fixed by adding an argument to split()
|
|
|
|
|
if s[0:1] == ":":
|
|
|
|
|
prefix, s = s[1:].split(" ", 1)
|
|
|
|
|
if s.find(" :") != -1:
|
|
|
|
|
s, trailing = s.split(" :", 1)
|
|
|
|
|
args = s.split(" ") # Twisted bug fixed by adding an argument to split()
|
|
|
|
|
args.append(trailing)
|
|
|
|
|
else:
|
|
|
|
|
args = s.split(' ') # And again
|
|
|
|
|
args = s.split(" ") # And again
|
|
|
|
|
command = args.pop(0)
|
|
|
|
|
return prefix, command, args
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IRCRelay(IRCClient):
|
|
|
|
|
def __init__(self, num, relayCommands, user, stage2):
|
|
|
|
|
self.isconnected = False
|
|
|
|
@ -77,7 +82,7 @@ class IRCRelay(IRCClient):
|
|
|
|
|
self.nickname = "relay"
|
|
|
|
|
self.realname = "relay"
|
|
|
|
|
self.username = self.user
|
|
|
|
|
self.password = self.user+":"+password
|
|
|
|
|
self.password = self.user + ":" + password
|
|
|
|
|
|
|
|
|
|
self.relayCommands = relayCommands
|
|
|
|
|
self.num = num
|
|
|
|
@ -109,19 +114,25 @@ class IRCRelay(IRCClient):
|
|
|
|
|
def signedOn(self):
|
|
|
|
|
if not self.isconnected:
|
|
|
|
|
self.isconnected = True
|
|
|
|
|
#log("signed on as a relay: %s" % self.num)
|
|
|
|
|
# log("signed on as a relay: %s" % self.num)
|
|
|
|
|
sleeptime = 0
|
|
|
|
|
increment = 0.8
|
|
|
|
|
for i in self.relayCommands.keys():
|
|
|
|
|
for x in self.relayCommands[i]:
|
|
|
|
|
reactor.callLater(sleeptime, self.msg, main.config["Tweaks"]["ZNC"]["Prefix"]+i, x)
|
|
|
|
|
reactor.callLater(
|
|
|
|
|
sleeptime,
|
|
|
|
|
self.msg,
|
|
|
|
|
main.config["Tweaks"]["ZNC"]["Prefix"] + i,
|
|
|
|
|
x,
|
|
|
|
|
)
|
|
|
|
|
sleeptime += increment
|
|
|
|
|
increment += 0.8
|
|
|
|
|
if not self.stage2 == None:
|
|
|
|
|
reactor.callLater(sleeptime, self.sendStage2)
|
|
|
|
|
reactor.callLater(sleeptime+5, self.transport.loseConnection)
|
|
|
|
|
reactor.callLater(sleeptime + 5, self.transport.loseConnection)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IRCBot(IRCClient):
|
|
|
|
|
def __init__(self, net, num):
|
|
|
|
|
self.isconnected = False
|
|
|
|
@ -135,26 +146,26 @@ class IRCBot(IRCClient):
|
|
|
|
|
relay = main.network[self.net].relays[num]
|
|
|
|
|
self.nickname = alias["nick"]
|
|
|
|
|
self.realname = alias["realname"]
|
|
|
|
|
self.username = alias["nick"].lower()+"/"+relay["net"]
|
|
|
|
|
self.username = alias["nick"].lower() + "/" + relay["net"]
|
|
|
|
|
self.password = main.config["Relay"]["Password"]
|
|
|
|
|
self.userinfo = None #
|
|
|
|
|
self.fingerReply = None #
|
|
|
|
|
self.versionName = None # Don't give out information
|
|
|
|
|
self.versionNum = None #
|
|
|
|
|
self.versionEnv = None #
|
|
|
|
|
self.sourceURL = None #
|
|
|
|
|
|
|
|
|
|
self._getWho = {} # LoopingCall objects -- needed to be able to stop them
|
|
|
|
|
|
|
|
|
|
self._tempWho = {} # temporary storage for gathering WHO info
|
|
|
|
|
self._tempNames = {} # temporary storage for gathering NAMES info
|
|
|
|
|
self._tempList = ([], []) # temporary storage for gathering LIST info
|
|
|
|
|
self.listOngoing = False # we are currently receiving a LIST
|
|
|
|
|
self.listRetried = False # we asked and got nothing so asked again
|
|
|
|
|
self.listAttempted = False # we asked for a list
|
|
|
|
|
self.listSimple = False # after asking again we got the list, so use the simple
|
|
|
|
|
# syntax from now on
|
|
|
|
|
self.wantList = False # we want to send a LIST, but not all relays are active yet
|
|
|
|
|
self.userinfo = None #
|
|
|
|
|
self.fingerReply = None #
|
|
|
|
|
self.versionName = None # Don't give out information
|
|
|
|
|
self.versionNum = None #
|
|
|
|
|
self.versionEnv = None #
|
|
|
|
|
self.sourceURL = None #
|
|
|
|
|
|
|
|
|
|
self._getWho = {} # LoopingCall objects -- needed to be able to stop them
|
|
|
|
|
|
|
|
|
|
self._tempWho = {} # temporary storage for gathering WHO info
|
|
|
|
|
self._tempNames = {} # temporary storage for gathering NAMES info
|
|
|
|
|
self._tempList = ([], []) # temporary storage for gathering LIST info
|
|
|
|
|
self.listOngoing = False # we are currently receiving a LIST
|
|
|
|
|
self.listRetried = False # we asked and got nothing so asked again
|
|
|
|
|
self.listAttempted = False # we asked for a list
|
|
|
|
|
self.listSimple = False # after asking again we got the list, so use the simple
|
|
|
|
|
# syntax from now on
|
|
|
|
|
self.wantList = False # we want to send a LIST, but not all relays are active yet
|
|
|
|
|
self.chanlimit = 0
|
|
|
|
|
self.prefix = {}
|
|
|
|
|
self.servername = None
|
|
|
|
@ -214,8 +225,8 @@ class IRCBot(IRCClient):
|
|
|
|
|
cast["time"] = str(datetime.now().isoformat())
|
|
|
|
|
|
|
|
|
|
# remove odd stuff
|
|
|
|
|
for i in list(cast.keys()): # Make a copy of the .keys() as Python 3 cannot handle iterating over
|
|
|
|
|
if cast[i] == "": # a dictionary that changes length with each iteration
|
|
|
|
|
for i in list(cast.keys()): # Make a copy of the .keys() as Python 3 cannot handle iterating over
|
|
|
|
|
if cast[i] == "": # a dictionary that changes length with each iteration
|
|
|
|
|
del cast[i]
|
|
|
|
|
# remove server stuff
|
|
|
|
|
if "muser" in cast.keys():
|
|
|
|
@ -259,11 +270,11 @@ class IRCBot(IRCClient):
|
|
|
|
|
if "channel" in cast.keys():
|
|
|
|
|
if cast["type"] == "mode":
|
|
|
|
|
if cast["channel"].lower() == self.nickname.lower():
|
|
|
|
|
#castDup = deepcopy(cast)
|
|
|
|
|
# castDup = deepcopy(cast)
|
|
|
|
|
cast["mtype"] = cast["type"]
|
|
|
|
|
cast["type"] = "self"
|
|
|
|
|
#self.event(**castDup)
|
|
|
|
|
if cast["modearg"]: # check if modearg is non-NoneType
|
|
|
|
|
# self.event(**castDup)
|
|
|
|
|
if cast["modearg"]: # check if modearg is non-NoneType
|
|
|
|
|
if self.nickname.lower() == cast["modearg"].lower():
|
|
|
|
|
castDup = deepcopy(cast)
|
|
|
|
|
castDup["mtype"] = cast["type"]
|
|
|
|
@ -273,7 +284,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
if cast["channel"].lower() == self.nickname.lower():
|
|
|
|
|
cast["mtype"] = cast["type"]
|
|
|
|
|
cast["type"] = "query"
|
|
|
|
|
#self.event(**castDup)
|
|
|
|
|
# self.event(**castDup)
|
|
|
|
|
# Don't call self.event for this one because queries are not events on a
|
|
|
|
|
# channel, but we still want to see them
|
|
|
|
|
|
|
|
|
@ -296,7 +307,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
castDup["type"] = "self"
|
|
|
|
|
|
|
|
|
|
# we have been mentioned in a msg/notice/action/part/quit/topic message
|
|
|
|
|
if "msg" in cast.keys(): # Don't highlight queries
|
|
|
|
|
if "msg" in cast.keys(): # Don't highlight queries
|
|
|
|
|
if not cast["msg"] == None:
|
|
|
|
|
if self.nickname.lower() in cast["msg"].lower():
|
|
|
|
|
castDup = deepcopy(cast)
|
|
|
|
@ -373,7 +384,16 @@ class IRCBot(IRCClient):
|
|
|
|
|
return
|
|
|
|
|
n = self._tempWho[channel][1]
|
|
|
|
|
n.append([nick, nick, host, server, status, realname])
|
|
|
|
|
self.event(type="who", nick=nick, ident=ident, host=host, realname=realname, channel=channel, server=server, status=status)
|
|
|
|
|
self.event(
|
|
|
|
|
type="who",
|
|
|
|
|
nick=nick,
|
|
|
|
|
ident=ident,
|
|
|
|
|
host=host,
|
|
|
|
|
realname=realname,
|
|
|
|
|
channel=channel,
|
|
|
|
|
server=server,
|
|
|
|
|
status=status,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def irc_RPL_ENDOFWHO(self, prefix, params):
|
|
|
|
|
channel = params[1]
|
|
|
|
@ -390,7 +410,10 @@ class IRCBot(IRCClient):
|
|
|
|
|
def sanit(self, data):
|
|
|
|
|
if len(data) >= 1:
|
|
|
|
|
if data[0] in self.prefix.keys():
|
|
|
|
|
return (self.prefix[data[0]], data[1:]) # would use a set but it's possible these are the same
|
|
|
|
|
return (
|
|
|
|
|
self.prefix[data[0]],
|
|
|
|
|
data[1:],
|
|
|
|
|
) # would use a set but it's possible these are the same
|
|
|
|
|
return (None, data)
|
|
|
|
|
else:
|
|
|
|
|
return (None, False)
|
|
|
|
@ -405,7 +428,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
|
|
|
|
|
def irc_RPL_NAMREPLY(self, prefix, params):
|
|
|
|
|
channel = params[2]
|
|
|
|
|
nicklist = params[3].split(' ')
|
|
|
|
|
nicklist = params[3].split(" ")
|
|
|
|
|
if channel not in self._tempNames:
|
|
|
|
|
return
|
|
|
|
|
n = self._tempNames[channel][1]
|
|
|
|
@ -438,7 +461,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
self._tempList[0].append(d)
|
|
|
|
|
if self.listSimple:
|
|
|
|
|
self.sendLine("LIST")
|
|
|
|
|
return d # return early if we know what to do
|
|
|
|
|
return d # return early if we know what to do
|
|
|
|
|
|
|
|
|
|
if noargs:
|
|
|
|
|
self.sendLine("LIST")
|
|
|
|
@ -460,8 +483,8 @@ class IRCBot(IRCClient):
|
|
|
|
|
return
|
|
|
|
|
else:
|
|
|
|
|
if nocheck:
|
|
|
|
|
allRelays = True # override the system - if this is
|
|
|
|
|
else: # specified, we already did this
|
|
|
|
|
allRelays = True # override the system - if this is
|
|
|
|
|
else: # specified, we already did this
|
|
|
|
|
allRelays = chankeep.allRelaysActive(self.net)
|
|
|
|
|
if not allRelays:
|
|
|
|
|
self.wantList = True
|
|
|
|
@ -481,7 +504,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
self._tempList[1].append([channel, users, topic])
|
|
|
|
|
|
|
|
|
|
def irc_RPL_LISTEND(self, prefix, params):
|
|
|
|
|
if not len(self._tempList[0]) > 0: # there are no callbacks, can't do anything there
|
|
|
|
|
if not len(self._tempList[0]) > 0: # there are no callbacks, can't do anything there
|
|
|
|
|
debug("We didn't ask for this LIST, discarding")
|
|
|
|
|
self._tempList[0].clear()
|
|
|
|
|
self._tempList[1].clear()
|
|
|
|
@ -510,18 +533,18 @@ class IRCBot(IRCClient):
|
|
|
|
|
self.listSimple = True
|
|
|
|
|
|
|
|
|
|
def got_list(self, listinfo):
|
|
|
|
|
if len(listinfo) == 0: # probably ngircd not supporting LIST >0
|
|
|
|
|
if len(listinfo) == 0: # probably ngircd not supporting LIST >0
|
|
|
|
|
return
|
|
|
|
|
chankeep.initialList(self.net, self.num, listinfo, self.chanlimit)
|
|
|
|
|
|
|
|
|
|
def recheckList(self):
|
|
|
|
|
allRelays = chankeep.allRelaysActive(self.net)
|
|
|
|
|
if allRelays:
|
|
|
|
|
name = self.net+"1"
|
|
|
|
|
name = self.net + "1"
|
|
|
|
|
if main.IRCPool[name].wantList == True:
|
|
|
|
|
main.IRCPool[name].list(nocheck=True)
|
|
|
|
|
debug("Asking for a list for %s after final relay %i connected" % (self.net, self.num))
|
|
|
|
|
if self.num == 1: # Only one instance should do a list
|
|
|
|
|
if self.num == 1: # Only one instance should do a list
|
|
|
|
|
if self.chanlimit:
|
|
|
|
|
if allRelays:
|
|
|
|
|
self.list()
|
|
|
|
@ -532,24 +555,26 @@ class IRCBot(IRCClient):
|
|
|
|
|
self.checkChannels()
|
|
|
|
|
|
|
|
|
|
def seed_chanlimit(self, chanlimit):
|
|
|
|
|
if not main.network[self.net].relays[self.num]["registered"]: #TODO: add check for register request sent, only send it once
|
|
|
|
|
if not main.network[self.net].relays[self.num][
|
|
|
|
|
"registered"
|
|
|
|
|
]: # TODO: add check for register request sent, only send it once
|
|
|
|
|
if main.config["AutoReg"]:
|
|
|
|
|
self._regAttempt = reactor.callLater(5, regproc.registerAccount, self.net, self.num)
|
|
|
|
|
#regproc.registerAccount(self.net, self.num)
|
|
|
|
|
# regproc.registerAccount(self.net, self.num)
|
|
|
|
|
try:
|
|
|
|
|
self.chanlimit = int(chanlimit)
|
|
|
|
|
except TypeError:
|
|
|
|
|
warn("Invalid chanlimit: %s" % i)
|
|
|
|
|
if self.chanlimit == 0:
|
|
|
|
|
self.chanlimit = 200 # don't take the piss if it's not limited
|
|
|
|
|
if not regproc.needToRegister(self.net): # if we need to register, only recheck on auth confirmation
|
|
|
|
|
self.chanlimit = 200 # don't take the piss if it's not limited
|
|
|
|
|
if not regproc.needToRegister(self.net): # if we need to register, only recheck on auth confirmation
|
|
|
|
|
self.recheckList()
|
|
|
|
|
|
|
|
|
|
def seed_prefix(self, prefix):
|
|
|
|
|
prefix = prefix.replace(")", "")
|
|
|
|
|
prefix = prefix.replace("(", "")
|
|
|
|
|
length = len(prefix)
|
|
|
|
|
half = int(length/2)
|
|
|
|
|
half = int(length / 2)
|
|
|
|
|
prefixToMode = dict(zip(prefix[half:], prefix[:half]))
|
|
|
|
|
self.prefix = prefixToMode
|
|
|
|
|
|
|
|
|
@ -585,7 +610,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
# the hostname and other useful information in the functions
|
|
|
|
|
# that these call by default
|
|
|
|
|
def irc_JOIN(self, prefix, params):
|
|
|
|
|
nick = prefix.split('!')[0]
|
|
|
|
|
nick = prefix.split("!")[0]
|
|
|
|
|
channel = params[-1]
|
|
|
|
|
if nick == self.nickname:
|
|
|
|
|
self.joined(channel)
|
|
|
|
@ -593,7 +618,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
self.userJoined(prefix, channel)
|
|
|
|
|
|
|
|
|
|
def irc_PART(self, prefix, params):
|
|
|
|
|
nick = prefix.split('!')[0]
|
|
|
|
|
nick = prefix.split("!")[0]
|
|
|
|
|
channel = params[0]
|
|
|
|
|
if len(params) >= 2:
|
|
|
|
|
message = params[1]
|
|
|
|
@ -605,11 +630,11 @@ class IRCBot(IRCClient):
|
|
|
|
|
self.userLeft(prefix, channel, message)
|
|
|
|
|
|
|
|
|
|
def irc_QUIT(self, prefix, params):
|
|
|
|
|
nick = prefix.split('!')[0]
|
|
|
|
|
nick = prefix.split("!")[0]
|
|
|
|
|
self.userQuit(prefix, params[0])
|
|
|
|
|
|
|
|
|
|
def irc_NICK(self, prefix, params):
|
|
|
|
|
nick = prefix.split('!', 1)[0]
|
|
|
|
|
nick = prefix.split("!", 1)[0]
|
|
|
|
|
if nick == self.nickname:
|
|
|
|
|
self.nickChanged(prefix, params[0])
|
|
|
|
|
else:
|
|
|
|
@ -626,6 +651,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
channel = params[0]
|
|
|
|
|
newtopic = params[1]
|
|
|
|
|
self.topicUpdated(prefix, channel, newtopic)
|
|
|
|
|
|
|
|
|
|
# End of Twisted hackery
|
|
|
|
|
|
|
|
|
|
def regPing(self, negativepass=None):
|
|
|
|
@ -664,7 +690,15 @@ class IRCBot(IRCClient):
|
|
|
|
|
def signedOn(self):
|
|
|
|
|
log("signed on: %s - %i" % (self.net, self.num))
|
|
|
|
|
ctime = str(datetime.now().isoformat())
|
|
|
|
|
sendRelayNotification({"type": "conn", "net": self.net, "num": self.num, "status": "signedon", "time": ctime})
|
|
|
|
|
sendRelayNotification(
|
|
|
|
|
{
|
|
|
|
|
"type": "conn",
|
|
|
|
|
"net": self.net,
|
|
|
|
|
"num": self.num,
|
|
|
|
|
"status": "signedon",
|
|
|
|
|
"time": ctime,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
if not self.authenticated:
|
|
|
|
|
reactor.callLater(10, self.regPing)
|
|
|
|
|
|
|
|
|
@ -677,7 +711,7 @@ class IRCBot(IRCClient):
|
|
|
|
|
self._getWho[channel] = lc
|
|
|
|
|
intrange = main.config["Tweaks"]["Delays"]["WhoRange"]
|
|
|
|
|
minint = main.config["Tweaks"]["Delays"]["WhoLoop"]
|
|
|
|
|
interval = randint(minint, minint+intrange)
|
|
|
|
|
interval = randint(minint, minint + intrange)
|
|
|
|
|
lc.start(interval)
|
|
|
|
|
|
|
|
|
|
def botLeft(self, channel):
|
|
|
|
@ -687,10 +721,11 @@ class IRCBot(IRCClient):
|
|
|
|
|
lc = self._getWho[channel]
|
|
|
|
|
lc.stop()
|
|
|
|
|
del self._getWho[channel]
|
|
|
|
|
userinfo.delChannels(self.net, [channel]) # < we do not need to deduplicate this
|
|
|
|
|
#log("Can no longer cover %s, removing records" % channel)# as it will only be matched once --
|
|
|
|
|
# other bots have different nicknames so
|
|
|
|
|
def left(self, user, channel, message): # even if they saw it, they wouldn't react
|
|
|
|
|
userinfo.delChannels(self.net, [channel]) # < we do not need to deduplicate this
|
|
|
|
|
# log("Can no longer cover %s, removing records" % channel)# as it will only be matched once --
|
|
|
|
|
# other bots have different nicknames so
|
|
|
|
|
|
|
|
|
|
def left(self, user, channel, message): # even if they saw it, they wouldn't react
|
|
|
|
|
self.event(type="part", muser=user, channel=channel, msg=message)
|
|
|
|
|
self.botLeft(channel)
|
|
|
|
|
|
|
|
|
@ -711,14 +746,14 @@ class IRCBot(IRCClient):
|
|
|
|
|
def chanlessEvent(self, cast):
|
|
|
|
|
cast["time"] = str(datetime.now().isoformat())
|
|
|
|
|
cast["nick"], cast["ident"], cast["host"] = parsen(cast["muser"])
|
|
|
|
|
if dedup(self.name, cast): # Needs to be kept self.name until the dedup
|
|
|
|
|
# function is converted to the new net, num
|
|
|
|
|
# format
|
|
|
|
|
return # stop right there sir!
|
|
|
|
|
if dedup(self.name, cast): # Needs to be kept self.name until the dedup
|
|
|
|
|
# function is converted to the new net, num
|
|
|
|
|
# format
|
|
|
|
|
return # stop right there sir!
|
|
|
|
|
chans = userinfo.getChanList(self.net, cast["nick"])
|
|
|
|
|
if chans == None:
|
|
|
|
|
error("No channels returned for chanless event: %s" % cast)
|
|
|
|
|
# self.event(**cast) -- no, should NEVER happen
|
|
|
|
|
# self.event(**cast) -- no, should NEVER happen
|
|
|
|
|
return
|
|
|
|
|
# getChansSingle returns all channels of the user, we only want to use
|
|
|
|
|
# ones we have common with them
|
|
|
|
@ -737,7 +772,15 @@ class IRCBot(IRCClient):
|
|
|
|
|
argList = list(args)
|
|
|
|
|
modeList = [i for i in modes]
|
|
|
|
|
for a, m in zip(argList, modeList):
|
|
|
|
|
self.event(type="mode", muser=user, channel=channel, mode=m, status=toset, modearg=a)
|
|
|
|
|
self.event(
|
|
|
|
|
type="mode",
|
|
|
|
|
muser=user,
|
|
|
|
|
channel=channel,
|
|
|
|
|
mode=m,
|
|
|
|
|
status=toset,
|
|
|
|
|
modearg=a,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IRCBotFactory(ReconnectingClientFactory):
|
|
|
|
|
def __init__(self, net, num=None, relayCommands=None, user=None, stage2=None):
|
|
|
|
@ -747,7 +790,7 @@ class IRCBotFactory(ReconnectingClientFactory):
|
|
|
|
|
self.name = "relay - %i" % num
|
|
|
|
|
self.relay = True
|
|
|
|
|
else:
|
|
|
|
|
self.name = net+str(num)
|
|
|
|
|
self.name = net + str(num)
|
|
|
|
|
self.num = num
|
|
|
|
|
self.net = net
|
|
|
|
|
self.relay = False
|
|
|
|
@ -781,9 +824,18 @@ class IRCBotFactory(ReconnectingClientFactory):
|
|
|
|
|
log("%s - %i: connection lost: %s" % (self.net, self.num, error))
|
|
|
|
|
sendAll("%s - %i: connection lost: %s" % (self.net, self.num, error))
|
|
|
|
|
ctime = str(datetime.now().isoformat())
|
|
|
|
|
sendRelayNotification({"type": "conn", "net": self.net, "num": self.num, "status": "lost", "message": error, "time": ctime})
|
|
|
|
|
sendRelayNotification(
|
|
|
|
|
{
|
|
|
|
|
"type": "conn",
|
|
|
|
|
"net": self.net,
|
|
|
|
|
"num": self.num,
|
|
|
|
|
"status": "lost",
|
|
|
|
|
"message": error,
|
|
|
|
|
"time": ctime,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
self.retry(connector)
|
|
|
|
|
#ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
|
|
|
|
|
# ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
|
|
|
|
|
|
|
|
|
|
def clientConnectionFailed(self, connector, reason):
|
|
|
|
|
if not self.client == None:
|
|
|
|
@ -795,7 +847,15 @@ class IRCBotFactory(ReconnectingClientFactory):
|
|
|
|
|
if not self.relay:
|
|
|
|
|
sendAll("%s - %s: connection failed: %s" % (self.net, self.num, error))
|
|
|
|
|
ctime = str(datetime.now().isoformat())
|
|
|
|
|
sendRelayNotification({"type": "conn", "net": self.net, "num": self.num, "status": "failed", "message": error, "time": ctime})
|
|
|
|
|
sendRelayNotification(
|
|
|
|
|
{
|
|
|
|
|
"type": "conn",
|
|
|
|
|
"net": self.net,
|
|
|
|
|
"num": self.num,
|
|
|
|
|
"status": "failed",
|
|
|
|
|
"message": error,
|
|
|
|
|
"time": ctime,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
self.retry(connector)
|
|
|
|
|
#ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
|
|
|
|
|
|
|
|
|
|
# ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
|
|
|
|
|