Loading CHANGELOG.md +2 −1 Original line number Diff line number Diff line Loading @@ -40,8 +40,9 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr - Ensure rank cache is correctly updated when joining tournaments. - Ensure default parameters for tournament listings are consistent between API and runtimes. - Fix devconsole groups view incorrect visual removal of last group member. - Fix iap subscription notification handling. - Fix In-App Purchase subscription notification handling. - Fix handling of party leader transition if previous leader and other members leave concurrently. - Fix exact enforcement of maximum party size. ## [3.14.0] - 2022-10-14 ### Added Loading server/party_handler.go +23 −8 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ type PartyHandler struct { leaderUserPresence *rtapi.UserPresence members []*PresenceID memberUserPresences []*rtapi.UserPresence joinsInProgress int joinsInProgress []*PresenceID joinRequests []*Presence joinRequestUserPresences []*rtapi.UserPresence } Loading Loading @@ -80,7 +80,7 @@ func NewPartyHandler(logger *zap.Logger, partyRegistry PartyRegistry, matchmaker leaderUserPresence: nil, members: make([]*PresenceID, 0, maxSize), memberUserPresences: make([]*rtapi.UserPresence, 0, maxSize), joinsInProgress: 0, joinsInProgress: make([]*PresenceID, 0, maxSize), joinRequests: make([]*Presence, 0, maxSize), joinRequestUserPresences: make([]*rtapi.UserPresence, 0, maxSize), } Loading @@ -101,13 +101,13 @@ func (p *PartyHandler) JoinRequest(presence *Presence) (bool, error) { } // Check if party is full. if len(p.members)+p.joinsInProgress >= p.MaxSize { if len(p.members)+len(p.joinsInProgress) >= p.MaxSize { p.Unlock() return false, runtime.ErrPartyFull } // Check if party is open, and therefore automatically accepts join requests. if p.Open { p.joinsInProgress++ p.joinsInProgress = append(p.joinsInProgress, &presence.ID) p.Unlock() return true, nil } Loading Loading @@ -200,7 +200,15 @@ func (p *PartyHandler) Join(presences []*Presence) { p.members = append(p.members, ¤tPresence.ID) p.memberUserPresences = append(p.memberUserPresences, memberUserPresence) memberUserPresences = append(memberUserPresences, memberUserPresence) p.joinsInProgress-- for i := 0; i < len(p.joinsInProgress); i++ { if p.joinsInProgress[i].SessionID == presence.ID.SessionID && p.joinsInProgress[i].Node == presence.ID.Node { copy(p.joinsInProgress[i:], p.joinsInProgress[i+1:]) p.joinsInProgress[len(p.joinsInProgress)-1] = nil p.joinsInProgress = p.joinsInProgress[:len(p.joinsInProgress)-1] break } } // Prepare message to be sent to the new presences. if initialLeader != nil && presence == initialLeader { Loading Loading @@ -359,7 +367,7 @@ func (p *PartyHandler) Accept(sessionID, node string, presence *rtapi.UserPresen } // Check if there's room to accept the new party member. if len(p.members)+p.joinsInProgress >= p.MaxSize { if len(p.members)+len(p.joinsInProgress) >= p.MaxSize { p.Unlock() return runtime.ErrPartyFull } Loading @@ -386,14 +394,21 @@ func (p *PartyHandler) Accept(sessionID, node string, presence *rtapi.UserPresen return runtime.ErrPartyNotRequest } p.joinsInProgress++ p.joinsInProgress = append(p.joinsInProgress, &joinRequestPresence.ID) p.Unlock() // Add the presence to the party stream, which will trigger the Join() hook above. success, _, err := p.streamManager.UserJoin(p.Stream, joinRequestPresence.UserID, joinRequestPresence.ID.SessionID, false, false, "") if err != nil || !success { p.Lock() p.joinsInProgress-- for i := 0; i < len(p.joinsInProgress); i++ { if p.joinsInProgress[i].SessionID == joinRequestPresence.ID.SessionID && p.joinsInProgress[i].Node == joinRequestPresence.ID.Node { copy(p.joinsInProgress[i:], p.joinsInProgress[i+1:]) p.joinsInProgress[len(p.joinsInProgress)-1] = nil p.joinsInProgress = p.joinsInProgress[:len(p.joinsInProgress)-1] break } } p.Unlock() return runtime.ErrPartyAcceptRequest } Loading Loading
CHANGELOG.md +2 −1 Original line number Diff line number Diff line Loading @@ -40,8 +40,9 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr - Ensure rank cache is correctly updated when joining tournaments. - Ensure default parameters for tournament listings are consistent between API and runtimes. - Fix devconsole groups view incorrect visual removal of last group member. - Fix iap subscription notification handling. - Fix In-App Purchase subscription notification handling. - Fix handling of party leader transition if previous leader and other members leave concurrently. - Fix exact enforcement of maximum party size. ## [3.14.0] - 2022-10-14 ### Added Loading
server/party_handler.go +23 −8 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ type PartyHandler struct { leaderUserPresence *rtapi.UserPresence members []*PresenceID memberUserPresences []*rtapi.UserPresence joinsInProgress int joinsInProgress []*PresenceID joinRequests []*Presence joinRequestUserPresences []*rtapi.UserPresence } Loading Loading @@ -80,7 +80,7 @@ func NewPartyHandler(logger *zap.Logger, partyRegistry PartyRegistry, matchmaker leaderUserPresence: nil, members: make([]*PresenceID, 0, maxSize), memberUserPresences: make([]*rtapi.UserPresence, 0, maxSize), joinsInProgress: 0, joinsInProgress: make([]*PresenceID, 0, maxSize), joinRequests: make([]*Presence, 0, maxSize), joinRequestUserPresences: make([]*rtapi.UserPresence, 0, maxSize), } Loading @@ -101,13 +101,13 @@ func (p *PartyHandler) JoinRequest(presence *Presence) (bool, error) { } // Check if party is full. if len(p.members)+p.joinsInProgress >= p.MaxSize { if len(p.members)+len(p.joinsInProgress) >= p.MaxSize { p.Unlock() return false, runtime.ErrPartyFull } // Check if party is open, and therefore automatically accepts join requests. if p.Open { p.joinsInProgress++ p.joinsInProgress = append(p.joinsInProgress, &presence.ID) p.Unlock() return true, nil } Loading Loading @@ -200,7 +200,15 @@ func (p *PartyHandler) Join(presences []*Presence) { p.members = append(p.members, ¤tPresence.ID) p.memberUserPresences = append(p.memberUserPresences, memberUserPresence) memberUserPresences = append(memberUserPresences, memberUserPresence) p.joinsInProgress-- for i := 0; i < len(p.joinsInProgress); i++ { if p.joinsInProgress[i].SessionID == presence.ID.SessionID && p.joinsInProgress[i].Node == presence.ID.Node { copy(p.joinsInProgress[i:], p.joinsInProgress[i+1:]) p.joinsInProgress[len(p.joinsInProgress)-1] = nil p.joinsInProgress = p.joinsInProgress[:len(p.joinsInProgress)-1] break } } // Prepare message to be sent to the new presences. if initialLeader != nil && presence == initialLeader { Loading Loading @@ -359,7 +367,7 @@ func (p *PartyHandler) Accept(sessionID, node string, presence *rtapi.UserPresen } // Check if there's room to accept the new party member. if len(p.members)+p.joinsInProgress >= p.MaxSize { if len(p.members)+len(p.joinsInProgress) >= p.MaxSize { p.Unlock() return runtime.ErrPartyFull } Loading @@ -386,14 +394,21 @@ func (p *PartyHandler) Accept(sessionID, node string, presence *rtapi.UserPresen return runtime.ErrPartyNotRequest } p.joinsInProgress++ p.joinsInProgress = append(p.joinsInProgress, &joinRequestPresence.ID) p.Unlock() // Add the presence to the party stream, which will trigger the Join() hook above. success, _, err := p.streamManager.UserJoin(p.Stream, joinRequestPresence.UserID, joinRequestPresence.ID.SessionID, false, false, "") if err != nil || !success { p.Lock() p.joinsInProgress-- for i := 0; i < len(p.joinsInProgress); i++ { if p.joinsInProgress[i].SessionID == joinRequestPresence.ID.SessionID && p.joinsInProgress[i].Node == joinRequestPresence.ID.Node { copy(p.joinsInProgress[i:], p.joinsInProgress[i+1:]) p.joinsInProgress[len(p.joinsInProgress)-1] = nil p.joinsInProgress = p.joinsInProgress[:len(p.joinsInProgress)-1] break } } p.Unlock() return runtime.ErrPartyAcceptRequest } Loading