diff options
author | Hubert Hirtz <hubert@hirtz.pm> | 2021-11-04 14:24:59 +0100 |
---|---|---|
committer | Hubert Hirtz <hubert@hirtz.pm> | 2021-11-06 12:26:16 +0100 |
commit | 9a595ffa7d5cec02e9f85ac8915676f4b6eb5e76 (patch) | |
tree | 554d52bd441ea9e09a2957371e7e087195bbbe03 /irc/tokens.go | |
parent | Revert "Show the current channel topic at the top of the timeline" (diff) |
Take mode changes into account
Diffstat (limited to 'irc/tokens.go')
-rw-r--r-- | irc/tokens.go | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/irc/tokens.go b/irc/tokens.go index a52a764..b28ef12 100644 --- a/irc/tokens.go +++ b/irc/tokens.go @@ -502,3 +502,62 @@ func ParseNameReply(trailing string, prefixes string) (names []Member) { return } + +// Mode types available in the CHANMODES 005 token. +const ( + ModeTypeA int = iota + ModeTypeB + ModeTypeC + ModeTypeD +) + +type ModeChange struct { + Enable bool + Mode byte + Param string +} + +// ParseChannelMode parses a MODE message for a channel, according to the +// CHANMODES of the server. +func ParseChannelMode(mode string, params []string, chanmodes [4]string, membershipModes string) ([]ModeChange, error) { + var changes []ModeChange + enable := true + paramIdx := 0 + for i := 0; i < len(mode); i++ { + m := mode[i] + if m == '+' || m == '-' { + enable = m == '+' + continue + } + modeType := -1 + for t := 0; t < 4; t++ { + if 0 <= strings.IndexByte(chanmodes[t], m) { + modeType = t + break + } + } + if 0 <= strings.IndexByte(membershipModes, m) { + modeType = ModeTypeB + } else if modeType == -1 { + return nil, fmt.Errorf("unknown mode %c", m) + } + // ref: https://modern.ircdocs.horse/#mode-message + if modeType == ModeTypeA || modeType == ModeTypeB || (enable && modeType == ModeTypeC) { + if len(params) <= paramIdx { + return nil, fmt.Errorf("missing mode params") + } + changes = append(changes, ModeChange{ + Enable: enable, + Mode: m, + Param: params[paramIdx], + }) + paramIdx++ + } else { + changes = append(changes, ModeChange{ + Enable: enable, + Mode: m, + }) + } + } + return changes, nil +} |