/// <summary>
        /// Handles the request after all relevant info has been parsed out
        /// </summary>
        /// <param name="line"></param>
        /// <param name="p"></param>
        private void ProcessRequest(string line, object p = null)
        {
            String result = "";

            // this handles 'make user' request
            if (makeUserPattern.IsMatch(firstLine))
            {
                UserNickames name = JsonConvert.DeserializeObject <UserNickames>(line);
                dynamic      user = new BoggleService().Register(name, out HttpStatusCode status);
                result = ComposeResponse(user, status);
            }
            // this handles 'join game' request
            else if (joinGamePattern.IsMatch(firstLine))
            {
                GameRequest  request  = JsonConvert.DeserializeObject <GameRequest>(line);
                JoinResponse response = new BoggleService().Join(request, out HttpStatusCode status);
                result = ComposeResponse(response, status);
            }
            // this handles 'update game status' with brief parameter on or off
            else if (updateNoBriefPattern.IsMatch(firstLine) || updateBriefPattern.IsMatch(firstLine))
            {
                Match  m;
                string gameID     = "";
                string briefParam = null;
                string brief      = "";

                // if brief parameter is not provided
                if (updateNoBriefPattern.Match(firstLine).Success)
                {
                    m      = updateNoBriefPattern.Match(firstLine);
                    gameID = m.Groups[1].ToString();
                }

                // or not provided, parse brief parameter
                if (updateBriefPattern.Match(firstLine).Success)
                {
                    m = updateBriefPattern.Match(firstLine);

                    // game ID is embedded in first group of regex pattern
                    gameID = m.Groups[1].ToString();

                    // brief parameter is embedded in second group of regex pattern
                    briefParam = m.Groups[2].ToString();

                    // remove irrelevent strings
                    brief = briefParam.Substring(7);
                }

                GameStatus     response;
                HttpStatusCode status;
                if (briefParam == null)
                {
                    response = new BoggleService().Update(gameID, "No", out status);
                }
                else
                {
                    response = new BoggleService().Update(gameID, brief, out status);
                }

                result = ComposeResponse(response, status);
            }
            // this handles playword request
            else if (playWordPattern.IsMatch(firstLine))
            {
                string       gameID   = playWordPattern.Match(firstLine).Groups[1].ToString();
                PlayRequest  request  = JsonConvert.DeserializeObject <PlayRequest>(line);
                PlayResponse response = new BoggleService().PlayWord(request, gameID, out HttpStatusCode status);
                result = ComposeResponse(response, status);
            }
            // this handles cancel game request
            else if (cancelPattern.IsMatch(firstLine))
            {
                UserObject user = JsonConvert.DeserializeObject <UserObject>(line);
                new BoggleService().CancelJoinRequest(user, out HttpStatusCode status);
                result = ComposeResponse(null, status);
            }
            // capturing whatever string requests that does not match any of the above regex patterns
            else
            {
                result = "HTTP/1.1 " + "403" + " Forbidden" + "\r\n\r\n";
            }
            socket.BeginSend(result, (x, y) => { socket.Shutdown(SocketShutdown.Both); }, null);
        }
Пример #2
0
        /// <summary>
        /// Join a game as either the first or second player.
        /// </summary>
        public Game JoinGame(GameRequest data)
        {
            // Validate incoming data
            if (data.UserToken == null || data.TimeLimit < 5 || data.TimeLimit > 120)
            {
                SetStatus(Forbidden);
                return(null);
            }

            using (SqlConnection conn = new SqlConnection(BoggleDB))
            {
                conn.Open();
                SqlTransaction trans = conn.BeginTransaction();

                try
                {
                    // Validate the incoming UserToken
                    SqlCommand command = new SqlCommand("select UserToken from Users where UserToken=@UserToken", conn, trans);
                    command.Parameters.AddWithValue("@UserToken", data.UserToken);
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        if (!reader.Read())
                        {
                            SetStatus(Forbidden);
                            return(null);
                        }
                    }

                    // See if there's a pending game, and get its gameID, player token, and timeLimit if so.
                    long   gameID       = 0;
                    string player1Token = null;
                    int    timeLimit    = 0;

                    command = new SqlCommand("select GameID, Player1, TimeLimit from Games where Player2 is null", conn, trans);
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            gameID       = (long)reader["GameID"];
                            player1Token = (string)reader["Player1"];
                            timeLimit    = (int)reader["TimeLimit"];
                        }
                    }

                    // There is a pending game
                    if (player1Token != null)
                    {
                        // Validate the incoming UserToken by making sure it is different from player1Token
                        if (player1Token == data.UserToken)
                        {
                            SetStatus(Conflict);
                            return(null);
                        }

                        // Convert the pending game into an active game
                        else
                        {
                            command = new SqlCommand("update Games set Player2=@Player2, Board=@Board, StartTime=@StartTime, TimeLimit=@TimeLimit where GameID=@GameID", conn, trans);
                            command.Parameters.AddWithValue("@Player2", data.UserToken);
                            command.Parameters.AddWithValue("@Board", BoggleBoard.GenerateBoard());
                            command.Parameters.AddWithValue("@TimeLimit", (timeLimit + data.TimeLimit) / 2);
                            command.Parameters.Add("@StartTime", SqlDbType.DateTime).Value = DateTime.Now;
                            command.Parameters.AddWithValue("@GameID", gameID);
                            command.ExecuteNonQuery();

                            // Report the GameID of the new active game
                            SetStatus(Created);
                            return(new Game()
                            {
                                GameID = gameID.ToString()
                            });
                        }
                    }

                    // There is no pending game
                    else
                    {
                        // Create a new pending game
                        command = new SqlCommand("insert into Games (Player1, TimeLimit) output inserted.GameID values(@Player1, @TimeLimit)", conn, trans);
                        command.Parameters.AddWithValue("@Player1", data.UserToken);
                        command.Parameters.AddWithValue("@TimeLimit", data.TimeLimit);
                        SetStatus(Accepted);
                        return(new Game()
                        {
                            GameID = command.ExecuteScalar().ToString()
                        });
                    }
                }
                catch (Exception)
                {
                    trans.Rollback();
                    SetStatus(InternalServerError);
                    return(null);
                }
                finally
                {
                    if (trans.Connection != null)
                    {
                        trans.Commit();
                    }
                }
            }
        }