summaryrefslogtreecommitdiff
path: root/irc/tokens.go
diff options
context:
space:
mode:
authorHubert Hirtz <hubert@hirtz.pm>2021-11-04 14:24:59 +0100
committerHubert Hirtz <hubert@hirtz.pm>2021-11-06 12:26:16 +0100
commit9a595ffa7d5cec02e9f85ac8915676f4b6eb5e76 (patch)
tree554d52bd441ea9e09a2957371e7e087195bbbe03 /irc/tokens.go
parentRevert "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.go59
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
+}