Пример #1
0
        /// <summary>
        /// Joins a random Photon room that matches with the given options. The matchmaker's state must be <see cref="ConnectionState.Connected"/>.
        /// </summary>
        /// Note that Photon will be connected to any found room instantly.
        /// See <see cref="LoadBalancingClient.OpJoinRoom"/> for more information.
        ///
        /// <inheritdoc cref="IMatchmaker.FindRandomGame"/>
        /// <param name="options">The <see cref="PhotonJoinRandomGameOptions"/> used to find a random game</param>
        /// <returns>An observable resolving with the <see cref="PhotonAlreadyJoinedGame"/> that was joined.</returns>
        /// <exception cref="ArgumentException">If <see cref="options"/> is not of type <see cref="PhotonJoinRandomGameOptions"/></exception>
        public virtual IObservable <IGame> FindRandomGame(IJoinRandomGameOptions options)
        {
            var photonOptions = options as PhotonJoinRandomGameOptions;

            if (photonOptions == null)
            {
                throw new ArgumentException($"{nameof(options)} must be of type {nameof(PhotonJoinRandomGameOptions)}.", nameof(options));
            }

            if (_photonClient.State != ClientState.ConnectedToMasterserver && _photonClient.State != ClientState.JoinedLobby)
            {
                return(Observable.Throw <IGame>(new InvalidOperationException($"Operation failed: Invalid state '{_photonClient.State}'." +
                                                                              " Please make sure you are connected to Photon.")));
            }

            var observable = PhotonUtils.CreateObservableForExpectedStateChange <IGame>(_photonClient,
                                                                                        expectedState: ClientState.Joined, returnValue: new PhotonAlreadyJoinedGame(_photonClient));

            State = ConnectionState.JoiningRoom;

            _photonClient.OpJoinRandomRoom(new OpJoinRandomRoomParams
            {
                ExpectedCustomRoomProperties = photonOptions.ExpectedCustomRoomProperties,
                ExpectedMaxPlayers           = photonOptions.ExpectedMaxPlayers,
                ExpectedUsers  = photonOptions.ExpectedUsers,
                MatchingType   = photonOptions.MatchmakingMode,
                TypedLobby     = photonOptions.Lobby,
                SqlLobbyFilter = photonOptions.SqlLobbyFilter
            });

            return(observable);
        }
Пример #2
0
        /// <summary>
        /// Join a room found by the given query. The matchmaker's state must be <see cref="ConnectionState.Connected"/>.
        /// </summary>
        /// Note that Photon will be connected to any found room instantly.
        /// See <see cref="LoadBalancingClient.OpJoinRoom"/> for more information.
        ///
        /// <inheritdoc cref="IMatchmaker.FindGame"/>
        /// <param name="options">The <see cref="PhotonGameQuery"/> used to find a game</param>
        /// <returns>An observable resolving with the <see cref="PhotonAlreadyJoinedGame"/> that was joined with the given query.</returns>
        /// <exception cref="ArgumentException">If <see cref="query"/> is not of type <see cref="PhotonGameQuery"/></exception>
        public virtual IObservable <IGame> FindGame(IGameQuery query)
        {
            var photonOptions = query as PhotonGameQuery;

            if (photonOptions == null)
            {
                throw new ArgumentException($"{nameof(query)} must be of type {nameof(PhotonGameQuery)}.", nameof(query));
            }

            if (string.IsNullOrEmpty(photonOptions.RoomName))
            {
                throw new ArgumentException($"{nameof(photonOptions.RoomName)} must not be null or empty.", nameof(query));
            }

            if (_photonClient.State != ClientState.ConnectedToMasterserver && _photonClient.State != ClientState.JoinedLobby)
            {
                return(Observable.Throw <IGame>(new InvalidOperationException($"Operation failed: Invalid state '{_photonClient.State}'." +
                                                                              " Please make sure you are connected to Photon.")));
            }

            var observable = PhotonUtils.CreateObservableForExpectedStateChange <IGame>(_photonClient,
                                                                                        expectedState: ClientState.Joined, returnValue: new PhotonAlreadyJoinedGame(_photonClient));

            State = ConnectionState.JoiningRoom;

            _photonClient.OpJoinRoom(new EnterRoomParams
            {
                RoomName      = photonOptions.RoomName,
                ExpectedUsers = photonOptions.ExpectedPlayers
            });

            return(observable);
        }
Пример #3
0
        /// <summary>
        /// Creates a new Photon room with the given options. The matchmaker's state must be <see cref="ConnectionState.Connected"/>.
        /// </summary>
        /// See <see cref="LoadBalancingClient.OpCreateRoom"/> for more information.
        ///
        /// <inheritdoc cref="IMatchmaker.CreateGame"/>
        /// <param name="options">The <see cref="PhotonCreateGameOptions"/> used to create the room</param>
        /// <returns>An observable resolving with the <see cref="PhotonAlreadyJoinedGame"/> that was joined with the given query.</returns>
        /// <exception cref="ArgumentException">If <see cref="options"/> is not of type <see cref="PhotonCreateGameOptions"/></exception>
        public virtual IObservable <IGame> CreateGame(ICreateGameOptions options)
        {
            var photonOptions = options as PhotonCreateGameOptions;

            if (photonOptions == null)
            {
                throw new ArgumentException($"{nameof(options)} must be of type {nameof(PhotonCreateGameOptions)}.", nameof(options));
            }

            if (_photonClient.State != ClientState.ConnectedToMasterserver && _photonClient.State != ClientState.JoinedLobby)
            {
                return(Observable.Throw <IGame>(new InvalidOperationException($"Operation failed: Invalid state '{_photonClient.State}'." +
                                                                              " Please make sure you are connected to Photon.")));
            }

            var observable = PhotonUtils.CreateObservableForExpectedStateChange <IGame>(_photonClient,
                                                                                        expectedState: ClientState.Joined, returnValue: new PhotonAlreadyJoinedGame(_photonClient));

            _photonClient.OpCreateRoom(new EnterRoomParams
            {
                RoomName      = photonOptions.RoomName,
                RoomOptions   = photonOptions,
                Lobby         = photonOptions.PhotonLobby,
                ExpectedUsers = photonOptions.ExpectedUsers
            });
            State = ConnectionState.JoiningRoom;

            return(observable);
        }
Пример #4
0
        /// <inheritdoc cref="Skaillz.Ubernet.IDisconnectable.Disconnect()"/>
        public override IObservable <IConnection> Disconnect()
        {
            base.Disconnect();

            var observable = PhotonUtils.CreateObservableForExpectedStateChange(_photonClient,
                                                                                expectedState: ClientState.ConnectedToMasterserver, returnValue: this);

            _photonClient.OpLeaveRoom(false);

            return(observable);
        }
Пример #5
0
        private void InitializeEvents()
        {
            _photonClient.StateChanged += (oldState, newState) =>
            {
                if (newState != ClientState.Joined)
                {
                    var reason = PhotonUtils.ConvertPhotonDisconnectCause(_photonClient.DisconnectedCause);
                    DisconnectedSubject.OnNext(reason);
                }
            };

            _photonClient.EventReceived += data =>
            {
                switch (data.Code)
                {
                case EventCode.Join:
                    AddClient(new Client((int)data.Parameters[ParameterCode.ActorNr]), true);
                    break;

                case EventCode.Leave:
                    RemoveClient((int)data.Parameters[ParameterCode.ActorNr]);
                    if (data.Parameters.ContainsKey(ParameterCode.MasterClientId))
                    {
                        int newHostId = (int)data.Parameters[ParameterCode.MasterClientId];
                        if (newHostId != Server.ClientId)
                        {
                            MigrateHost(newHostId, Server.ClientId, false);
                        }
                    }
                    break;

                case EventCode.PropertiesChanged:
                    var properties = (Hashtable)data.Parameters[ParameterCode.Properties];
                    if (properties.ContainsKey(GamePropertyKey.MasterClientId))
                    {
                        int newHostId = (int)properties[GamePropertyKey.MasterClientId];
                        MigrateHost(newHostId, Server.ClientId, false);
                    }
                    break;

                case PhotonEventCode:
                    var buffer = (PhotonArrayWrapper)data.Parameters[ParameterCode.Data];
                    var evt    = Serializer.Deserialize(buffer.Array, buffer.Length);
                    EventSubject.OnNext(evt);
                    break;
                }
            };
        }
Пример #6
0
        private void InitializeEvents()
        {
            _photonClient.StateChanged += (oldState, newState) =>
            {
                switch (newState)
                {
                case ClientState.Disconnecting:
                    State = ConnectionState.Disconnecting;
                    break;

                case ClientState.Disconnected:
                    var reason = PhotonUtils.ConvertPhotonDisconnectCause(_photonClient.DisconnectedCause);
                    _disconnectedSubject.OnNext(reason);
                    State = ConnectionState.Disconnected;
                    break;
                }
            };
        }
Пример #7
0
        protected virtual IObservable <PhotonMatchmaker> Connect()
        {
            if (_photonClient.State != ClientState.PeerCreated && _photonClient.State != ClientState.Disconnected)
            {
                return(Observable.Throw <PhotonMatchmaker>(new InvalidOperationException($"Operation failed: Invalid state '{_photonClient.State}'." +
                                                                                         " Please make sure you aren't already connected to Photon.")));
            }

            var observable = PhotonUtils.CreateObservableForExpectedStateChange(_photonClient,
                                                                                expectedState: ClientState.ConnectedToMasterserver, returnValue: this);

            State = ConnectionState.Connecting;

            if (!_photonClient.ConnectToRegionMaster(_photonSettings.Region))
            {
                return(Observable.Throw <PhotonMatchmaker>(new ConnectionException("Cannot connect to Photon.",
                                                                                   DisconnectReason.Exception)));
            }

            return(observable);
        }