/// <summary> /// Handles connecting player message. /// </summary> /// <param name="msg">Annoted player request.</param> protected virtual void ConnectPlayer(AnnotedPlayerRequest msg) { // Check if it good time if (Executor.CurrentPhase != GamePhase.BEFORE_START && !_Loaded) { throw new WrongGamePhaseException(); } // Check if there is empty seat if (_PlayerLimit == PlayersInGame.Count) { throw new PlayerLimitException(); } // Check if color is enabled for the game if (!_EnabledColors.Contains(msg.Request.Color)) { throw new ColorDisabledException(); } // Check if color is already selected if (PlayersInGame.ContainsKey(msg.Request.Color)) { throw new ColorAlreadySelectedException(); } // Check if client is already connected if (PlayersInGame.ContainsValue(msg.HandlerSocket)) { throw new AlreadyConnectedException(); } // Connect the player PlayersInGame.Add(msg.Request.Color, msg.HandlerSocket); PlayersNames.Add(msg.Request.Color, msg.Request.Name); PlayerConnected.Invoke(msg.Request.Color, msg.Request.Name, msg.HandlerSocket); }
/// <summary> /// Loop for handling messages. /// </summary> public void MessageHandlingLoop() { try { // Inifinite loop while (true) { // Waiting for any message HasMessageResetEvent.Wait(); lock (MessageHandlerThread) { HasMessageResetEvent.Reset(); // Handle all messages while (true) { // Get next message AnnotedPlayerRequest msg = Socket.GetNextMessage(); // Finish when no message to handle if (msg == null) { break; } PlayerRequest rqst = msg.Request; GameExecutionResult result = GameExecutionResult.NONE; // Check if player should be known when making the request if (rqst.Type != PlayerRequestType.CONNECT && rqst.Type != PlayerRequestType.DISCONNECT && !(PlayersInGame.TryGetValue(rqst.Color, out ClientHandlerSocket realSocket) && realSocket == msg.HandlerSocket)) { result = GameExecutionResult.ERR_UNKNOWN_PLAYER; } else { result = GameExecutionResult.OK; try { switch (rqst.Type) { case PlayerRequestType.CONNECT: ConnectPlayer(msg); break; case PlayerRequestType.FOLLOWER_PLACEMENT: Executor.PlaceFollower(rqst.Color, rqst.Coords, rqst.RegionId); break; case PlayerRequestType.FOLLOWER_REMOVEMENT: Executor.RemoveFollower(rqst.Color, rqst.Coords); break; case PlayerRequestType.NO_FOLLOWER_PLACEMENT: Executor.NoFollowerPlacement(rqst.Color); break; case PlayerRequestType.TILE_PLACEMENT: Executor.PlaceTile(rqst.Color, rqst.Scheme, rqst.Coords, rqst.Orientation); break; case PlayerRequestType.DISCONNECT: msg.HandlerSocket.Stop(); Socket_ClientDisconnected(msg.HandlerSocket); result = GameExecutionResult.NONE; break; default: result = GameExecutionResult.ERROR; break; } } catch (GameException ex) { result = ex.ToExecutionResult(); } if (result != GameExecutionResult.NONE) { msg.HandlerSocket.SendMessage(new ServerResponse() { Type = ServerResponseType.EXECUTION_REQUEST_RESULT, Request = rqst, ExecutionResult = result }); } } } } } } catch (ThreadAbortException) { } }