//method: GetSpreadSheet //description: retrieves spread sheet information //params: none //returns: void public void GetSpreadSheet() { if(stopped) return; Task.Factory.StartNew(() => { try { lock (socketLock) { writer.WriteLine("GET_SPREADSHEET"); writer.Flush(); List<SpreadsheetRow> rows = new List<SpreadsheetRow>(); while(reader.PeekLine() != "DONE") { SpreadsheetRow r = new SpreadsheetRow(); r.questionNumber = int.Parse(reader.ReadLine()); r.questionText = reader.ReadLine(); r.averageTimeToAnswer = int.Parse(reader.ReadLine()); r.percentageCorrect = int.Parse(reader.ReadLine()); rows.Add(r); } string writerDump = reader.ReadLine(); //dump for "DONE" string from server owner.Invoke((MethodInvoker)( () => { SpreadsheetReceived(this, rows); } )); } } catch(Exception) { stopped = true; socket.Close(); owner.Invoke((MethodInvoker)(() => { ConnectionLost(this, new EventArgs()); })); } }); }
//method: AdminSession //description: establishes a new admin session //params: TcpClient client - client // StreamReader reader - reader // StreamWriter writer - writer //returns: void private void AdminSession(TcpClient client, StreamReader reader, StreamWriter writer) { while (!stopped) { //loop and wait for the admin page to send a task Task<string> readTask = reader.ReadLineAsync(); do { if (stopped) { client.Close(); return;//exit method } Thread.Sleep(CHECK_MSG_INTVL); } while (!readTask.IsCompleted); if (readTask.IsFaulted) { client.Close(); return;//exit method } if (readTask.Result == "GET_QUESTION") { int questionNum = 0; List<Question> questions = new List<Question>(); //get question number readTask = reader.ReadLineAsync(); do { if (stopped) { client.Close(); return;//exit method } Thread.Sleep(CHECK_MSG_INTVL); } while (!readTask.IsCompleted); if (readTask.IsFaulted) { client.Close(); return;//exit method } questionNum = int.Parse(readTask.Result); using (MySqlConnection dbConnection = new MySqlConnection(CON_STR)) { dbConnection.Open(); //get questions string questionCmdStr = "SELECT * FROM question WHERE QuestionNumber = " + questionNum; MySqlCommand questionCmd = new MySqlCommand(questionCmdStr, dbConnection); using (MySqlDataReader questionRdr = questionCmd.ExecuteReader()) { while (questionRdr.Read()) { Question q = new Question(); q.questionStr = (string)questionRdr[1]; questions.Add(q); } } //get answers for (int i = 0; i < questions.Count(); i++) { string answerCmdStr = "SELECT AnswerText, IsCorrect FROM answer WHERE QuestionNumber = " + questionNum; MySqlCommand answerCmd = new MySqlCommand(answerCmdStr, dbConnection); questions[i].answers = new List<Tuple<string, bool>>(); using (MySqlDataReader answerRdr = answerCmd.ExecuteReader()) { while (answerRdr.Read()) { questions[i].answers.Add(new Tuple<string, bool>( (string)answerRdr[0], (bool)answerRdr[1] )); } } } for (int i = 0; i < questions.Count; i++) { try { //send question writer.WriteLine("QUESTION:" + questions[i].questionStr); //send answers for (int j = 0; j < questions[i].answers.Count; j++) { writer.WriteLine("ANSWER:" + questions[i].answers[j].Item1); writer.WriteLine("ISCORRECT:" + questions[i].answers[j].Item2); } //write something for the reader to peek at writer.WriteLine("DONE"); writer.Flush(); } catch (IOException) { client.Close(); return; } } } } else if (readTask.Result == "GET_USERS") { try { lock (connectedUsersLock) { for(int i = 0; i < connectedUsers.Count(); i++) { writer.WriteLine("USER:"******"DONE"); writer.Flush(); } catch (IOException) { client.Close(); return; } } else if (readTask.Result == "ADD_QUESTION") { int questionNum = 0; Question q = new Question(); q.answers = new List<Tuple<string, bool>>(); List<string> oldAnswers = new List<string>(); string oldAnswerText = ""; string answerText = ""; bool isCorrect = false; //get question number readTask = reader.ReadLineAsync(); do { if (stopped) { client.Close(); return;//exit method } Thread.Sleep(CHECK_MSG_INTVL); } while (!readTask.IsCompleted); if (readTask.IsFaulted) { client.Close(); return;//exit method } questionNum = int.Parse(readTask.Result); //get question text readTask = reader.ReadLineAsync(); do { if (stopped) { client.Close(); return;//exit method } Thread.Sleep(CHECK_MSG_INTVL); } while (!readTask.IsCompleted); if (readTask.IsFaulted) { client.Close(); return;//exit method } q.questionStr = readTask.Result; //get old answer text readTask = reader.ReadLineAsync(); do { if (stopped) { client.Close(); return;//exit method } Thread.Sleep(CHECK_MSG_INTVL); } while (!readTask.IsCompleted); if (readTask.IsFaulted) { client.Close(); return;//exit method } //loop to get old answer text while (readTask.Result.StartsWith("OLDANSWER:")) { oldAnswerText = readTask.Result.Substring("OLDANSWER:".Length); oldAnswers.Add(oldAnswerText); //get next old answer readTask = reader.ReadLineAsync(); do { if (stopped) { client.Close(); return;//exit method } Thread.Sleep(CHECK_MSG_INTVL); } while (!readTask.IsCompleted); if (readTask.IsFaulted) { client.Close(); return;//exit method } } while (readTask.Result.StartsWith("ANSWER:")) { answerText = readTask.Result.Substring("ANSWER:".Length); //get if the anwser is correct or not readTask = reader.ReadLineAsync(); do { if (stopped) { client.Close(); return;//exit method } Thread.Sleep(CHECK_MSG_INTVL); } while (!readTask.IsCompleted); if (readTask.IsFaulted) { client.Close(); return;//exit method } if (readTask.Result.StartsWith("ISCORRECT:")) { isCorrect = Convert.ToBoolean(readTask.Result.Substring("ISCORRECT:".Length)); q.answers.Add(new Tuple<string, bool>(answerText, isCorrect)); } //get next answer readTask = reader.ReadLineAsync(); do { if (stopped) { client.Close(); return;//exit method } Thread.Sleep(CHECK_MSG_INTVL); } while (!readTask.IsCompleted); if (readTask.IsFaulted) { client.Close(); return;//exit method } } using (MySqlConnection dbConnection = new MySqlConnection(CON_STR)) { dbConnection.Open(); string questionUpdateCmdString = "UPDATE question SET QuestionNumber = " + questionNum + ", QuestionText = '" + q.questionStr + "' WHERE QuestionNumber = " + questionNum; MySqlCommand questionUpdateCmd = new MySqlCommand(questionUpdateCmdString, dbConnection); questionUpdateCmd.ExecuteNonQuery(); for (int i = 0; i < q.answers.Count(); i++) { string answerUpdateCmdString = "UPDATE answer SET AnswerText = '" + q.answers[i].Item1 + "' , IsCorrect = " + q.answers[i].Item2 + " WHERE QuestionNumber = " + questionNum + " AND AnswerText = '" + oldAnswers[i] + "'"; MySqlCommand answerUpdateCmd = new MySqlCommand(answerUpdateCmdString, dbConnection); answerUpdateCmd.ExecuteNonQuery(); } } } else if (readTask.Result == "GET_SPREADSHEET") { using (MySqlConnection dbConnection = new MySqlConnection(CON_STR)) { dbConnection.Open(); List<SpreadsheetRow> rows = new List<SpreadsheetRow>(); //get questions string questionCmdStr = "SELECT * FROM question ORDER BY QuestionNumber"; MySqlCommand questionCmd = new MySqlCommand(questionCmdStr, dbConnection); using (MySqlDataReader rdr = questionCmd.ExecuteReader()) { while (rdr.Read()) { SpreadsheetRow r = new SpreadsheetRow(); r.questionNumber = int.Parse((rdr[0].ToString())); r.questionText = rdr[1].ToString(); rows.Add(r); } } //get user info for questions foreach(SpreadsheetRow r in rows) { questionCmdStr = "SELECT TimeToAnswer FROM userAnswer Where QuestionNumber = " + r.questionNumber; questionCmd = new MySqlCommand(questionCmdStr, dbConnection); using(MySqlDataReader rdr = questionCmd.ExecuteReader()) { int totalTimeToAnswer = 0; int totalCorrect = 0; int total = 0; while(rdr.Read()) { if(rdr[0] != DBNull.Value) {//answer was correct totalTimeToAnswer += int.Parse(rdr[0].ToString()); totalCorrect += 1; } total += 1; } if(totalCorrect == 0) { r.averageTimeToAnswer = 0; } else { r.averageTimeToAnswer = (int)((totalTimeToAnswer/(float)totalCorrect) + .5); } if(total == 0) { r.percentageCorrect = 0; } else { r.percentageCorrect = (int)((totalCorrect/(float)total) * 100 + .5); } } } //send to admin try { foreach(SpreadsheetRow r in rows) { writer.WriteLine(r.questionNumber); writer.WriteLine(r.questionText); writer.WriteLine(r.averageTimeToAnswer); writer.WriteLine(r.percentageCorrect); writer.Flush(); } writer.WriteLine("DONE"); writer.Flush(); } catch(IOException) { client.Close(); return;//exit method } } } else if(readTask.Result == "GET_LEADERBOARD") { try { SendLeaderboard(writer); writer.WriteLine("DONE"); writer.Flush(); } catch(IOException) { client.Close(); return;//exit method } } } }