Anonymous IRC daemon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
2.7 KiB

package main
import (
"strings"
"sync"
"time"
)
const entityClient = 0
const entityChannel = 1
const stateTerminating = 0
const stateNormal = 1
const clientModes = "cD"
const channelModes = "cDiklmprstz"
const channelModesWithArg = "kl"
type Entity struct {
entitytype int
identifier string
created int64
state int
modes *sync.Map
}
func (e *Entity) Initialize(etype int, identifier string) {
e.identifier = identifier
e.entitytype = etype
e.created = time.Now().Unix()
e.state = stateNormal
e.modes = new(sync.Map)
}
func (e *Entity) getMode(mode string) string {
if v, ok := e.modes.Load(mode); ok {
return v.(string)
}
return ""
}
func (e *Entity) getModes() map[string]string {
modes := make(map[string]string)
e.modes.Range(func(k, v interface{}) bool {
modes[k.(string)] = v.(string)
return true
})
return modes
}
func (e *Entity) hasMode(mode string) bool {
_, ok := e.modes.Load(mode)
return ok
}
func (e *Entity) addMode(mode string, value string) {
var allowedmodes string
if e.entitytype == entityClient {
allowedmodes = clientModes
} else {
allowedmodes = channelModes
}
if strings.Contains(allowedmodes, mode) && !e.hasMode(mode) {
e.modes.Store(mode, value)
}
}
func (e *Entity) addModes(newmodes []string) {
if len(newmodes) == 0 {
return
}
p := 1
for _, mode := range strings.Split(newmodes[0], "") {
if strings.ContainsAny(mode, channelModesWithArg) {
if len(newmodes) > p {
e.addMode(mode, newmodes[p])
p++
}
} else {
e.addMode(mode, "")
}
}
}
func (e *Entity) removeMode(mode string) {
if e.hasMode(mode) {
e.modes.Delete(mode)
}
}
func (e *Entity) removeModes(modes string) {
for _, mode := range strings.Split(modes, "") {
e.removeMode(mode)
}
}
func (e *Entity) diffModes(lastmodes map[string]string) (map[string]string, map[string]string) {
addedmodes := make(map[string]string)
if lastmodes != nil {
e.modes.Range(func(k, v interface{}) bool {
if _, ok := lastmodes[k.(string)]; !ok {
addedmodes[k.(string)] = lastmodes[k.(string)]
}
return true
})
}
removedmodes := make(map[string]string)
for mode := range lastmodes {
if _, ok := e.modes.Load(mode); !ok {
removedmodes[mode] = mode
}
}
return addedmodes, removedmodes
}
func (e *Entity) printModes(addedmodes map[string]string, removedmodes map[string]string) string {
if removedmodes == nil {
removedmodes = make(map[string]string)
}
m := ""
// Added modes
sentsign := false
for mode := range addedmodes {
if !sentsign {
m += "+"
sentsign = true
}
m += mode
}
// Removed modes
sentsign = false
for mode := range removedmodes {
if !sentsign {
m += "-"
sentsign = true
}
m += mode
}
if m == "" {
m = "+"
}
return m
}