mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-01 01:09:22 +01:00
Merge branch 'devel' into wip/unrealircd
This commit is contained in:
commit
07fce69c5e
@ -1,6 +1,6 @@
|
||||
# PyLink
|
||||
|
||||
PyLink is an extensible, plugin-based IRC Services framework written in Python. It aims to be a replacement for the now-defunct Janus.
|
||||
PyLink is an extensible, plugin-based IRC Services framework written in Python. It aims to be 1) a replacement for the now-defunct Janus 2) a versatile framework and gateway to IRC.
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -32,6 +32,10 @@ relay_started = True
|
||||
|
||||
def initializeAll(irc):
|
||||
"""Initializes all relay channels for the given IRC object."""
|
||||
# Wait for all IRC objects to initialize first. This prevents
|
||||
# relay servers from being spawned too early (before server authentication),
|
||||
# which would break connections.
|
||||
world.started.wait(2)
|
||||
for chanpair, entrydata in db.items():
|
||||
network, channel = chanpair
|
||||
initializeChannel(irc, channel)
|
||||
@ -164,6 +168,8 @@ def getPrefixModes(irc, remoteirc, channel, user, mlist=None):
|
||||
def getRemoteSid(irc, remoteirc):
|
||||
"""Gets the remote server SID representing remoteirc on irc, spawning
|
||||
it if it doesn't exist."""
|
||||
# Don't spawn servers too early.
|
||||
irc.connected.wait(2)
|
||||
try:
|
||||
spawnservers = irc.conf['relay']['spawn_servers']
|
||||
except KeyError:
|
||||
@ -183,6 +189,7 @@ def getRemoteSid(irc, remoteirc):
|
||||
log.exception('(%s) Failed to spawn server for %r:',
|
||||
irc.name, remoteirc.name)
|
||||
irc.aborted.set()
|
||||
return
|
||||
else:
|
||||
irc.servers[sid].remote = remoteirc.name
|
||||
relayservers[irc.name][remoteirc.name] = sid
|
||||
@ -996,6 +1003,9 @@ def handle_endburst(irc, numeric, command, args):
|
||||
utils.add_hook(handle_endburst, "ENDBURST")
|
||||
|
||||
def handle_disconnect(irc, numeric, command, args):
|
||||
"""Handles IRC network disconnections (internal hook)."""
|
||||
# Quit all of our users' representations on other nets, and remove
|
||||
# them from our relay clients index.
|
||||
for k, v in relayusers.copy().items():
|
||||
if irc.name in v:
|
||||
del relayusers[k][irc.name]
|
||||
@ -1005,11 +1015,15 @@ def handle_disconnect(irc, numeric, command, args):
|
||||
del relayusers[k]
|
||||
except KeyError:
|
||||
pass
|
||||
for name, ircobj in world.networkobjects.items():
|
||||
if name != irc.name:
|
||||
rsid = getRemoteSid(ircobj, irc)
|
||||
# Let's be super extra careful here...
|
||||
if rsid and name in relayservers and irc.name in relayservers[name]:
|
||||
# SQUIT all relay pseudoservers spawned for us, and remove them
|
||||
# from our relay subservers index.
|
||||
for name, ircobj in world.networkobjects.copy().items():
|
||||
if name != irc.name and ircobj.connected.is_set():
|
||||
try:
|
||||
rsid = relayservers[ircobj.name][irc.name]
|
||||
except KeyError:
|
||||
continue
|
||||
else:
|
||||
ircobj.proto.squitServer(ircobj.sid, rsid, text='Home network lost connection.')
|
||||
del relayservers[name][irc.name]
|
||||
try:
|
||||
|
@ -288,7 +288,7 @@ class TS6Protocol(TS6BaseProtocol):
|
||||
def squitServer(self, source, target, text='No reason given'):
|
||||
"""SQUITs a PyLink server."""
|
||||
# -> SQUIT 9PZ :blah, blah
|
||||
self.irc.send('SQUIT %s :%s' % (target, text))
|
||||
self._send(source, 'SQUIT %s :%s' % (target, text))
|
||||
self.handle_squit(source, 'SQUIT', [target, text])
|
||||
|
||||
def connect(self):
|
||||
@ -588,22 +588,23 @@ class TS6Protocol(TS6BaseProtocol):
|
||||
raise ProtocolError("Servers should use EUID instead of UID to send users! "
|
||||
"This IS a required capability after all...")
|
||||
|
||||
def handle_server(self, numeric, command, args):
|
||||
"""Handles incoming SERVER introductions."""
|
||||
def handle_sid(self, numeric, command, args):
|
||||
"""Handles incoming server introductions."""
|
||||
# parameters: server name, hopcount, sid, server description
|
||||
servername = args[0].lower()
|
||||
try:
|
||||
sid = args[2]
|
||||
except IndexError:
|
||||
# It is allowed to send JUPEd servers that exist without a SID.
|
||||
# That's not very fun to handle, though.
|
||||
# XXX: don't just save these by their server names; that's ugly!
|
||||
sid = servername
|
||||
sid = args[2]
|
||||
sdesc = args[-1]
|
||||
self.irc.servers[sid] = IrcServer(numeric, servername, desc=sdesc)
|
||||
return {'name': servername, 'sid': sid, 'text': sdesc}
|
||||
|
||||
handle_sid = handle_server
|
||||
def handle_server(self, sender, command, args):
|
||||
"""Handles incoming legacy (no SID) server introductions."""
|
||||
# <- :services.int SERVER a.bc 2 :(H) [GL] a
|
||||
numeric = self._getSid(sender) # Convert the server name prefix to a SID.
|
||||
servername = args[0].lower()
|
||||
sdesc = args[-1]
|
||||
self.irc.servers[servername] = IrcServer(numeric, servername, desc=sdesc)
|
||||
return {'name': servername, 'sid': None, 'text': sdesc}
|
||||
|
||||
def handle_tmode(self, numeric, command, args):
|
||||
"""Handles incoming TMODE commands (channel mode change)."""
|
||||
|
@ -19,6 +19,13 @@ class TS6BaseProtocol(Protocol):
|
||||
args[0] = args[0].split(':', 1)[1]
|
||||
return args
|
||||
|
||||
def _getSid(self, sname):
|
||||
"""Returns the SID of a server with the given name, if present."""
|
||||
nick = sname.lower()
|
||||
for k, v in self.irc.servers.items():
|
||||
if v.name.lower() == nick:
|
||||
return k
|
||||
|
||||
### OUTGOING COMMANDS
|
||||
|
||||
def _sendKick(self, numeric, channel, target, reason=None):
|
||||
@ -162,8 +169,10 @@ class TS6BaseProtocol(Protocol):
|
||||
# :70M SQUIT 1ML :Server quit by GL!gl@0::1
|
||||
split_server = args[0]
|
||||
affected_users = []
|
||||
log.info('(%s) Netsplit on server %s', self.irc.name, split_server)
|
||||
assert split_server in self.irc.servers, "Tried to split a server (%s) that didn't exist!" % split_server
|
||||
log.debug('(%s) Splitting server %s (reason: %s)', self.irc.name, split_server, args[-1])
|
||||
if split_server not in self.irc.servers:
|
||||
log.warning("(%s) Tried to split a server (%s) that didn't exist!", self.irc.name, split_server)
|
||||
return
|
||||
# Prevent RuntimeError: dictionary changed size during iteration
|
||||
old_servers = self.irc.servers.copy()
|
||||
for sid, data in old_servers.items():
|
||||
|
Loading…
Reference in New Issue
Block a user