3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-27 21:19:31 +01:00

TS6: Initial support for elemental-ircd

The TS6 protocol gets some new options here: use_halfop, use_admin, use_owner, and use_elemental_modes, to deal with features
supported in Elemental but not charybdis. A second server block is added in the example config to document this.
This commit is contained in:
James Lu 2015-08-03 23:20:19 -07:00
parent d533ce3d28
commit 4d76593901
2 changed files with 104 additions and 46 deletions

View File

@ -33,6 +33,9 @@ servers:
# Autojoin channels # Autojoin channels
channels: ["#pylink"] channels: ["#pylink"]
# Sets the protocol module to use - see the protocols/ folder for a list of valid values
# (omitting the .py extension).
protocol: "inspircd" protocol: "inspircd"
# Sets autoconnect delay - comment this out or set the value negative to disable autoconnect entirely. # Sets autoconnect delay - comment this out or set the value negative to disable autoconnect entirely.
@ -40,6 +43,7 @@ servers:
# Sets ping frequency (i.e. how long we should wait between sending pings to our uplink). # Sets ping frequency (i.e. how long we should wait between sending pings to our uplink).
# When more than two consecutive pings are missed, PyLink will disconnect with a ping timeout. # When more than two consecutive pings are missed, PyLink will disconnect with a ping timeout.
# Defaults to 30 if not set.
pingfreq: 30 pingfreq: 30
# Separator character (used by relay) # Separator character (used by relay)
@ -49,6 +53,39 @@ servers:
# PyLink might introduce a nick that is too long and cause netsplits! # PyLink might introduce a nick that is too long and cause netsplits!
maxnicklen: 30 maxnicklen: 30
ts6net:
ip: 127.0.0.1
port: 7000
recvpass: "abcd"
sendpass: "abcd"
hostname: "pylink.example.com"
sid: "8PY"
# Leave this as an empty list if you don't want to join any channels.
channels: []
protocol: "ts6"
autoconnect: 5
pingfreq: 30
maxnicklen: 30
# /'s in nicks are automatically converted to |'s for TS6 networks, since they
# don't allow "/" in nicks
separator: "|"
# The following options are specific to TS6 servers:
# Toggles owner (+y), admin (+a), and halfop (+h) support for shadowircd/elemental-ircd.
# This defaults to off for the best compatibility.
use_owner: false
use_admin: false
use_halfop: false
# Toggles support of shadowircd/elemental-ircd specific channel modes:
# +T (no notice), +u (hidden ban list), +E (no kicks), +J (blocks kickrejoin),
# +K (no repeat messages), +d (no nick changes), and user modes:
# +B (bot), +C (blocks CTCP), +D (deaf), +V (no invites), +I (hides channel list)
use_elemental_modes: false
# Plugins to load (omit the .py extension) # Plugins to load (omit the .py extension)
plugins: plugins:
- commands - commands

View File

@ -97,8 +97,6 @@ def sjoinServer(irc, server, channel, users, ts=None):
prefixchars += pr prefixchars += pr
namelist.append(prefixchars+user) namelist.append(prefixchars+user)
uids.append(user) uids.append(user)
for m in prefixes:
changedmodes.append(('+%s' % m, user))
try: try:
irc.users[user].channels.add(channel) irc.users[user].channels.add(channel)
except KeyError: # Not initialized yet? except KeyError: # Not initialized yet?
@ -237,6 +235,69 @@ def connect(irc):
ts = irc.start_ts ts = irc.start_ts
f = irc.send f = irc.send
# Valid keywords (from mostly InspIRCd's named modes):
# admin allowinvite autoop ban banexception blockcolor
# c_registered exemptchanops filter forward flood halfop history invex
# inviteonly joinflood key kicknorejoin limit moderated nickflood
# noctcp noextmsg nokick noknock nonick nonotice official-join op
# operonly opmoderated owner permanent private redirect regonly
# regmoderated secret sslonly stripcolor topiclock voice
# https://github.com/grawity/irc-docs/blob/master/server/ts6.txt#L80
chary_cmodes = { # TS6 generic modes:
# Note: charybdis +p has the effect of being both
# noknock AND private. Surprisingly, mapping it twice
# works pretty well: setting +p on a charybdis relay
# server sets +pK on an InspIRCd network.
'op': 'o', 'voice': 'v', 'ban': 'b', 'key': 'k', 'limit':
'l', 'moderated': 'm', 'noextmsg': 'n', 'noknock': 'p',
'secret': 's', 'topiclock': 't',
# charybdis-specific modes:
'quiet': 'q', 'redirect': 'f', 'freetarget': 'F',
'joinflood': 'j', 'largebanlist': 'L', 'permanent': 'P',
'c_noforwards': 'Q', 'stripcolor': 'c', 'allowinvite':
'g', 'opmoderated': 'z', 'noctcp': 'C',
# charybdis-specific modes provided by EXTENSIONS
'operonly': 'O', 'adminonly': 'A', 'sslonly': 'S',
# Now, map all the ABCD type modes:
'*A': 'beIq', '*B': 'k', '*C': 'l', '*D': 'mnprst'}
if irc.serverdata.get('use_owner'):
chary_cmodes['owner'] = 'y'
irc.prefixmodes['y'] = '~'
if irc.serverdata.get('use_admin'):
chary_cmodes['admin'] = 'a'
irc.prefixmodes['a'] = '!'
if irc.serverdata.get('use_halfop'):
chary_cmodes['halfop'] = 'h'
irc.prefixmodes['h'] = '%'
irc.cmodes.update(chary_cmodes)
# Same thing with umodes:
# bot callerid cloak deaf_commonchan helpop hidechans hideoper invisible oper regdeaf servprotect showwhois snomask u_registered u_stripcolor wallops
chary_umodes = {'deaf': 'D', 'servprotect': 'S', 'u_admin': 'a',
'invisible': 'i', 'oper': 'o', 'wallops': 'w',
'snomask': 's', 'u_noforward': 'Q', 'regdeaf': 'R',
'callerid': 'g', 'chary_operwall': 'z', 'chary_locops':
'l',
# Now, map all the ABCD type modes:
'*A': '', '*B': '', '*C': '', '*D': 'DSaiowsQRgzl'}
irc.umodes.update(chary_umodes)
# Toggles support of shadowircd/elemental-ircd specific channel modes:
# +T (no notice), +u (hidden ban list), +E (no kicks), +J (blocks kickrejoin),
# +K (no repeat messages), +d (no nick changes), and user modes:
# +B (bot), +C (blocks CTCP), +D (deaf), +V (no invites), +I (hides channel list)
if irc.serverdata.get('use_elemental_modes'):
elemental_cmodes = {'nonotice': 'T', 'hiddenbans': 'u', 'nokick': 'E',
'kicknorejoin': 'J', 'repeat': 'K', 'nonick': 'd'}
irc.cmodes.update(elemental_cmodes)
irc.cmodes['*D'] += ''.join(elemental_cmodes.values())
elemental_umodes = {'u_noctcp': 'C', 'deaf': 'D', 'bot': 'B', 'u_noinvite': 'V',
'hidechans': 'I'}
irc.umodes.update(elemental_umodes)
irc.umodes['*D'] += ''.join(elemental_umodes.values())
# https://github.com/grawity/irc-docs/blob/master/server/ts6.txt#L55 # https://github.com/grawity/irc-docs/blob/master/server/ts6.txt#L55
f('PASS %s TS 6 %s' % (irc.serverdata["sendpass"], irc.sid)) f('PASS %s TS 6 %s' % (irc.serverdata["sendpass"], irc.sid))
@ -318,7 +379,7 @@ def handle_sjoin(irc, servernumeric, command, args):
log.debug('(%s) handle_sjoin: got userlist %r for %r', irc.name, userlist, channel) log.debug('(%s) handle_sjoin: got userlist %r for %r', irc.name, userlist, channel)
for userpair in userlist: for userpair in userlist:
# charybdis sends this in the form "@+UID1, +UID2, UID3, @UID4" # charybdis sends this in the form "@+UID1, +UID2, UID3, @UID4"
r = re.search(r'([%s]*)(.*)' % ''.join(irc.prefixmodes.values()), userpair) r = re.search(r'([^\d]*)(.*)', userpair)
user = r.group(2) user = r.group(2)
modeprefix = r.group(1) or '' modeprefix = r.group(1) or ''
finalprefix = '' finalprefix = ''
@ -455,53 +516,13 @@ def handle_events(irc, data):
if required_cap not in caps: if required_cap not in caps:
raise ProtocolError('%s not found in TS6 capabilities list; this is required! (got %r)' % (required_cap, caps)) raise ProtocolError('%s not found in TS6 capabilities list; this is required! (got %r)' % (required_cap, caps))
# Valid keywords (from mostly InspIRCd's named modes):
# admin allowinvite autoop ban banexception blockcolor
# c_registered exemptchanops filter forward flood halfop history invex
# inviteonly joinflood key kicknorejoin limit moderated nickflood
# noctcp noextmsg nokick noknock nonick nonotice official-join op
# operonly opmoderated owner permanent private redirect regonly
# regmoderated secret sslonly stripcolor topiclock voice
# https://github.com/grawity/irc-docs/blob/master/server/ts6.txt#L80
chary_cmodes = { # TS6 generic modes:
# Note: charybdis +p has the effect of being both
# noknock AND private. Surprisingly, mapping it twice
# works pretty well: setting +p on a charybdis relay
# server sets +pK on an InspIRCd network.
'op': 'o', 'voice': 'v', 'ban': 'b', 'key': 'k', 'limit':
'l', 'moderated': 'm', 'noextmsg': 'n', 'noknock': 'p',
'secret': 's', 'topiclock': 't',
# charybdis-specific modes:
'quiet': 'q', 'redirect': 'f', 'freetarget': 'F',
'joinflood': 'j', 'largebanlist': 'L', 'permanent': 'P',
'c_noforwards': 'Q', 'stripcolor': 'c', 'allowinvite':
'g', 'opmoderated': 'z', 'noctcp': 'C',
# charybdis-specific modes provided by EXTENSIONS
'operonly': 'O', 'adminonly': 'A', 'sslonly': 'S',
# Now, map all the ABCD type modes:
'*A': 'beI', '*B': 'k', '*C': 'l', '*D': 'mnprst'}
if 'EX' in caps: if 'EX' in caps:
chary_cmodes['banexception'] = 'e' irc.cmodes['banexception'] = 'e'
if 'IE' in caps: if 'IE' in caps:
chary_cmodes['invex'] = 'I' irc.cmodes['invex'] = 'I'
if 'SERVICES' in caps: if 'SERVICES' in caps:
chary_cmodes['regonly'] = 'r' irc.cmodes['regonly'] = 'r'
irc.cmodes.update(chary_cmodes)
# Same thing with umodes:
# bot callerid cloak deaf_commonchan helpop hidechans hideoper invisible oper regdeaf servprotect showwhois snomask u_registered u_stripcolor wallops
chary_umodes = {'deaf': 'D', 'servprotect': 'S', 'u_admin': 'a',
'invisible': 'i', 'oper': 'o', 'wallops': 'w',
'snomask': 's', 'u_noforward': 'Q', 'regdeaf': 'R',
'callerid': 'g', 'chary_operwall': 'z', 'chary_locops':
'l',
# Now, map all the ABCD type modes:
'*A': '', '*B': '', '*C': '', '*D': 'DSAiowQRglszZ'}
irc.umodes.update(chary_umodes)
# TODO: support module-created modes like +O, +S, etc.
# Does charybdis propagate these? If so, how?
log.debug('(%s) irc.connected set!', irc.name) log.debug('(%s) irc.connected set!', irc.name)
irc.connected.set() irc.connected.set()