Commit 30752305 authored by Andrei Mihu's avatar Andrei Mihu
Browse files

Fix handling of party leader transition if previous leader and other members leave concurrently.

parent b77747e4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr
- 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 handling of party leader transition if previous leader and other members leave concurrently.

## [3.14.0] - 2022-10-14
### Added
+13 −7
Original line number Diff line number Diff line
@@ -174,6 +174,9 @@ func (p *PartyHandler) Join(presences []*Presence) {
				}
			}
		}
		if initialLeader == nil {
			// If the expected initial leader was not assigned, select the first joiner. Also
			// covers the party leader leaving at some point during the lifecycle of the party.
			p.leader = &presences[0].ID
			p.leaderUserPresence = &rtapi.UserPresence{
				UserId:    presences[0].GetUserId(),
@@ -181,6 +184,7 @@ func (p *PartyHandler) Join(presences []*Presence) {
				Username:  presences[0].GetUsername(),
			}
		}
	}

	memberUserPresences := make([]*rtapi.UserPresence, len(p.memberUserPresences), len(p.memberUserPresences)+len(presences))
	copy(memberUserPresences, p.memberUserPresences)
@@ -211,7 +215,7 @@ func (p *PartyHandler) Join(presences []*Presence) {
					MaxSize: int32(p.MaxSize),
					Self:    memberUserPresence,
					Leader:  p.leaderUserPresence,
					// Presences assigned below,
					// Presences assigned below.
				},
			},
		}
@@ -241,7 +245,9 @@ func (p *PartyHandler) Leave(presences []*Presence) {

	// Drop each presence from the party list, and remove the leader if they've left.
	for _, presence := range presences {
		if p.leader.SessionID == presence.ID.SessionID && p.leader.Node == presence.ID.Node {
		if p.leader != nil && p.leader.SessionID == presence.ID.SessionID && p.leader.Node == presence.ID.Node {
			// Check is only meaningful if a leader exists. Leader may temporarily be nil here until a new
			// one is assigned below, when multiple presences leave concurrently and one was just the leader.
			p.leader = nil
			p.leaderUserPresence = nil
		}