private void JoinGameOnGameServer()
        {
            if (log.IsDebugEnabled)
            {
                log.DebugFormat("GAME: Joining game {0}", this.gameId);
            }

            var operation = new JoinGameRequest { GameId = this.gameId };
            var request = new OperationRequest((byte)OperationCode.JoinGame, operation);
            this.gameServerClient.SendOperationRequest(request, new SendParameters());
        }
        /// <summary>
        ///   Handles the <see cref = "JoinRequest" /> to enter a <see cref = "Game" />.
        ///   This method removes the peer from any previously joined room, finds the room intended for join
        ///   and enqueues the operation for it to handle.
        /// </summary>
        /// <param name = "operationRequest">
        ///   The operation request to handle.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        protected virtual void HandleJoinGameOperation(OperationRequest operationRequest, SendParameters sendParameters)
        {
            // create join operation
            var joinRequest = new JoinGameRequest(this.Protocol, operationRequest);
            if (this.ValidateOperation(joinRequest, sendParameters) == false)
            {
                return;
            }

            // remove peer from current game
            this.RemovePeerFromCurrentRoom();

            // try to get the game reference from the game cache 
            RoomReference gameReference;
            if (joinRequest.CreateIfNotExists)
            {
                gameReference = this.GetOrCreateRoom(joinRequest.GameId);
            }
            else
            {
                if (this.TryGetRoomReference(joinRequest.GameId, out gameReference) == false)
                {
                    this.OnRoomNotFound(joinRequest.GameId);

                    var response = new OperationResponse
                    {
                        OperationCode = (byte)OperationCode.JoinGame,
                        ReturnCode = (short)ErrorCode.GameIdNotExists,
                        DebugMessage = "Game does not exists"
                    };

                    this.SendOperationResponse(response, sendParameters);
                    return;
                }
            }

            // save the game reference in the peers state                    
            this.RoomReference = gameReference;

            // finally enqueue the operation into game queue
            gameReference.Room.EnqueueOperation(this, operationRequest, sendParameters);
        }
        protected virtual void HandleCreateGameOperation(OperationRequest operationRequest, SendParameters sendParameters)
        {
            // The JoinRequest from the Lite application is also used for create game operations to support all feaures 
            // provided by Lite games. 
            // The only difference is the operation code to prevent games created by a join operation. 
            // On "LoadBalancing" game servers games must by created first by the game creator to ensure that no other joining peer 
            // reaches the game server before the game is created.
            var createRequest = new JoinGameRequest(this.Protocol, operationRequest);
            if (this.ValidateOperation(createRequest, sendParameters) == false)
            {
                return;
            }

            // remove peer from current game
            this.RemovePeerFromCurrentRoom();

            // try to create the game
            RoomReference gameReference;
            if (this.TryCreateRoom(createRequest.GameId, out gameReference) == false)
            {
                var response = new OperationResponse
                    {
                        OperationCode = (byte)OperationCode.CreateGame,
                        ReturnCode = (short)ErrorCode.GameIdAlreadyExists,
                        DebugMessage = "Game already exists"
                    };

                this.SendOperationResponse(response, sendParameters);
                return;
            }

            // save the game reference in the peers state                    
            this.RoomReference = gameReference;

            // finally enqueue the operation into game queue
            gameReference.Room.EnqueueOperation(this, operationRequest, sendParameters);
        }
Exemple #4
0
        protected override void ExecuteOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            try
            {
                if (Log.IsDebugEnabled)
                {
                    Log.DebugFormat("Executing operation {0}", operationRequest.OperationCode);
                }

                switch (operationRequest.OperationCode)
                {
                    case (byte)OperationCode.CreateGame:
                        var createGameRequest = new JoinGameRequest(peer.Protocol, operationRequest);
                        if (peer.ValidateOperation(createGameRequest, sendParameters) == false)
                        {
                            return;
                        }

                        if (this.LogQueue.Log.IsDebugEnabled)
                        {

                            this.LogQueue.Add(
                                new LogEntry(
                                    "ExecuteOperation: " + (OperationCode)operationRequest.OperationCode,
                                    "Peer=" + peer.ConnectionId));
                        }
                        this.HandleCreateGameOperation(peer, createGameRequest, sendParameters);
                        break;

                    case (byte)OperationCode.JoinGame:
                        var joinGameRequest = new JoinRequest(peer.Protocol, operationRequest);
                        if (peer.ValidateOperation(joinGameRequest, sendParameters) == false)
                        {
                            return;
                        }

                        if (this.LogQueue.Log.IsDebugEnabled)
                        {

                            this.LogQueue.Add(
                                new LogEntry(
                                    "ExecuteOperation: " + (OperationCode)operationRequest.OperationCode,
                                    "Peer=" + peer.ConnectionId));
                        }
                        this.HandleJoinGameOperation(peer, joinGameRequest, sendParameters);
                        break;

                    // Lite operation code for join is not allowed in load balanced games.
                    case (byte)Lite.Operations.OperationCode.Join:
                        var response = new OperationResponse
                            {
                                OperationCode = operationRequest.OperationCode,
                                ReturnCode = (short)ErrorCode.OperationDenied,
                                DebugMessage = "Invalid operation code"
                            };
                        peer.SendOperationResponse(response, sendParameters);
                        break;

                    case (byte)OperationCode.DebugGame:
                        var debugGameRequest = new DebugGameRequest(peer.Protocol, operationRequest);
                        if (peer.ValidateOperation(debugGameRequest, sendParameters) == false)
                        {
                            return;
                        }

                        if (this.LogQueue.Log.IsDebugEnabled)
                        {

                            this.LogQueue.Add(
                                new LogEntry(
                                    "ExecuteOperation: " + (OperationCode)operationRequest.OperationCode,
                                    "Peer=" + peer.ConnectionId));
                        }

                        this.HandleDebugGameOperation(peer, debugGameRequest, sendParameters);
                        break;

                    // all other operation codes will be handled by the Lite game implementation
                    default:
                        base.ExecuteOperation(peer, operationRequest, sendParameters);
                        break;
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
        protected virtual OperationResponse HandleJoinGame(MasterClientPeer peer, OperationRequest operationRequest)
        {
            // validate operation
            var operation = new JoinGameRequest(peer.Protocol, operationRequest);
            OperationResponse response;
            if (OperationHelper.ValidateOperation(operation, log, out response) == false)
            {
                return response;
            }

            // special handling for game properties send by AS3/Flash (Amf3 protocol) or JSON clients
            var protocol = peer.Protocol.ProtocolType;
            if (protocol == ProtocolType.Amf3V152 || protocol == ProtocolType.Json)
            {
                Utilities.ConvertAs3WellKnownPropertyKeys(operation.GameProperties, null);   
            }


            // try to find game by id
            GameState gameState;
            bool gameCreated = false;
            if (operation.CreateIfNotExists == false)
            {
                // The client does not want to create the game if it does not exists.
                // In this case the game must have been created on the game server before it can be joined.
                if (this.GameList.TryGetGame(operation.GameId, out gameState) == false || gameState.IsCreatedOnGameServer == false)
                {
                    return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameIdNotExists, DebugMessage = "Game does not exist" };
                }
            }
            else
            {
                // The client will create the game if it does not exists already.
                if (!this.GameList.TryGetGame(operation.GameId, out gameState))
                {
                    if (!this.TryCreateGame(operation, operation.GameId, true, operation.GameProperties, out gameCreated, out gameState, out response))
                    {
                        return response;
                    }
                }
            }

            // game properties have only be to checked if the game was not created by the client
            if (gameCreated == false)
            {
                // check if max players of the game is already reached
                if (gameState.MaxPlayer > 0 && gameState.PlayerCount >= gameState.MaxPlayer)
                {
                    return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameFull, DebugMessage = "Game full" };
                }

                // check if the game is open
                if (gameState.IsOpen == false)
                {
                    return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameClosed, DebugMessage = "Game closed" };
                }
            }

            // add peer to game
            gameState.AddPeer(peer);

            this.ScheduleCheckJoinTimeOuts();

            // publish operation response
            object joinResponse = this.GetJoinGameResponse(peer, gameState);
            return new OperationResponse(operationRequest.OperationCode, joinResponse);
        }
Exemple #6
0
        private void SetupGameProperties(LitePeer peer, JoinGameRequest createRequest, 
            Hashtable gameProperties, ref SendParameters sendParameters, out byte? newMaxPlayer, out bool? newIsOpen, out bool? newIsVisible, out object[] newLobbyProperties)
        {
            newMaxPlayer = null;
            newIsOpen = null;
            newIsVisible = null;
            newLobbyProperties = null;

            // special treatment for game and actor properties sent by AS3/Flash or JSON clients
            var protocol = peer.Protocol.ProtocolType;
            if (protocol == ProtocolType.Amf3V152 || protocol == ProtocolType.Json)
            {
                Utilities.ConvertAs3WellKnownPropertyKeys(createRequest.GameProperties, createRequest.ActorProperties);
            }

            // try to parse build in properties for the first actor (creator of the game)
            if (this.Actors.Count == 0)
            {
                if (gameProperties != null && gameProperties.Count > 0)
                {
                    if (!TryParseDefaultProperties(peer, createRequest, gameProperties, 
                        sendParameters, out newMaxPlayer, out newIsOpen, out newIsVisible, out newLobbyProperties))
                    {
                        return;
                    }
                }
            }
            return;
        }
Exemple #7
0
        protected virtual void HandleCreateGameOperationBody(LitePeer peer, JoinGameRequest 
            createRequest, SendParameters sendParameters, bool restored)
        {
            var gamePeer = (GameClientPeer)peer;

            byte? newMaxPlayer;
            bool? newIsOpen;
            bool? newIsVisible;
            object[] newLobbyProperties;
            Hashtable properties = createRequest.GameProperties;
            if (restored)
            {
                properties = Properties.GetProperties();

                /// we set it to null in order to prevent property update in HandleJoinOperation
                createRequest.GameProperties = null;
            }

            SetupGameProperties(peer, createRequest, properties,
                ref sendParameters, out newMaxPlayer, out newIsOpen, out newIsVisible, out newLobbyProperties);

            Actor actor = this.HandleJoinOperation(peer, createRequest, sendParameters);
            if (actor == null)
            {
                return ;
            }

            this.lobbyId = createRequest.LobbyName;
            this.lobbyType = (AppLobbyType)createRequest.LobbyType;

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("CreateGame: name={0}, lobyName={1}, lobbyType={2}", this.Name, this.lobbyId, this.lobbyType);
            }

            // set default properties
            if (newMaxPlayer.HasValue && newMaxPlayer.Value != this.maxPlayers)
            {
                this.maxPlayers = newMaxPlayer.Value;
            }

            if (newIsOpen.HasValue && newIsOpen.Value != this.isOpen)
            {
                this.isOpen = newIsOpen.Value;
            }

            if (newIsVisible.HasValue && newIsVisible.Value != this.isVisible)
            {
                this.isVisible = newIsVisible.Value;
            }

            if (newLobbyProperties != null)
            {
                this.lobbyProperties = new HashSet<object>(newLobbyProperties);
            }

            // update game state at master server            
            var peerId = gamePeer.PeerId ?? string.Empty;
            Hashtable gameProperties = this.GetLobbyGameProperties(properties);
            this.UpdateGameStateOnMaster(newMaxPlayer, newIsOpen, newIsVisible, newLobbyProperties, gameProperties, peerId);

            return;
        }
Exemple #8
0
        protected virtual Actor HandleCreateGameOperation(LitePeer peer, JoinGameRequest createRequest, SendParameters sendParameters)
        {
            if (!this.ValidateGame(peer, createRequest.OperationRequest, sendParameters)) 
            {
                return null; 
            }

            HandleCreateGameOperationBody(peer, createRequest, sendParameters, false);
            return null;
        }
        public OperationResponse HandleJoinGame(OperationRequest operationRequest, SendParameters sendParameters)
        {
            var joinGameRequest = new JoinGameRequest(this.Protocol, operationRequest);

            OperationResponse response;
            if (OperationHelper.ValidateOperation(joinGameRequest, log, out response) == false)
            {
                return response;
            }

            GameState gameState;
            if (this.Application.TryGetGame(joinGameRequest.GameId, out gameState))
            {
                gameState.Lobby.EnqueueOperation(this, operationRequest, sendParameters);
                return null;
            }

            if (joinGameRequest.CreateIfNotExists == false)
            {
                return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameIdNotExists, DebugMessage = "Game does not exist" };
            }

            AppLobby lobby;
            if (!this.Application.LobbyFactory.GetOrCreateAppLobby(joinGameRequest.LobbyName, (AppLobbyType)joinGameRequest.LobbyType, out lobby))
            {
                return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.OperationDenied, DebugMessage = "Lobby does not exist" };
            }

            lobby.EnqueueOperation(this, operationRequest, sendParameters);
            return null;
        }
        protected virtual OperationResponse HandleJoinGame(MasterClientPeer peer, OperationRequest operationRequest)
        {
            // validate operation
            var operation = new JoinGameRequest(peer.Protocol, operationRequest);
            OperationResponse response;
            if (OperationHelper.ValidateOperation(operation, log, out response) == false)
            {
                return response;
            }

            GameState gameState;

            // try to find game by id
            if (this.GameList.TryGetGame(operation.GameId, out gameState) == false)
            {
                return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameIdNotExists, DebugMessage = "Game does not exist" };
            }

            // check if max players of the game is already reached
            if (gameState.MaxPlayer > 0 && gameState.PlayerCount >= gameState.MaxPlayer)
            {
                return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameFull, DebugMessage = "Game full" };
            }

            // check if the game is open
            if (gameState.IsOpen == false)
            {
                return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameClosed, DebugMessage = "Game closed" };
            }

            // check if user is blocked by peers allready in the game
            if (gameState.IsBlocked(peer))
            {
                return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.UserBlocked, DebugMessage = "User is blocked" };
            }

            // add peer to game
            if (gameState.TryAddPeer(peer) == false)
            {
                return new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.UserBlocked, DebugMessage = "Already joined the specified game." };
            }

            // publish operation response
            object joinResponse = this.GetJoinGameResponse(peer, gameState);
            return new OperationResponse(operationRequest.OperationCode, joinResponse);
        }