mirror of
https://github.com/ergochat/ergo.git
synced 2025-12-20 02:00:11 -08:00
parent
42316bc04f
commit
91cfdb963d
8 changed files with 214 additions and 44 deletions
|
|
@ -7,6 +7,8 @@ package sno
|
|||
// Mask is a type of server notice mask.
|
||||
type Mask rune
|
||||
|
||||
type Masks []Mask
|
||||
|
||||
// Notice mask types
|
||||
const (
|
||||
LocalAnnouncements Mask = 'a'
|
||||
|
|
@ -18,8 +20,8 @@ const (
|
|||
LocalQuits Mask = 'q'
|
||||
Stats Mask = 't'
|
||||
LocalAccounts Mask = 'u'
|
||||
LocalXline Mask = 'x'
|
||||
LocalVhosts Mask = 'v'
|
||||
LocalXline Mask = 'x'
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -39,17 +41,17 @@ var (
|
|||
}
|
||||
|
||||
// ValidMasks contains the snomasks that we support.
|
||||
ValidMasks = map[Mask]bool{
|
||||
LocalAnnouncements: true,
|
||||
LocalConnects: true,
|
||||
LocalChannels: true,
|
||||
LocalKills: true,
|
||||
LocalNicks: true,
|
||||
LocalOpers: true,
|
||||
LocalQuits: true,
|
||||
Stats: true,
|
||||
LocalAccounts: true,
|
||||
LocalXline: true,
|
||||
LocalVhosts: true,
|
||||
ValidMasks = []Mask{
|
||||
LocalAnnouncements,
|
||||
LocalConnects,
|
||||
LocalChannels,
|
||||
LocalKills,
|
||||
LocalNicks,
|
||||
LocalOpers,
|
||||
LocalQuits,
|
||||
Stats,
|
||||
LocalAccounts,
|
||||
LocalVhosts,
|
||||
LocalXline,
|
||||
}
|
||||
)
|
||||
|
|
|
|||
87
irc/sno/utils.go
Normal file
87
irc/sno/utils.go
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2020 Shivaram Lingamneni
|
||||
// released under the MIT license
|
||||
|
||||
package sno
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func IsValidMask(r rune) bool {
|
||||
for _, m := range ValidMasks {
|
||||
if m == Mask(r) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (masks Masks) String() string {
|
||||
var buf strings.Builder
|
||||
buf.Grow(len(masks))
|
||||
for _, m := range masks {
|
||||
buf.WriteRune(rune(m))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (masks Masks) Contains(mask Mask) bool {
|
||||
for _, m := range masks {
|
||||
if mask == m {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Evaluate changes to snomasks made with MODE. There are several cases:
|
||||
// adding snomasks with `/mode +s a` or `/mode +s +a`, removing them with `/mode +s -a`,
|
||||
// adding all with `/mode +s *` or `/mode +s +*`, removing all with `/mode +s -*` or `/mode -s`
|
||||
func EvaluateSnomaskChanges(add bool, arg string, currentMasks Masks) (addMasks, removeMasks Masks, newArg string) {
|
||||
if add {
|
||||
if len(arg) == 0 {
|
||||
return
|
||||
}
|
||||
add := true
|
||||
switch arg[0] {
|
||||
case '+':
|
||||
arg = arg[1:]
|
||||
case '-':
|
||||
add = false
|
||||
arg = arg[1:]
|
||||
default:
|
||||
// add
|
||||
}
|
||||
if strings.IndexByte(arg, '*') != -1 {
|
||||
if add {
|
||||
for _, mask := range ValidMasks {
|
||||
if !currentMasks.Contains(mask) {
|
||||
addMasks = append(addMasks, mask)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
removeMasks = currentMasks
|
||||
}
|
||||
} else {
|
||||
for _, r := range arg {
|
||||
if IsValidMask(r) {
|
||||
m := Mask(r)
|
||||
if add && !currentMasks.Contains(m) {
|
||||
addMasks = append(addMasks, m)
|
||||
} else if !add && currentMasks.Contains(m) {
|
||||
removeMasks = append(removeMasks, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(addMasks) != 0 {
|
||||
newArg = "+" + addMasks.String()
|
||||
} else if len(removeMasks) != 0 {
|
||||
newArg = "-" + removeMasks.String()
|
||||
}
|
||||
} else {
|
||||
removeMasks = currentMasks
|
||||
newArg = ""
|
||||
}
|
||||
return
|
||||
}
|
||||
53
irc/sno/utils_test.go
Normal file
53
irc/sno/utils_test.go
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2020 Shivaram Lingamneni
|
||||
// released under the MIT license
|
||||
|
||||
package sno
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func assertEqual(supplied, expected interface{}, t *testing.T) {
|
||||
if !reflect.DeepEqual(supplied, expected) {
|
||||
panic(fmt.Sprintf("expected %#v but got %#v", expected, supplied))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvaluateSnomaskChanges(t *testing.T) {
|
||||
add, remove, newArg := EvaluateSnomaskChanges(true, "*", nil)
|
||||
assertEqual(add, Masks{'a', 'c', 'j', 'k', 'n', 'o', 'q', 't', 'u', 'v', 'x'}, t)
|
||||
assertEqual(len(remove), 0, t)
|
||||
assertEqual(newArg, "+acjknoqtuvx", t)
|
||||
|
||||
add, remove, newArg = EvaluateSnomaskChanges(true, "*", Masks{'a', 'u'})
|
||||
assertEqual(add, Masks{'c', 'j', 'k', 'n', 'o', 'q', 't', 'v', 'x'}, t)
|
||||
assertEqual(len(remove), 0, t)
|
||||
assertEqual(newArg, "+cjknoqtvx", t)
|
||||
|
||||
add, remove, newArg = EvaluateSnomaskChanges(true, "-a", Masks{'a', 'u'})
|
||||
assertEqual(len(add), 0, t)
|
||||
assertEqual(remove, Masks{'a'}, t)
|
||||
assertEqual(newArg, "-a", t)
|
||||
|
||||
add, remove, newArg = EvaluateSnomaskChanges(true, "-*", Masks{'a', 'u'})
|
||||
assertEqual(len(add), 0, t)
|
||||
assertEqual(remove, Masks{'a', 'u'}, t)
|
||||
assertEqual(newArg, "-au", t)
|
||||
|
||||
add, remove, newArg = EvaluateSnomaskChanges(true, "+c", Masks{'a', 'u'})
|
||||
assertEqual(add, Masks{'c'}, t)
|
||||
assertEqual(len(remove), 0, t)
|
||||
assertEqual(newArg, "+c", t)
|
||||
|
||||
add, remove, newArg = EvaluateSnomaskChanges(false, "", Masks{'a', 'u'})
|
||||
assertEqual(len(add), 0, t)
|
||||
assertEqual(remove, Masks{'a', 'u'}, t)
|
||||
assertEqual(newArg, "", t)
|
||||
|
||||
add, remove, newArg = EvaluateSnomaskChanges(false, "*", Masks{'a', 'u'})
|
||||
assertEqual(len(add), 0, t)
|
||||
assertEqual(remove, Masks{'a', 'u'}, t)
|
||||
assertEqual(newArg, "", t)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue