This is an issue to keep track of design decisions/open question/postponed tasks for arbitrary mode support in Eggdrop. The parsing was done in #1872 and now allows us to write actual supporting code.
Goals
- pushmode/add_mode() should be able to send all valid modes with an optional argument
- all modes are tracked internally properly according to 005 isupport info (e.g.
PREFIX=(qaohv)~&@%+ CHANMODE=eIbq,k,flj,ACFHLMOPQTcgimnprstz).
- The mode types are:
list-type modes (ebIq, ban-type masks as parameter)
key-type modes (k, parameter on set/unset)
limit-type modes (flj, parameter on set only)
flag-type modes (imnprst.., no parameter)
prefix-type modes (qaohv, set on nicknames with a corresponding non-alphanumeric prefix char)
- module API stays compatible through accessor functions that set legacy struct fields (e.g.
set_mode(chan, 'l', "12") also sets chan->maxmembers=12)
- bind mode triggers for all valid mode changes
- new generic list-mode tracking, +beI could be folded into it later, but that's not a goal of this step
- channel mode and prefix mode tracking is however going to be unified
Implementation details
chan_t.modeflags is a new uint64_t bitfield to track a-zA-Z0-9 (62 bits), compressing it would be of little benefit
chan_t.modeargs is a new char *[62] storing the argument for a-zA-Z0-9 if needed (wastes space for non-flag modes)
chan_t.modelists is a new struct field to track new list modes (q)
opchars is removed from the code with a deprecation warning if it is being set in the config, it never worked right to begin with
- the outgoing mode queue in
chanset_t.cmode is changed to instead have a list of modes and their arguments that should be set (from pushmode/add_mode), flushes when full or after timeout or after flushmode
- the old outgoing mode queue is removed, I cannot imagine anything relying on it in the module API
- drive-by fix for supporting more than 6 modes per line (we never actually supported that, oops)
- prefix modes get a modechar 'o', a prefixchar '@' and a rank (1..8) so we can see that admin is higher than op, but I have no idea what to do with that information yet
Design decisions
- existing prefix functionality remains focused on op/halfop/voice (bitch, stopnethack, flood-deop, protectops, ...)
- there is no new chattr flag to automatically assign new prefixes (+a autoop sticks with +o only)
- botisop, isop, etc. only check the actual 'o' flag, not "o or higher"
- there is logic to see who can set which modes, but I have no clue if this is correct (the rule is roughly: highest prefix can unset/set highest prefix and all lower ones - every other one can only set/unset lower ones except for 'o' which can set/unset 'o')
- WHO/WHOX is kept as authoritative prefix source, not names
- we try to negotiate the
multi-prefix CAP automatically unless disabled so WHO shows all prefixes
- only up to 8 prefixes are supported (can be changed to 16 or 32 easily, the limit is the rank)
- the
chanmode channel setting accepts arbitrary strings and is parsed as-needed when 005 isupport is known
getchanmode returns modes in arbitrary order (might be backwards incompatible if that was relied upon)
- the last known isupport string is fully saved to the userfile and loaded before connecting to the ircd so we have a reasonable default (from the last connection)
Tcl commands
chanmodeinfo <letter>
isprefix/wasprefix alongside isop/wasop/isvoice/wasvoice
isprefixatleast for rank-based prefix check e.g. isprefixatleast o is true for admins
chanmodelist to access generic list modes (q)
This is an issue to keep track of design decisions/open question/postponed tasks for arbitrary mode support in Eggdrop. The parsing was done in #1872 and now allows us to write actual supporting code.
Goals
PREFIX=(qaohv)~&@%+ CHANMODE=eIbq,k,flj,ACFHLMOPQTcgimnprstz).list-type modes (ebIq, ban-type masks as parameter)key-type modes (k, parameter on set/unset)limit-type modes (flj, parameter on set only)flag-type modes (imnprst.., no parameter)prefix-type modes (qaohv, set on nicknames with a corresponding non-alphanumeric prefix char)set_mode(chan, 'l', "12")also setschan->maxmembers=12)Implementation details
chan_t.modeflagsis a new uint64_t bitfield to track a-zA-Z0-9 (62 bits), compressing it would be of little benefitchan_t.modeargsis a newchar *[62]storing the argument for a-zA-Z0-9 if needed (wastes space for non-flag modes)chan_t.modelistsis a new struct field to track new list modes (q)opcharsis removed from the code with a deprecation warning if it is being set in the config, it never worked right to begin withchanset_t.cmodeis changed to instead have a list of modes and their arguments that should be set (from pushmode/add_mode), flushes when full or after timeout or after flushmodeDesign decisions
multi-prefixCAP automatically unless disabled so WHO shows all prefixeschanmodechannel setting accepts arbitrary strings and is parsed as-needed when 005 isupport is knowngetchanmodereturns modes in arbitrary order (might be backwards incompatible if that was relied upon)Tcl commands
chanmodeinfo <letter>isprefix/wasprefixalongside isop/wasop/isvoice/wasvoiceisprefixatleastfor rank-based prefix check e.g. isprefixatleast o is true for adminschanmodelistto access generic list modes (q)