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:
parent
d533ce3d28
commit
4d76593901
@ -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
|
||||||
|
113
protocols/ts6.py
113
protocols/ts6.py
@ -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()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user