private void HandleMessage(string message) //when a the server receives a message from the client { if (message.StartsWith("GET_CATE:")) { // asking for specific category string response = ""; message = message.Replace("GET_CATE:", ""); if (int.TryParse(message, out int id)) { LastCategoryRequested = id; if (Program.Database.AllCategories.TryGetValue(id, out Category cat)) { response = $"{cat.ID}:{cat.Prompt}"; this.Send("Cat:" + response); } } // dont respond if it is out of range. }/* else if (message.StartsWith("SET_CATE")) * { * message = message.Replace("SET_CATE", ""); * // expecting: ID:Username * * if(message.Contains(":")) * { * string[] options = message.Split(':'); * if(int.TryParse(options[0], out int id)) * { * if(Program.TryGetUser(options[1], out User voted)) * { * Program.Database.AddVoteFor(id, voted, this.User); * } * } * } * }*/ else if (message.StartsWith("SUBMIT:")) { // submit all votes. message = message.Replace("SUBMIT:", ""); //?? what is the format? SUBMIT:category;thing#category;thing ? // SUBMIT:male;female#male;female#male;female .... // the male;female pairs are in order, so we should just be able to increment a counter as we go thorugh each string rejectedReason = ""; UserVoteSubmit vote = new UserVoteSubmit(this.User); try { string[] cats = message.Split('#'); //categories for (int index = 0; index < cats.Length; index++) //go through every category { string thing = cats[index]; //?? a pair of male:female winners if (string.IsNullOrWhiteSpace(thing)) { continue; // but if we havnt given a winner for this category, it may be empty } string[] winners = thing.Split(';'); // these are "male;female", so yes string maleWin = winners[0]; string femaleWin = winners[1]; Program.TryGetUser(maleWin, out User firstWinner); Program.TryGetUser(femaleWin, out User secondWinner); if ((firstWinner?.AccountName ?? ",") == (secondWinner?.AccountName ?? "")) { rejectedReason = "Rejected:Duplicate"; return; // break out } if (firstWinner != null) { if (firstWinner.AccountName == this.User.AccountName) //trying to vote for themself { rejectedReason = "Rejected:Self"; } } if (secondWinner != null) { if (secondWinner.AccountName == this.User.AccountName) { rejectedReason = "Rejected:Self"; } } if (string.IsNullOrWhiteSpace(rejectedReason)) { vote.AddVote(index + 1, firstWinner, secondWinner); } } } catch (Exception ex) { rejectedReason = "Rejected:Errored"; Logging.Log($"{UserName}/Submit", ex); } finally { if (string.IsNullOrWhiteSpace(rejectedReason)) { var now = DateTime.Now; var ts = now - this.StartedTime; Program.Database.AlreadyVotedNames.Add(this.User.AccountName); vote.Submit(); this.Send("Accepted"); Logging.Log(Logging.LogSeverity.Warning, $"User has voted (took: {ts})", this.User.AccountName); } else { this.Send(rejectedReason); } this.Close("Submitted"); } } else if (message.StartsWith("QUERY")) //?? querying for what? - when user types in someone's name, query any student that contains that name { message = message.Replace("QUERY:", ""); string response = ""; // format: // ENTERED_TEXT // its substring(2) '2' because we need to ignore first M/F and the : var students = QueryStudent(message); foreach (var student in students) { response += student.ToString("AN:FN:LN:TT") + "#"; } this.Send("Q_RES:" + response); } else if (message.StartsWith("QUES:")) { try { message = message.Substring(5); } catch { } Logging.Log(Logging.LogSeverity.Severe, "Category: " + message, this.UserName); try { System.IO.File.AppendAllText($@"..\..\..\CategorySuggestions.txt", $"{this.UserName} - {message}\r\n"); } catch (Exception ex) { Logging.Log("SuggestFile", ex); } } else if (message.StartsWith("REPORT:")) { var report = BugReport.BugReport.Parse(message, this.User); Logging.Log(Logging.LogSeverity.Warning, $"NEW: {report.Primary ?? report.Additional}{(string.IsNullOrWhiteSpace(report.Primary) ? "" : " " + report.Additional)} @ {report.LogFile}" , $"Bugs/{report.Reporter.AccountName}"); Program.BugReports.Add(report); Program.SaveBugs(); } else if (message.StartsWith("/")) { // admin message message = message.Substring(1); if (message.StartsWith("CHAT:")) { message = message.Substring(5); Program.SendAdminChat(new AdminMessage(this, message)); } else if (message.StartsWith("QUEUE")) { var str = "/AQU:"; int num = 0; foreach (var s in ClientQueue) { num += 1; str += $"{s.User.AccountName}:{s.User.FirstName}:{s.User.LastName}:{s.User.Tutor}:{num}:{s.IPAddress}#"; } Send(str); } else if (message.StartsWith("VOTERS")) { var str = "/AVT:"; int num = 0; foreach (var s in CurrentClients) { num += 1; str += $"{s.User.AccountName}:{s.User.FirstName}:{s.User.LastName}:{s.User.Tutor}:{(int)s.Authentication}:{s.IPAddress}#"; } Send(str); } else if (message.StartsWith("KICK:")) { message = message.Substring("KICK:".Length); var split = message.Split(':'); if (Program.TryGetUser(split[0], out User user)) { var conn = AllClients.FirstOrDefault(x => x.User.AccountName == user.AccountName); if (conn != null) { if (conn.Authentication >= this.Authentication || conn.UserName == this.UserName) { return; // prevent kicking self or those with higher 'auth' } var kick = new Kick(conn, this.User, split[1]); if (Program.Options.Perm_Block_Kicked_Users) { PriorKickedUsers.Add(kick); } conn.Send("Kicked:" + kick.Reason); AdminMessage msg = new AdminMessage("Server", Authentication.Sysadmin, $"[STATUS] {kick.Kicked.AccountName} was kicked by {kick.Admin.AccountName} for {kick.Reason}"); Program.SendAdminChat(msg); conn.Close($"Kicked by {kick.Admin.AccountName} with reason {kick.Reason}"); } } } else if (message.StartsWith("MANR:")) { message = message.Replace("MANR:", ""); if (Program.TryGetUser(message, out User user)) { string response = "/MANRD:"; foreach (var category in Program.Database.AllCategories.Values) { var votes = category.GetVotesBy(user); response += $"{votes.Item1?.ToString("AN:FN:LN:TT") ?? ""};{votes.Item2?.ToString("AN:FN:LN:TT") ?? ""}#"; } Send(response); } } else if (message.StartsWith("MANVOTE:")) { message = message.Replace("MANVOTE:", ""); var split = message.Split(':'); if (Program.Database.AllStudents.TryGetValue(split.ElementAt(0), out User user)) { int categoryId = 1; var votes = split.ElementAt(1).Split('#').Where(x => !string.IsNullOrWhiteSpace(x)); foreach (string vote in votes) { var each = vote.Split(';'); Program.TryGetUser(each.ElementAt(0), out User first); Program.TryGetUser(each.ElementAt(1), out User second); if (first != null) { Program.Database.AddVoteFor(categoryId, first, user); } if (second != null) { Program.Database.AddVoteFor(categoryId, second, user); } categoryId++; } } } else if (message.StartsWith("QUERY:")) { message = message.Replace("QUERY:", ""); var split = message.Split(':').Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); var rowIndex = int.Parse(split[0]); var colIndex = int.Parse(split[1]); var queryT = split[2]; var students = QueryStudent(queryT); if (students.Count == 1) { Send($"/QUERY:{rowIndex}:{colIndex}:{students[0].ToString("AN;FN;LN;TT")}"); } } } }