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
|
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()
|
lru.lock.Lock()
|
||||||
defer lru.lock.Unlock()
|
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 {
|
if len(lru.m) > int(MUCOccupantsLimit) && lru.oldest != nil {
|
||||||
|
deleted = lru.oldest
|
||||||
delete(lru.m, lru.oldest.key)
|
delete(lru.m, lru.oldest.key)
|
||||||
lru.cutOut(lru.oldest)
|
lru.cutOut(lru.oldest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete occupant by member ID
|
||||||
func (lru *MUCOccupantsLRU) Delete(key int64) {
|
func (lru *MUCOccupantsLRU) Delete(key int64) {
|
||||||
lru.lock.Lock()
|
lru.lock.Lock()
|
||||||
defer lru.lock.Unlock()
|
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) {
|
func (lru *MUCOccupantsLRU) Bump(occupant *MUCOccupant) {
|
||||||
lru.lock.Lock()
|
lru.lock.Lock()
|
||||||
defer lru.lock.Unlock()
|
defer lru.lock.Unlock()
|
||||||
|
|
@ -147,6 +153,7 @@ func (lru *MUCOccupantsLRU) Bump(occupant *MUCOccupant) {
|
||||||
lru.insertNewest(occupant)
|
lru.insertNewest(occupant)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Range loops over all occupants
|
||||||
func (lru *MUCOccupantsLRU) Range() chan *MUCOccupant {
|
func (lru *MUCOccupantsLRU) Range() chan *MUCOccupant {
|
||||||
lru.lock.Lock()
|
lru.lock.Lock()
|
||||||
|
|
||||||
|
|
@ -166,6 +173,7 @@ func (lru *MUCOccupantsLRU) Range() chan *MUCOccupant {
|
||||||
return occupantChan
|
return occupantChan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear properly removes all occupants and their possible mutual references (not necessary in Golang, yet still)
|
||||||
func (lru *MUCOccupantsLRU) Clear() {
|
func (lru *MUCOccupantsLRU) Clear() {
|
||||||
lru.lock.Lock()
|
lru.lock.Lock()
|
||||||
defer lru.lock.Unlock()
|
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 {
|
for mucId, state := range c.mucCache {
|
||||||
occupant, ok := state.Occupants.Get(chatID)
|
occupant, ok := state.Occupants.Get(chatID)
|
||||||
if ok {
|
if ok {
|
||||||
|
if show == "" {
|
||||||
|
// Bump occupants who just went online
|
||||||
|
state.Occupants.Bump(occupant)
|
||||||
|
}
|
||||||
|
|
||||||
_, toJids := c.getMUCJoinedJIDs(mucId, state, false)
|
_, toJids := c.getMUCJoinedJIDs(mucId, state, false)
|
||||||
newMucArgs := append(
|
newMucArgs := append(
|
||||||
newArgs,
|
newArgs,
|
||||||
|
|
@ -753,7 +758,8 @@ func (c *Client) mucCacheHasOccupant(mucID int64, memberID int64) bool {
|
||||||
return false // no MUC to be added to
|
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
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -780,12 +786,14 @@ func (c *Client) addMUCOccupant(mucID int64, memberID int64, affiliation, role s
|
||||||
)
|
)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
mucState.Occupants.Set(memberID, &MUCOccupant{
|
deleted := mucState.Occupants.Set(memberID, &MUCOccupant{
|
||||||
Nickname: nickname,
|
Nickname: nickname,
|
||||||
Affiliation: affiliation,
|
Affiliation: affiliation,
|
||||||
Role: role,
|
Role: role,
|
||||||
Status: status,
|
Status: status,
|
||||||
})
|
})
|
||||||
|
c.kickStaleOccupant(mucID, deleted, mucState)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -832,12 +840,13 @@ func (c *Client) updateMUCsNickname(memberID int64, newNickname string) {
|
||||||
for mucId, state := range c.mucCache {
|
for mucId, state := range c.mucCache {
|
||||||
oldOccupant, ok := state.Occupants.Get(memberID)
|
oldOccupant, ok := state.Occupants.Get(memberID)
|
||||||
if ok {
|
if ok {
|
||||||
state.Occupants.Set(memberID, &MUCOccupant{
|
deleted := state.Occupants.Set(memberID, &MUCOccupant{
|
||||||
Nickname: newNickname,
|
Nickname: newNickname,
|
||||||
Affiliation: oldOccupant.Affiliation,
|
Affiliation: oldOccupant.Affiliation,
|
||||||
Role: oldOccupant.Role,
|
Role: oldOccupant.Role,
|
||||||
Status: oldOccupant.Status,
|
Status: oldOccupant.Status,
|
||||||
})
|
})
|
||||||
|
c.kickStaleOccupant(mucId, deleted, state)
|
||||||
|
|
||||||
sMucId := gateway.MUCNODE(mucId)
|
sMucId := gateway.MUCNODE(mucId)
|
||||||
unavailableStatusCodes := []uint16{303, 210}
|
unavailableStatusCodes := []uint16{303, 210}
|
||||||
|
|
@ -925,6 +934,7 @@ func (c *Client) GetMyMUCNickname(chatID int64) (string, bool) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
mucState.Occupants.Bump(occupant)
|
||||||
return occupant.Nickname, true
|
return occupant.Nickname, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2882,6 +2892,31 @@ func (c *Client) kickMeFromMUC(chatID int64, statusCodes []uint16, destroy bool,
|
||||||
return c.sendPresence(args...)
|
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
|
// MigrateToMUCs unsubscribes from legacy group chats and invites to MUCs
|
||||||
func (c *Client) MigrateToMUCs() {
|
func (c *Client) MigrateToMUCs() {
|
||||||
var chatIDs []int64
|
var chatIDs []int64
|
||||||
|
|
@ -3072,6 +3107,7 @@ func (c *Client) mucOccupantRolePresence(chatID, userID int64, status ChatMember
|
||||||
} else {
|
} else {
|
||||||
occupant, ok := mucState.Occupants.Get(userID)
|
occupant, ok := mucState.Occupants.Get(userID)
|
||||||
if ok {
|
if ok {
|
||||||
|
mucState.Occupants.Bump(occupant)
|
||||||
occupant.Affiliation = newAffiliation
|
occupant.Affiliation = newAffiliation
|
||||||
occupant.Role = newRole
|
occupant.Role = newRole
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue