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); }
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); }
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; }
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; }
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); }