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 }