158 lines
2.7 KiB
Go
158 lines
2.7 KiB
Go
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
|
|
}
|