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