diff options
author | Emile <git@emile.space> | 2024-10-25 15:55:50 +0200 |
---|---|---|
committer | Emile <git@emile.space> | 2024-10-25 15:55:50 +0200 |
commit | c90f36e3dd179d2de96f4f5fe38d8dc9a9de6dfe (patch) | |
tree | 89e9afb41c5bf76f48cfb09305a2d3db8d302b06 /vendor/maunium.net/go/mautrix/event/powerlevels.go | |
parent | 98bbb0f559a8883bc47bae80607dbe326a448e61 (diff) |
Diffstat (limited to 'vendor/maunium.net/go/mautrix/event/powerlevels.go')
-rw-r--r-- | vendor/maunium.net/go/mautrix/event/powerlevels.go | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/vendor/maunium.net/go/mautrix/event/powerlevels.go b/vendor/maunium.net/go/mautrix/event/powerlevels.go new file mode 100644 index 0000000..2f4d457 --- /dev/null +++ b/vendor/maunium.net/go/mautrix/event/powerlevels.go @@ -0,0 +1,199 @@ +// Copyright (c) 2020 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package event + +import ( + "sync" + + "go.mau.fi/util/ptr" + "golang.org/x/exp/maps" + + "maunium.net/go/mautrix/id" +) + +// PowerLevelsEventContent represents the content of a m.room.power_levels state event content. +// https://spec.matrix.org/v1.5/client-server-api/#mroompower_levels +type PowerLevelsEventContent struct { + usersLock sync.RWMutex + Users map[id.UserID]int `json:"users,omitempty"` + UsersDefault int `json:"users_default,omitempty"` + + eventsLock sync.RWMutex + Events map[string]int `json:"events,omitempty"` + EventsDefault int `json:"events_default,omitempty"` + + Notifications *NotificationPowerLevels `json:"notifications,omitempty"` + + StateDefaultPtr *int `json:"state_default,omitempty"` + + InvitePtr *int `json:"invite,omitempty"` + KickPtr *int `json:"kick,omitempty"` + BanPtr *int `json:"ban,omitempty"` + RedactPtr *int `json:"redact,omitempty"` +} + +func (pl *PowerLevelsEventContent) Clone() *PowerLevelsEventContent { + if pl == nil { + return nil + } + return &PowerLevelsEventContent{ + Users: maps.Clone(pl.Users), + UsersDefault: pl.UsersDefault, + Events: maps.Clone(pl.Events), + EventsDefault: pl.EventsDefault, + StateDefaultPtr: ptr.Clone(pl.StateDefaultPtr), + + Notifications: pl.Notifications.Clone(), + + InvitePtr: ptr.Clone(pl.InvitePtr), + KickPtr: ptr.Clone(pl.KickPtr), + BanPtr: ptr.Clone(pl.BanPtr), + RedactPtr: ptr.Clone(pl.RedactPtr), + } +} + +type NotificationPowerLevels struct { + RoomPtr *int `json:"room,omitempty"` +} + +func (npl *NotificationPowerLevels) Clone() *NotificationPowerLevels { + if npl == nil { + return nil + } + return &NotificationPowerLevels{ + RoomPtr: ptr.Clone(npl.RoomPtr), + } +} + +func (npl *NotificationPowerLevels) Room() int { + if npl != nil && npl.RoomPtr != nil { + return *npl.RoomPtr + } + return 50 +} + +func (pl *PowerLevelsEventContent) Invite() int { + if pl.InvitePtr != nil { + return *pl.InvitePtr + } + return 0 +} + +func (pl *PowerLevelsEventContent) Kick() int { + if pl.KickPtr != nil { + return *pl.KickPtr + } + return 50 +} + +func (pl *PowerLevelsEventContent) Ban() int { + if pl.BanPtr != nil { + return *pl.BanPtr + } + return 50 +} + +func (pl *PowerLevelsEventContent) Redact() int { + if pl.RedactPtr != nil { + return *pl.RedactPtr + } + return 50 +} + +func (pl *PowerLevelsEventContent) StateDefault() int { + if pl.StateDefaultPtr != nil { + return *pl.StateDefaultPtr + } + return 50 +} + +func (pl *PowerLevelsEventContent) GetUserLevel(userID id.UserID) int { + pl.usersLock.RLock() + defer pl.usersLock.RUnlock() + level, ok := pl.Users[userID] + if !ok { + return pl.UsersDefault + } + return level +} + +func (pl *PowerLevelsEventContent) SetUserLevel(userID id.UserID, level int) { + pl.usersLock.Lock() + defer pl.usersLock.Unlock() + if level == pl.UsersDefault { + delete(pl.Users, userID) + } else { + if pl.Users == nil { + pl.Users = make(map[id.UserID]int) + } + pl.Users[userID] = level + } +} + +func (pl *PowerLevelsEventContent) EnsureUserLevel(target id.UserID, level int) bool { + return pl.EnsureUserLevelAs("", target, level) +} + +func (pl *PowerLevelsEventContent) EnsureUserLevelAs(actor, target id.UserID, level int) bool { + existingLevel := pl.GetUserLevel(target) + if actor != "" { + actorLevel := pl.GetUserLevel(actor) + if actorLevel <= existingLevel || actorLevel < level { + return false + } + } + if existingLevel != level { + pl.SetUserLevel(target, level) + return true + } + return false +} + +func (pl *PowerLevelsEventContent) GetEventLevel(eventType Type) int { + pl.eventsLock.RLock() + defer pl.eventsLock.RUnlock() + level, ok := pl.Events[eventType.String()] + if !ok { + if eventType.IsState() { + return pl.StateDefault() + } + return pl.EventsDefault + } + return level +} + +func (pl *PowerLevelsEventContent) SetEventLevel(eventType Type, level int) { + pl.eventsLock.Lock() + defer pl.eventsLock.Unlock() + if (eventType.IsState() && level == pl.StateDefault()) || (!eventType.IsState() && level == pl.EventsDefault) { + delete(pl.Events, eventType.String()) + } else { + if pl.Events == nil { + pl.Events = make(map[string]int) + } + pl.Events[eventType.String()] = level + } +} + +func (pl *PowerLevelsEventContent) EnsureEventLevel(eventType Type, level int) bool { + return pl.EnsureEventLevelAs("", eventType, level) +} + +func (pl *PowerLevelsEventContent) EnsureEventLevelAs(actor id.UserID, eventType Type, level int) bool { + existingLevel := pl.GetEventLevel(eventType) + if actor != "" { + actorLevel := pl.GetUserLevel(actor) + if existingLevel > actorLevel || level > actorLevel { + return false + } + } + if existingLevel != level { + pl.SetEventLevel(eventType, level) + return true + } + return false +} |