diff --git a/classes.py b/classes.py index 60963b0..b3b4d54 100644 --- a/classes.py +++ b/classes.py @@ -1,4 +1,6 @@ from collections import defaultdict +import threading +from random import randint from log import log import main @@ -90,6 +92,10 @@ class FakeIRC(main.Irc): self.hookargs = [] self.hookmsgs = [] self.socket = None + self.initVars() + self.spawnMain() + self.connected = threading.Event() + self.connected.set() def run(self, data): """Queues a message to the fake IRC server.""" @@ -140,3 +146,15 @@ class FakeProto(): @staticmethod def connect(irc): pass + + @staticmethod + def spawnClient(irc, nick, *args, **kwargs): + uid = randint(1, 10000000000) + ts = int(time.time()) + irc.users[uid] = user = IrcUser(nick, ts, uid) + return user + + @staticmethod + def joinClient(irc, client, channel): + irc.channels[channel].users.add(client) + irc.users[client].channels.add(channel) diff --git a/main.py b/main.py index 4b2d7f2..568764b 100755 --- a/main.py +++ b/main.py @@ -19,7 +19,7 @@ class Irc(): def initVars(self): # Server, channel, and user indexes to be populated by our protocol module - self.servers = {} + self.servers = {self.sid: classes.IrcServer(None, self.serverdata['hostname'], internal=True)} self.users = {} self.channels = defaultdict(classes.IrcChannel) # Sets flags such as whether to use halfops, etc. The default RFC1459 @@ -36,6 +36,7 @@ class Irc(): self.umodes = {'invisible': 'i', 'snomask': 's', 'wallops': 'w', 'oper': 'o', '*A': '', '*B': '', '*C': 's', '*D': 'iow'} + # This nicklen value is only a default, and SHOULD be set by the # protocol module as soon as the relevant capability information is # received from the uplink. Plugins that depend on maxnicklen being @@ -44,17 +45,19 @@ class Irc(): # is also dependent on the protocol module. self.maxnicklen = 30 self.prefixmodes = 'ov' + # Uplink SID (filled in by protocol module) self.uplink = None + self.start_ts = int(time.time()) + + # UID generators, for servers that need it + self.uidgen = {} def __init__(self, netname, proto, conf): # Initialize some variables self.connected = threading.Event() self.name = netname.lower() self.conf = conf - - self.initVars() - self.serverdata = conf['servers'][netname] self.sid = self.serverdata["sid"] self.botdata = conf['bot'] @@ -62,6 +65,8 @@ class Irc(): self.pingfreq = self.serverdata.get('pingfreq') or 10 self.pingtimeout = self.pingfreq * 2 + self.initVars() + self.connection_thread = threading.Thread(target = self.connect) self.connection_thread.start() self.pingTimer = None diff --git a/protocols/inspircd.py b/protocols/inspircd.py index d571537..95d7a91 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -291,16 +291,14 @@ def pingServer(irc, source=None, target=None): _send(irc, source, 'PING %s %s' % (source, target)) def connect(irc): - irc.start_ts = ts = int(time.time()) + ts = irc.start_ts irc.uidgen = {} - host = irc.serverdata["hostname"] - irc.servers[irc.sid] = IrcServer(None, host, internal=True) f = irc.send f('CAPAB START 1202') f('CAPAB CAPABILITIES :PROTOCOL=1202') f('CAPAB END') - f('SERVER {host} {Pass} 0 {sid} :PyLink Service'.format(host=host, + f('SERVER {host} {Pass} 0 {sid} :PyLink Service'.format(host=irc.serverdata["hostname"], Pass=irc.serverdata["sendpass"], sid=irc.sid)) f(':%s BURST %s' % (irc.sid, ts)) f(':%s ENDBURST' % (irc.sid)) diff --git a/tests/test_proto_inspircd.py b/tests/test_proto_inspircd.py index 5f9eb6c..931351a 100644 --- a/tests/test_proto_inspircd.py +++ b/tests/test_proto_inspircd.py @@ -8,6 +8,7 @@ from collections import defaultdict import inspircd import classes import utils +import coreplugin class TestProtoInspIRCd(unittest.TestCase): def setUp(self): diff --git a/tests/test_relay.py b/tests/test_relay.py index 5e6ae4b..07240b0 100644 --- a/tests/test_relay.py +++ b/tests/test_relay.py @@ -19,21 +19,22 @@ class TestRelay(unittest.TestCase): self.f = relay.normalizeNick def testNormalizeNick(self): - self.assertEqual(self.f(self.irc, 'helloworld'), 'helloworld/unittest') - self.assertEqual(self.f(self.irc, 'ObnoxiouslyLongNick'), 'Obnoxiously/unittest') - self.assertEqual(self.f(self.irc, '10XAAAAAA'), '_10XAAAAAA/unittest') + # Second argument simply states the suffix. + self.assertEqual(self.f(self.irc, 'unittest', 'helloworld'), 'helloworld/unittest') + self.assertEqual(self.f(self.irc, 'unittest', 'ObnoxiouslyLongNick'), 'Obnoxiously/unittest') + self.assertEqual(self.f(self.irc, 'unittest', '10XAAAAAA'), '_10XAAAAAA/unittest') def testNormalizeNickConflict(self): - self.assertEqual(self.f(self.irc, 'helloworld'), 'helloworld/unittest') + self.assertEqual(self.f(self.irc, 'unittest', 'helloworld'), 'helloworld/unittest') self.irc.users['10XAAAAAA'] = classes.IrcUser('helloworld/unittest', 1234, '10XAAAAAA') # Increase amount of /'s by one - self.assertEqual(self.f(self.irc, 'helloworld'), 'helloworld//unittest') + self.assertEqual(self.f(self.irc, 'unittest', 'helloworld'), 'helloworld//unittest') self.irc.users['10XAAAAAB'] = classes.IrcUser('helloworld//unittest', 1234, '10XAAAAAB') # Cut off the nick, not the suffix if the result is too long. - self.assertEqual(self.f(self.irc, 'helloworld'), 'helloworl///unittest') + self.assertEqual(self.f(self.irc, 'unittest', 'helloworld'), 'helloworl///unittest') def testNormalizeNickRemovesSlashes(self): self.irc.proto.__name__ = "charybdis" - self.assertEqual(self.f(self.irc, 'helloworld'), 'helloworld|unittest') - self.assertEqual(self.f(self.irc, 'abcde/eJanus'), 'abcde|eJanu|unittest') - self.assertEqual(self.f(self.irc, 'ObnoxiouslyLongNick'), 'Obnoxiously|unittest') + self.assertEqual(self.f(self.irc, 'unittest', 'helloworld'), 'helloworld|unittest') + self.assertEqual(self.f(self.irc, 'unittest', 'abcde/eJanus'), 'abcde|eJanu|unittest') + self.assertEqual(self.f(self.irc, 'unittest', 'ObnoxiouslyLongNick'), 'Obnoxiously|unittest')