private void HandleCreateOrJoinResponse(IncomingMessage receivedMessage, ClientIncomingMessageTypes messageType)
        {
            var resultCode = receivedMessage.ReadEnterRoomResultCode();

            if (resultCode == EnterRoomResultCodes.Succeed)
            {
                if (messageType == ClientIncomingMessageTypes.CreateResponse)
                {
                    this.CurrentRoom = new LocalNetworkRoom(this.lastRoomOptionsRequest, this.LocalPlayer);
                }
                else
                {
                    this.CurrentRoom = LocalNetworkRoom.FromJoinMessage(receivedMessage, this.LocalPlayer, this.lastRoomOptionsRequest);
                }

                this.State = ClientStates.Joined;
            }
            else
            {
                Debug.WriteLine($"[MatchmakingClient] EnterRoom response error: {resultCode}");

                this.State = ClientStates.InLobby;
            }

            this.enterRoomTCS?.TrySetResult(resultCode);
            this.enterRoomTCS           = null;
            this.lastRoomOptionsRequest = null;
        }
        /// <summary>
        /// Disconnects this client from any matchmaking server and sets the <see cref="State"/> if the connection
        /// is successfully closed.
        /// </summary>
        public void Disconnect()
        {
            if (this.State != ClientStates.Disconnected &&
                this.networkClient != null)
            {
                if (this.IsConnectedAndReady)
                {
                    this.LeaveRoom();
                }

                this.networkClient.Disconnect();
                this.networkClient.HostDisconnected -= this.NetworkClient_HostDisconnected;
                this.networkClient.HostDiscovered   -= this.NetworkClient_HostDiscovered;
                this.networkClient.MessageReceived  -= this.NetworkClient_MessageReceived;
                this.networkClient = null;

                this.enterRoomTCS?.TrySetResult(EnterRoomResultCodes.Aborted);

                this.LocalPlayer.Id = -1;
                this.CurrentRoom    = null;
                this.roomsInLobby.Clear();

                this.State = ClientStates.Disconnected;
            }
        }
        /// <summary>
        /// Leaves the <see cref="CurrentRoom"/> and returns to the lobby.
        /// </summary>
        /// <returns>If the current room could be left (impossible while not in a room).</returns>
        public bool LeaveRoom()
        {
            this.CheckClientIsReady();

            if (this.State != ClientStates.Joined)
            {
                return(false);
            }

            this.State = ClientStates.Leaving;
            var leaveRoomMsg = this.CreateClientMessage(ServerIncomingMessageTypes.LeaveRoomRequest);

            this.networkClient.Send(leaveRoomMsg, DeliveryMethod.ReliableOrdered);

            this.LocalPlayer.Id = -1;
            this.CurrentRoom    = null;

            return(true);
        }