示例#1
0
 internal void Leave(ClientSession session, MatchListingLeaveReason reason)
 {
     if (this._Clients.Remove(session))
     {
         this.Leave0(session, reason);
     }
 }
示例#2
0
        internal void Leave0(ClientSession session, MatchListingLeaveReason reason)
        {
            session.LobbySession.MatchListing = null;

            //Concurrency complexity
            Interlocked.Decrement(ref this.UsersReady); //We can freely decrement this here without having issues

            while (true)
            {
                int spotsLeft = this._SpotsLeft;
                if (spotsLeft != MatchListing.SPOTS_LEFT_GAME_STARTED) //Match has not been started or it is in progress of starting
                {
                    if (Interlocked.CompareExchange(ref this._SpotsLeft, spotsLeft + 1, spotsLeft) == spotsLeft)
                    {
                        break; //Match has not been started
                    }
                }
            }

            foreach (ClientSession other in this._Clients.Values)
            {
                other.UntrackUserInRoom(this.Name, session.SocketId);
            }

            foreach (ClientSession other in this.LobbyClients.Values)
            {
                other.UntrackUserInRoom(this.Name, session.SocketId);
            }

            session.UntrackUsersInRoom(this.Name);

            if (reason == MatchListingLeaveReason.Kicked)
            {
                session.SendPacket(new UserLeaveRoomOutgoingMessage(this.Name, session.SocketId));
            }

            if (Interlocked.CompareExchange(ref this._SpotsLeft, (int)this.MaxMembers, MatchListing.SPOTS_LEFT_DIED) != (int)this.MaxMembers)
            {
                uint currentHost = this._HostSocketId;
                if (currentHost == session.SocketId) //Time to pick new host
                {
                    //TODO: How should we handle friends only?

                    while (this._Clients.Count > 0)
                    {
                        ClientSession other = this._Clients.Values.FirstOrDefault();
                        if (other != null)
                        {
                            if (InterlockedExtansions.CompareExchange(ref this._HostSocketId, other.SocketId, currentHost) == currentHost)
                            {
                                if (this._Clients.Contains(other))
                                {
                                    other.SendPacket(new MatchOwnerOutgoingMessage(this.Name, true, true, true));
                                    break;
                                }
                                else
                                {
                                    currentHost = other.SocketId;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                foreach (ClientSession other in this.LobbyClients.Values)
                {
                    other.LobbySession.RemoveMatch(this);
                }

                PlatformRacing3Server.MatchListingManager.Die(this);
            }
        }