コード例 #1
0
        public string JoinGame(JoinRequest joinRequest)
        {
            lock (sync)
            {
                string userToken = joinRequest.UserToken;
                int    timeLimit = joinRequest.TimeLimit;

                //A user token is valid if it is non - null and identifies a user. Time must be between 5 and 120.
                if (userToken == null || !users.ContainsKey(userToken) || timeLimit < 5 || timeLimit > 120)
                {
                    SetStatus(Forbidden);
                    return(null);
                }
                // Check if user is already in pending game.
                else if (games[gameID].Player1Token == userToken || games[gameID].Player2Token == userToken)
                {
                    SetStatus(Conflict);
                    return(null);
                }

                // If player 1 is taken, user is player 2
                if (games[gameID].Player1Token != null && games[gameID].Player2Token == null)
                {
                    string GameID = gameID.ToString();


                    games[gameID].Player2Token = userToken;
                    StartPendingGame(timeLimit);

                    SetStatus(Created);
                    return(GameID);
                }
                // if player 2 is taken, user is player 1
                else if (games[gameID].Player2Token != null && games[gameID].Player1Token == null)
                {
                    string GameID = gameID.ToString();

                    games[gameID].Player1Token = userToken;
                    StartPendingGame(timeLimit);

                    SetStatus(Created);
                    return(GameID);
                }
                // if user is first to enter pending game
                else
                {
                    string GameID = gameID.ToString();

                    games[gameID].Player1Token = userToken;
                    games[gameID].TimeLimit    = timeLimit;

                    SetStatus(Accepted);
                    return(GameID);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Attempts to join a game with user userToken and timeLimit
        ///
        /// If UserToken is invalid, TimeLimit is less than 5, or TimeLimit is over 120, responds
        /// with status 403 (Forbidden).
        ///
        /// Otherwise, if UserToken is already a player in the pending game, responds with status
        /// 409 (Conflict).
        ///
        /// Otherwise, if there is already one player in the pending game, adds UserToken as the
        /// second player. The pending game becomes active. The active game's time limit is the integer
        /// average of the time limits requested by the two players. Returns the new active game's
        /// GameID (which should be the same as the old pending game's GameID). Responds with
        /// status 201 (Created).
        ///
        /// Otherwise, adds UserToken as the first player of a new pending game, and the TimeLimit as
        /// the pending game's requested time limit. Returns the pending game's GameID. Responds with
        /// status 202 (Accepted).
        /// </summary>
        public GameIDResponse JoinGame(JoinRequest request, out HttpStatusCode status)
        {
            int timeLimit = request.TimeLimit;

            // make sure TimeLimit is within the expected bounds
            if (!(timeLimit >= 5 && timeLimit <= 120))
            {
                status = Forbidden;
                return(null);
            }

            //null checks
            if (request is null || request.UserToken is null)
            {
                status = Forbidden;
                return(null);
            }

            // the UserID that'll be used throughout this method
            string userID = request.UserToken.Trim();

            // make sure UserToken is within the expected bounds
            if (userID == null || userID.Length == 0 || userID.Length > 36)
            {
                status = Forbidden;
                return(null);
            }

            // open connection to database
            using (SqlConnection connection = new SqlConnection(BoggleDB))
            {
                connection.Open();

                // execute all commands within a single transaction
                using (SqlTransaction transaction = connection.BeginTransaction())
                {
                    // todo: make sure GameID starts at 1, not 0
                    // (otherwise, this should be changed, because this might actually end up as 0 when creating a game)
                    int gameID = -1;

                    // find out whether there's a pending game
                    using (SqlCommand command = new SqlCommand("select GameID, Player1, TimeLimit from Games where Player2 is null",
                                                               connection, transaction))
                    {
                        // the reader that will determine whether there's a pending game, and if so, what its gameID is
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                gameID = (int)reader["GameID"];
                                string player1 = (string)reader["Player1"];

                                // averages the time between player1's requested time and this user's requested time
                                int player1RequestedTime = (int)reader["TimeLimit"];
                                timeLimit = (timeLimit + player1RequestedTime) / 2;

                                // player is already searching for a game
                                if (player1 == userID)
                                {
                                    status = Conflict;
                                    reader.Close();
                                    transaction.Commit();
                                    return(null);
                                }
                            }
                        }
                    }

                    if (gameID == -1)
                    {
                        using (SqlCommand command = new SqlCommand("insert into Games (Player1, TimeLimit) output inserted.GameID values(@Player1, @TimeLimit)", connection, transaction))
                        {
                            command.Parameters.AddWithValue("@Player1", userID);
                            command.Parameters.AddWithValue("@TimeLimit", timeLimit);

                            SqlParameter outputparam = new SqlParameter("@GameID", SqlDbType.Int)
                            {
                                Direction = ParameterDirection.Output
                            };

                            command.Parameters.Add(outputparam);

                            // execute command, and get back the primary key (GameID)
                            try
                            {
                                gameID = (int)command.ExecuteScalar();
                            }
                            //If an exception was thrown, a foreign key pair was violated
                            catch (SqlException)
                            {
                                status = Forbidden;
                                transaction.Commit();
                                return(null);
                            }
                            status = Accepted;
                        }
                    }
                    else
                    {
                        using (SqlCommand command = new SqlCommand("update Games set Player2 = @Player2, Board = @Board, TimeLimit = @TimeLimit, StartTime = @StartTime where GameID = @GameID", connection, transaction))
                        {
                            command.Parameters.AddWithValue("@Player2", userID);
                            command.Parameters.AddWithValue("@Board", StaticBoard.GenerateBoggleBoard());
                            command.Parameters.AddWithValue("@TimeLimit", timeLimit);
                            command.Parameters.AddWithValue("@StartTime", DateTime.UtcNow);
                            command.Parameters.AddWithValue("@GameID", gameID);

                            try
                            {
                                if (command.ExecuteNonQuery() != 1)
                                {
                                    throw new Exception("SQL query failed");
                                }
                            }
                            //If Player2 is not a registered user
                            catch (SqlException)
                            {
                                status = Forbidden;
                                transaction.Commit();
                                return(null);
                            }

                            status = Created;
                        }
                    }

                    transaction.Commit();
                    return(new GameIDResponse {
                        GameID = gameID
                    });
                }
            }
        }
コード例 #3
0
        public gameID Join(JoinRequest Request)
        {
            if (Request.UserToken == null || Request.TimeLimit < 5 || Request.TimeLimit > 120)
            {
                SetStatus(Forbidden);
                return(null);
            }

            using (SqlConnection conn = new SqlConnection(BoggleDB))
            {
                conn.Open();
                using (SqlTransaction trans = conn.BeginTransaction())
                {
                    //Checking if UserToken exists in Users table.
                    using (SqlCommand command = new SqlCommand("select UserID from Users where UserID = @UserID", conn, trans))
                    {
                        command.Parameters.AddWithValue("@UserID", Request.UserToken);
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            if (!reader.HasRows)
                            {
                                SetStatus(Forbidden);
                                trans.Commit();
                                return(null);
                            }
                        }
                    }

                    bool player1 = false;
                    int  oldTime = 0;
                    //Checking if the UserToken is already in the pending game.
                    using (SqlCommand command = new SqlCommand("select Player1, TimeLimit from Games where Player1 is not null and Player2 is null", conn, trans))
                    {
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                if ((string)reader["Player1"] == Request.UserToken)
                                {
                                    SetStatus(Conflict);
                                    trans.Commit();
                                    return(null);
                                }
                                if ((int?)reader["TimeLimit"] != null)
                                {
                                    player1 = true;
                                    oldTime = (int)reader["TimeLimit"];
                                }
                            }
                        }
                    }
                    gameID ID = new gameID();
                    if (player1)
                    {
                        using (SqlCommand command = new SqlCommand("update Games set Player2 = @UserID, Board = @Board, TimeLimit = @TimeLimit, StartTime = @StartTime output inserted.GameID where Player2 is null", conn, trans))
                        {
                            command.Parameters.AddWithValue("@UserID", Request.UserToken);
                            command.Parameters.AddWithValue("@Board", new BoggleBoard().ToString());
                            command.Parameters.AddWithValue("@TimeLimit", (Request.TimeLimit + oldTime) / 2);
                            command.Parameters.AddWithValue("@StartTime", DateTime.Now);
                            ID.GameID = command.ExecuteScalar().ToString();
                            SetStatus(Created);
                            trans.Commit();
                            return(ID);
                        }
                    }
                    else
                    {
                        using (SqlCommand command = new SqlCommand("insert into Games (Player1, TimeLimit) output inserted.GameID values (@UserID, @TimeLimit)", conn, trans))
                        {
                            command.Parameters.AddWithValue("@UserID", Request.UserToken);
                            command.Parameters.AddWithValue("@TimeLimit", Request.TimeLimit);
                            ID.GameID = command.ExecuteScalar().ToString();
                            SetStatus(Accepted);
                            trans.Commit();
                            return(ID);
                        }
                    }
                }
            }
        }