From 815190be147e575f12211c468f8121e5c60e6337 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 16 Apr 2020 19:27:35 +0300 Subject: Update stuff and move pushrules to mautrix-go --- matrix/rooms/room.go | 153 +++++++++++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 65 deletions(-) (limited to 'matrix/rooms/room.go') diff --git a/matrix/rooms/room.go b/matrix/rooms/room.go index fd7d53b..0c28a9d 100644 --- a/matrix/rooms/room.go +++ b/matrix/rooms/room.go @@ -27,6 +27,8 @@ import ( sync "github.com/sasha-s/go-deadlock" "maunium.net/go/mautrix" + "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/id" "maunium.net/go/gomuks/debug" ) @@ -54,25 +56,27 @@ type RoomTag struct { } type UnreadMessage struct { - EventID string + EventID id.EventID Counted bool Highlight bool } type Member struct { - mautrix.Member + event.Member // The user who sent the membership event - Sender string `json:"-"` + Sender id.UserID `json:"-"` } // Room represents a single Matrix room. type Room struct { // The room ID. - ID string + ID id.RoomID // Whether or not the user has left the room. HasLeft bool + // Whether or not the room is encrypted. + Encrypted bool // The first batch of events that has been fetched for this room. // Used for fetching additional history. @@ -80,14 +84,14 @@ type Room struct { // The last_batch field from the most recent sync. Used for fetching member lists. LastPrevBatch string // The MXID of the user whose session this room was created for. - SessionUserID string + SessionUserID id.UserID SessionMember *Member // The number of unread messages that were notified about. UnreadMessages []UnreadMessage unreadCountCache *int highlightCache *bool - lastMarkedRead string + lastMarkedRead id.EventID // Whether or not this room is marked as a direct chat. IsDirect bool @@ -101,10 +105,10 @@ type Room struct { // Whether or not the members for this room have been fetched from the server. MembersFetched bool // Room state cache. - state map[mautrix.EventType]map[string]*mautrix.Event + state map[event.Type]map[string]*event.Event // MXID -> Member cache calculated from membership events. - memberCache map[string]*Member - exMemberCache map[string]*Member + memberCache map[id.UserID]*Member + exMemberCache map[id.UserID]*Member // The first two non-SessionUserID members in the room. Calculated at // the same time as memberCache. firstMemberCache *Member @@ -117,11 +121,11 @@ type Room struct { // The topic of the room. Directly fetched from the m.room.topic state event. topicCache string // The canonical alias of the room. Directly fetched from the m.room.canonical_alias state event. - CanonicalAliasCache string + CanonicalAliasCache id.RoomAlias // Whether or not the room has been tombstoned. replacedCache bool // The room ID that replaced this room. - replacedByCache *string + replacedByCache *id.RoomID // Path for state store file. path string @@ -174,7 +178,7 @@ func (room *Room) load() { return } debug.Print("Loading state for room", room.ID, "from disk") - room.state = make(map[mautrix.EventType]map[string]*mautrix.Event) + room.state = make(map[event.Type]map[string]*event.Event) file, err := os.OpenFile(room.path, os.O_RDONLY, 0600) if err != nil { if !os.IsNotExist(err) { @@ -265,7 +269,7 @@ func (room *Room) Save() { } // MarkRead clears the new message statuses on this room. -func (room *Room) MarkRead(eventID string) bool { +func (room *Room) MarkRead(eventID id.EventID) bool { room.lock.Lock() defer room.lock.Unlock() if room.lastMarkedRead == eventID { @@ -319,7 +323,7 @@ func (room *Room) HasNewMessages() bool { return len(room.UnreadMessages) > 0 } -func (room *Room) AddUnread(eventID string, counted, highlight bool) { +func (room *Room) AddUnread(eventID id.EventID, counted, highlight bool) { room.lock.Lock() defer room.lock.Unlock() room.UnreadMessages = append(room.UnreadMessages, UnreadMessage{ @@ -341,18 +345,25 @@ func (room *Room) AddUnread(eventID string, counted, highlight bool) { } } +var ( + tagDirect = RoomTag{"net.maunium.gomuks.fake.direct", "0.5"} + tagInvite = RoomTag{"net.maunium.gomuks.fake.invite", "0.5"} + tagDefault = RoomTag{"", "0.5"} + tagLeave = RoomTag{"net.maunium.gomuks.fake.leave", "0.5"} +) + func (room *Room) Tags() []RoomTag { room.lock.RLock() defer room.lock.RUnlock() if len(room.RawTags) == 0 { if room.IsDirect { - return []RoomTag{{"net.maunium.gomuks.fake.direct", "0.5"}} - } else if room.SessionMember != nil && room.SessionMember.Membership == mautrix.MembershipInvite { - return []RoomTag{{"net.maunium.gomuks.fake.invite", "0.5"}} - } else if room.SessionMember != nil && room.SessionMember.Membership != mautrix.MembershipJoin { - return []RoomTag{{"net.maunium.gomuks.fake.leave", "0.5"}} + return []RoomTag{tagDirect} + } else if room.SessionMember != nil && room.SessionMember.Membership == event.MembershipInvite { + return []RoomTag{tagInvite} + } else if room.SessionMember != nil && room.SessionMember.Membership != event.MembershipJoin { + return []RoomTag{tagLeave} } - return []RoomTag{{"", "0.5"}} + return []RoomTag{tagDefault} } return room.RawTags } @@ -374,46 +385,46 @@ func (room *Room) UpdateSummary(summary mautrix.LazyLoadSummary) { // UpdateState updates the room's current state with the given Event. This will clobber events based // on the type/state_key combination. -func (room *Room) UpdateState(event *mautrix.Event) { - if event.StateKey == nil { +func (room *Room) UpdateState(evt *event.Event) { + if evt.StateKey == nil { panic("Tried to UpdateState() event with no state key.") } room.Load() room.lock.Lock() defer room.lock.Unlock() room.changed = true - _, exists := room.state[event.Type] + _, exists := room.state[evt.Type] if !exists { - room.state[event.Type] = make(map[string]*mautrix.Event) + room.state[evt.Type] = make(map[string]*event.Event) } - switch event.Type { - case mautrix.StateRoomName: - room.NameCache = event.Content.Name + switch evt.Type { + case event.StateRoomName: + room.NameCache = evt.Content.Name room.nameCacheSource = ExplicitRoomName - case mautrix.StateCanonicalAlias: + case event.StateCanonicalAlias: if room.nameCacheSource <= CanonicalAliasRoomName { - room.NameCache = event.Content.Alias + room.NameCache = string(evt.Content.Alias) room.nameCacheSource = CanonicalAliasRoomName } - room.CanonicalAliasCache = event.Content.Alias - case mautrix.StateMember: + room.CanonicalAliasCache = evt.Content.Alias + case event.StateMember: if room.nameCacheSource <= MemberRoomName { room.NameCache = "" } - room.updateMemberState(event) - case mautrix.StateTopic: - room.topicCache = event.Content.Topic + room.updateMemberState(evt) + case event.StateTopic: + room.topicCache = evt.Content.Topic } - if event.Type != mautrix.StateMember { - debug.Printf("Updating state %s#%s for %s", event.Type.String(), event.GetStateKey(), room.ID) + if evt.Type != event.StateMember { + debug.Printf("Updating state %s#%s for %s", evt.Type.String(), evt.GetStateKey(), room.ID) } - room.state[event.Type][*event.StateKey] = event + room.state[evt.Type][*evt.StateKey] = evt } -func (room *Room) updateMemberState(event *mautrix.Event) { - userID := event.GetStateKey() +func (room *Room) updateMemberState(event *event.Event) { + userID := id.UserID(event.GetStateKey()) if userID == room.SessionUserID { debug.Print("Updating session user state:", string(event.Content.VeryRaw)) room.SessionMember = room.eventToMember(userID, event.Sender, &event.Content) @@ -442,7 +453,7 @@ func (room *Room) updateMemberState(event *mautrix.Event) { } // GetStateEvent returns the state event for the given type/state_key combo, or nil. -func (room *Room) GetStateEvent(eventType mautrix.EventType, stateKey string) *mautrix.Event { +func (room *Room) GetStateEvent(eventType event.Type, stateKey string) *event.Event { room.Load() room.lock.RLock() defer room.lock.RUnlock() @@ -452,7 +463,7 @@ func (room *Room) GetStateEvent(eventType mautrix.EventType, stateKey string) *m } // getStateEvents returns the state events for the given type. -func (room *Room) getStateEvents(eventType mautrix.EventType) map[string]*mautrix.Event { +func (room *Room) getStateEvents(eventType event.Type) map[string]*event.Event { stateEventMap, _ := room.state[eventType] return stateEventMap } @@ -460,7 +471,7 @@ func (room *Room) getStateEvents(eventType mautrix.EventType) map[string]*mautri // GetTopic returns the topic of the room. func (room *Room) GetTopic() string { if len(room.topicCache) == 0 { - topicEvt := room.GetStateEvent(mautrix.StateTopic, "") + topicEvt := room.GetStateEvent(event.StateTopic, "") if topicEvt != nil { room.topicCache = topicEvt.Content.Topic } @@ -468,9 +479,9 @@ func (room *Room) GetTopic() string { return room.topicCache } -func (room *Room) GetCanonicalAlias() string { +func (room *Room) GetCanonicalAlias() id.RoomAlias { if len(room.CanonicalAliasCache) == 0 { - canonicalAliasEvt := room.GetStateEvent(mautrix.StateCanonicalAlias, "") + canonicalAliasEvt := room.GetStateEvent(event.StateCanonicalAlias, "") if canonicalAliasEvt != nil { room.CanonicalAliasCache = canonicalAliasEvt.Content.Alias } else { @@ -485,7 +496,7 @@ func (room *Room) GetCanonicalAlias() string { // updateNameFromNameEvent updates the room display name to be the name set in the name event. func (room *Room) updateNameFromNameEvent() { - nameEvt := room.GetStateEvent(mautrix.StateRoomName, "") + nameEvt := room.GetStateEvent(event.StateRoomName, "") if nameEvt != nil { room.NameCache = nameEvt.Content.Name } @@ -528,7 +539,7 @@ func (room *Room) updateNameCache() { room.nameCacheSource = ExplicitRoomName } if len(room.NameCache) == 0 { - room.NameCache = room.GetCanonicalAlias() + room.NameCache = string(room.GetCanonicalAlias()) room.nameCacheSource = CanonicalAliasRoomName } if len(room.NameCache) == 0 { @@ -548,8 +559,8 @@ func (room *Room) GetTitle() string { func (room *Room) IsReplaced() bool { if room.replacedByCache == nil { - evt := room.GetStateEvent(mautrix.StateTombstone, "") - var replacement string + evt := room.GetStateEvent(event.StateTombstone, "") + var replacement id.RoomID if evt != nil { replacement = evt.Content.ReplacementRoom } @@ -559,18 +570,18 @@ func (room *Room) IsReplaced() bool { return room.replacedCache } -func (room *Room) ReplacedBy() string { +func (room *Room) ReplacedBy() id.RoomID { if room.replacedByCache == nil { room.IsReplaced() } return *room.replacedByCache } -func (room *Room) eventToMember(userID string, sender string, content *mautrix.Content) *Member { +func (room *Room) eventToMember(userID, sender id.UserID, content *event.Content) *Member { member := content.Member member.Membership = content.Membership if len(member.Displayname) == 0 { - member.Displayname = userID + member.Displayname = string(userID) } return &Member{ Member: member, @@ -578,7 +589,7 @@ func (room *Room) eventToMember(userID string, sender string, content *mautrix.C } } -func (room *Room) updateNthMemberCache(userID string, member *Member) { +func (room *Room) updateNthMemberCache(userID id.UserID, member *Member) { if userID != room.SessionUserID { if room.firstMemberCache == nil { room.firstMemberCache = member @@ -589,19 +600,20 @@ func (room *Room) updateNthMemberCache(userID string, member *Member) { } // createMemberCache caches all member events into a easily processable MXID -> *Member map. -func (room *Room) createMemberCache() map[string]*Member { +func (room *Room) createMemberCache() map[id.UserID]*Member { if len(room.memberCache) > 0 { return room.memberCache } - cache := make(map[string]*Member) - exCache := make(map[string]*Member) + cache := make(map[id.UserID]*Member) + exCache := make(map[id.UserID]*Member) room.lock.RLock() - events := room.getStateEvents(mautrix.StateMember) + memberEvents := room.getStateEvents(event.StateMember) room.firstMemberCache = nil room.secondMemberCache = nil - if events != nil { - for userID, event := range events { - member := room.eventToMember(userID, event.Sender, &event.Content) + if memberEvents != nil { + for userIDStr, evt := range memberEvents { + userID := id.UserID(userIDStr) + member := room.eventToMember(userID, evt.Sender, &evt.Content) if member.Membership.IsInviteOrJoin() { cache[userID] = member room.updateNthMemberCache(userID, member) @@ -631,7 +643,7 @@ func (room *Room) createMemberCache() map[string]*Member { // // The members are returned from the cache. // If the cache is empty, it is updated first. -func (room *Room) GetMembers() map[string]*Member { +func (room *Room) GetMembers() map[id.UserID]*Member { room.Load() room.createMemberCache() return room.memberCache @@ -639,7 +651,7 @@ func (room *Room) GetMembers() map[string]*Member { // GetMember returns the member with the given MXID. // If the member doesn't exist, nil is returned. -func (room *Room) GetMember(userID string) *Member { +func (room *Room) GetMember(userID id.UserID) *Member { if userID == room.SessionUserID && room.SessionMember != nil { return room.SessionMember } @@ -660,16 +672,27 @@ func (room *Room) GetMember(userID string) *Member { return nil } +func (room *Room) GetMemberCount() int { + if room.memberCache == nil && room.Summary.JoinedMemberCount != nil { + return *room.Summary.JoinedMemberCount + } + return len(room.GetMembers()) +} + // GetSessionOwner returns the ID of the user whose session this room was created for. -func (room *Room) GetSessionOwner() string { - return room.SessionUserID +func (room *Room) GetOwnDisplayname() string { + member := room.GetMember(room.SessionUserID) + if member != nil { + return member.Displayname + } + return "" } // NewRoom creates a new Room with the given ID -func NewRoom(roomID string, cache *RoomCache) *Room { +func NewRoom(roomID id.RoomID, cache *RoomCache) *Room { return &Room{ ID: roomID, - state: make(map[mautrix.EventType]map[string]*mautrix.Event), + state: make(map[event.Type]map[string]*event.Event), path: cache.roomPath(roomID), cache: cache, -- cgit v1.2.3