/// <summary> /// Invoked when a new client joins the system /// </summary> public void Joined() { // 1: Add user to list of connected users // 2: If waiting list is empty add user to waiting list // 3: Else find an opponent (first in the waiting list) and remove him from the waiting list // 4: Create room and assign both users // 5: Create a group for this room // 6: Setup match (playRoom Id, initial ball direction, player on the left and right etc...) // 7: Notify the group the match can start // 8: Add the game to the list of games that the Engine must simulate var user = new User() { Id = Context.ConnectionId, Username = Caller.username }; _userRepository.AddUser(user); if (_userRepository.WaitingList.Count() == 0) { _userRepository.AddToWaitingList(user); Caller.wait(); } else { var opponent = _userRepository.WaitingList.First(); _userRepository.RemoveFromWaitingList(opponent); var playRoom = new PlayRoom() { Id = Guid.NewGuid().ToString(), Player1 = opponent, Player2 = user }; _roomRepository.Add(playRoom); Task t1 = Groups.Add(opponent.Id, playRoom.Id); Task t2 = Groups.Add(user.Id, playRoom.Id); t1.Wait(); t2.Wait(); // Rough solution. We have to be sure the clients have received the group add messages over the wire // TODO: ask maybe on Jabbr or on StackOverflow and think about a better solution Thread.Sleep(3000); Player player1 = Engine.CreatePlayer(playRoom.Player1, 1, true); Player player2 = Engine.CreatePlayer(playRoom.Player2, 2, false); Game game = Engine.CreateGame(playRoom.Id, player1, player2); dynamic matchOptions = new ExpandoObject(); matchOptions.PlayRoomId = playRoom.Id; matchOptions.Player1 = playRoom.Player1; matchOptions.Player2 = playRoom.Player2; matchOptions.BallDirection = game.Ball.Direction; Clients[playRoom.Id].setupMatch(matchOptions); Thread.Sleep(3000); Engine.AddGame(game); } }