mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 04:07:07 +00:00
Bump MUC occupants and send unavailable presences for ones removed from LRU
This commit is contained in:
parent
f3eeba7273
commit
f9be86b5db
2 changed files with 48 additions and 4 deletions
|
|
@ -90,7 +90,8 @@ func (lru *MUCOccupantsLRU) insertNewest(occupant *MUCOccupant) {
|
|||
lru.newest = occupant
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) Set(key int64, occupant *MUCOccupant) {
|
||||
// Set adds or replaces an occupant and possibly returns an occupant removed instead because of overflow
|
||||
func (lru *MUCOccupantsLRU) Set(key int64, occupant *MUCOccupant) (deleted *MUCOccupant) {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
||||
|
|
@ -117,11 +118,15 @@ func (lru *MUCOccupantsLRU) Set(key int64, occupant *MUCOccupant) {
|
|||
}
|
||||
|
||||
if len(lru.m) > int(MUCOccupantsLimit) && lru.oldest != nil {
|
||||
deleted = lru.oldest
|
||||
delete(lru.m, lru.oldest.key)
|
||||
lru.cutOut(lru.oldest)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Delete occupant by member ID
|
||||
func (lru *MUCOccupantsLRU) Delete(key int64) {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
|
@ -134,6 +139,7 @@ func (lru *MUCOccupantsLRU) Delete(key int64) {
|
|||
}
|
||||
}
|
||||
|
||||
// Bump raises the occupant in LRU
|
||||
func (lru *MUCOccupantsLRU) Bump(occupant *MUCOccupant) {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
|
@ -147,6 +153,7 @@ func (lru *MUCOccupantsLRU) Bump(occupant *MUCOccupant) {
|
|||
lru.insertNewest(occupant)
|
||||
}
|
||||
|
||||
// Range loops over all occupants
|
||||
func (lru *MUCOccupantsLRU) Range() chan *MUCOccupant {
|
||||
lru.lock.Lock()
|
||||
|
||||
|
|
@ -166,6 +173,7 @@ func (lru *MUCOccupantsLRU) Range() chan *MUCOccupant {
|
|||
return occupantChan
|
||||
}
|
||||
|
||||
// Clear properly removes all occupants and their possible mutual references (not necessary in Golang, yet still)
|
||||
func (lru *MUCOccupantsLRU) Clear() {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
|
|
|||
|
|
@ -567,6 +567,11 @@ func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, o
|
|||
for mucId, state := range c.mucCache {
|
||||
occupant, ok := state.Occupants.Get(chatID)
|
||||
if ok {
|
||||
if show == "" {
|
||||
// Bump occupants who just went online
|
||||
state.Occupants.Bump(occupant)
|
||||
}
|
||||
|
||||
_, toJids := c.getMUCJoinedJIDs(mucId, state, false)
|
||||
newMucArgs := append(
|
||||
newArgs,
|
||||
|
|
@ -753,7 +758,8 @@ func (c *Client) mucCacheHasOccupant(mucID int64, memberID int64) bool {
|
|||
return false // no MUC to be added to
|
||||
}
|
||||
|
||||
_, ok = mucState.Occupants.Get(memberID)
|
||||
occupant, ok := mucState.Occupants.Get(memberID)
|
||||
mucState.Occupants.Bump(occupant)
|
||||
return ok
|
||||
}
|
||||
|
||||
|
|
@ -780,12 +786,14 @@ func (c *Client) addMUCOccupant(mucID int64, memberID int64, affiliation, role s
|
|||
)
|
||||
|
||||
if err == nil {
|
||||
mucState.Occupants.Set(memberID, &MUCOccupant{
|
||||
deleted := mucState.Occupants.Set(memberID, &MUCOccupant{
|
||||
Nickname: nickname,
|
||||
Affiliation: affiliation,
|
||||
Role: role,
|
||||
Status: status,
|
||||
})
|
||||
c.kickStaleOccupant(mucID, deleted, mucState)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -832,12 +840,13 @@ func (c *Client) updateMUCsNickname(memberID int64, newNickname string) {
|
|||
for mucId, state := range c.mucCache {
|
||||
oldOccupant, ok := state.Occupants.Get(memberID)
|
||||
if ok {
|
||||
state.Occupants.Set(memberID, &MUCOccupant{
|
||||
deleted := state.Occupants.Set(memberID, &MUCOccupant{
|
||||
Nickname: newNickname,
|
||||
Affiliation: oldOccupant.Affiliation,
|
||||
Role: oldOccupant.Role,
|
||||
Status: oldOccupant.Status,
|
||||
})
|
||||
c.kickStaleOccupant(mucId, deleted, state)
|
||||
|
||||
sMucId := gateway.MUCNODE(mucId)
|
||||
unavailableStatusCodes := []uint16{303, 210}
|
||||
|
|
@ -925,6 +934,7 @@ func (c *Client) GetMyMUCNickname(chatID int64) (string, bool) {
|
|||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
mucState.Occupants.Bump(occupant)
|
||||
return occupant.Nickname, true
|
||||
}
|
||||
|
||||
|
|
@ -2882,6 +2892,31 @@ func (c *Client) kickMeFromMUC(chatID int64, statusCodes []uint16, destroy bool,
|
|||
return c.sendPresence(args...)
|
||||
}
|
||||
|
||||
// achtung: assuming a locked mucState context
|
||||
func (c *Client) kickStaleOccupant(chatID int64, deleted *MUCOccupant, mucState *MUCState) {
|
||||
if deleted == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// u mad? put me back!
|
||||
if c.me != nil && c.me.Id == deleted.key {
|
||||
deleted = mucState.Occupants.Set(deleted.key, deleted)
|
||||
if deleted == nil {
|
||||
// WTF but okay
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.sendPresence(
|
||||
gateway.SPFrom(gateway.MUCNODE(chatID)),
|
||||
gateway.SPResource(deleted.Nickname),
|
||||
gateway.SPType("unavailable"),
|
||||
gateway.SPMUCAffiliation(deleted.Affiliation),
|
||||
gateway.SPMUCRole(deleted.Role),
|
||||
gateway.SPMUCStatusCodes([]uint16{307, 333}),
|
||||
)
|
||||
}
|
||||
|
||||
// MigrateToMUCs unsubscribes from legacy group chats and invites to MUCs
|
||||
func (c *Client) MigrateToMUCs() {
|
||||
var chatIDs []int64
|
||||
|
|
@ -3072,6 +3107,7 @@ func (c *Client) mucOccupantRolePresence(chatID, userID int64, status ChatMember
|
|||
} else {
|
||||
occupant, ok := mucState.Occupants.Get(userID)
|
||||
if ok {
|
||||
mucState.Occupants.Bump(occupant)
|
||||
occupant.Affiliation = newAffiliation
|
||||
occupant.Role = newRole
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue