From 589912b4202a477becf07ba6b5ba496669f94b75 Mon Sep 17 00:00:00 2001 From: Andrei Mihu Date: Thu, 29 Dec 2022 13:39:22 +0000 Subject: [PATCH] Fix exact enforcement of maximum party size. --- CHANGELOG.md | 3 ++- server/party_handler.go | 31 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9732282fe..8dfe8e43e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/server/party_handler.go b/server/party_handler.go index 6d5d9023e..1cd20346b 100644 --- a/server/party_handler.go +++ b/server/party_handler.go @@ -49,7 +49,7 @@ type PartyHandler struct { leaderUserPresence *rtapi.UserPresence members []*PresenceID memberUserPresences []*rtapi.UserPresence - joinsInProgress int + joinsInProgress []*PresenceID joinRequests []*Presence joinRequestUserPresences []*rtapi.UserPresence } @@ -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), } @@ -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 } @@ -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 { @@ -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 } @@ -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 } -- GitLab