package user import ( "citrons.xyz/talk/server/object" "citrons.xyz/talk/server/session" "citrons.xyz/talk/server/validate" "citrons.xyz/talk/proto" ) type UserStore struct { world *object.World byName map[string]*User gone map[string]Tombstone } type User struct { store *UserStore name string id string Stream session.Stream Channels map[string]bool Anonymous bool } type Tombstone struct { name string } func NewStore(world *object.World) *UserStore { return &UserStore { world, make(map[string]*User), make(map[string]Tombstone), } } func (us *UserStore) CreateUser(name string) (*User, *proto.Fail) { if us.ByName(name) != nil { return nil, &proto.Fail { "name-taken", "", map[string]string {"": name}, } } if !validate.Name(name) { return nil, &proto.Fail { "invalid-name", "", map[string]string {"": name}, } } var u User u.store = us u.name = name us.byName[validate.Fold(name)] = &u u.id = us.world.NewObject(&u) u.Channels = make(map[string]bool) return &u, nil } func (us *UserStore) ByName(name string) *User { return us.byName[validate.Fold(name)] } func (u *User) Name() string { return u.name } func (u *User) Id() string { return u.id } func (u *User) Rename(name string) *proto.Fail { if !validate.Name(name) { return &proto.Fail { "invalid-name", "", map[string]string {"": name}, } } if validate.Fold(name) == validate.Fold(u.name) { u.name = name return nil } if u.store.ByName(name) != nil { return &proto.Fail { "name-taken", "", map[string]string {"": name}, } } u.store.byName[validate.Fold(u.name)] = nil u.store.byName[validate.Fold(name)] = u u.name = name return nil } func (u *User) Delete() { u.Stream.Event(proto.NewCmd("delete", u.id)) u.Stream.UnsubscribeAll() delete(u.store.byName, validate.Fold(u.name)) u.store.world.RemoveObject(u.id) gone := Tombstone {u.name} u.store.gone[u.id] = gone u.store.world.PutObject(u.id, gone) } func (u *User) GetInfo() proto.Object { return proto.Object { "u", u.id, map[string]string {"": u.name}, } } func (t Tombstone) GetInfo() proto.Object { return proto.Object { "gone", "", map[string]string {"": t.name}, } }