public async Task SendMessage(string group, string message) { if (string.IsNullOrWhiteSpace(message)) { return; } // todo there is a corner case with only 1 player where the end will not end by answering the right answer // the reason is that the round is over but the detection logic does not catch that try { // get username GroupDetails.TryGetUsername(group, Context.ConnectionId, out string username); // check if we are in a round, and if so then check if this is a valid guess GroupDetails.TryGetInRound(group, out bool inround, out bool atendofround, out RoundDetails round); if (inround && round != null) { // check if this guess is currect if (message.IndexOf(round.Word, StringComparison.OrdinalIgnoreCase) >= 0) { // cannot guess for your own question or if you have already gotten it right if (!atendofround) { if (GroupDetails.TryGetHasAnswered(group, Context.ConnectionId, out bool answered) && !answered) { // give credit GroupDetails.AddToScore(group, Context.ConnectionId, (float)(round.End - DateTime.UtcNow).TotalSeconds); // mark that you answered GroupDetails.SetHasAnswered(group, Context.ConnectionId); } // check again GroupDetails.TryGetInRound(group, out inround, out atendofround, out round); } // remove the correct word from the phrase message = message.Replace(round.Word, "correct :)", StringComparison.OrdinalIgnoreCase); } } // send the message to everyone in this group await Clients.Group(group).SendAsync("ReceiveMessage", $"{username}: {message}"); // finish early if done if (atendofround) { await SendRoundComplete(group); } } catch (Exception e) { await Clients.Group(group).SendAsync("ReceiveMessage", $"failed to send message: {e.Message}"); } }
public async Task SendRoundComplete(string group) { try { // this method is callable by any connection GroupDetails.TryGetInRound(group, out bool inround, out bool atendofround, out RoundDetails round); // stop round GroupDetails.SetInRound(group, inround: false); // send a round done notification await Clients.Group(group).SendAsync("ReceiveRoundComplete", round != null ? round.Word : ""); // refresh the user list (with scores) await Clients.Group(group).SendAsync("ReceiveJoin", GetSortedUsers(GroupDetails.GetUsers(group))); } catch (Exception e) { await Clients.Group(group).SendAsync("ReceiveMessage", $"failed to complete round: {e.Message}"); } }
public async Task SendClear(string group) { try { // ensure this person is the drawer GroupDetails.TryGetInRound(group, out bool inround, out bool atendofround, out RoundDetails round); // exit if this client is not allowed to draw across all the screens if (!inround || atendofround || !string.Equals(Context.ConnectionId, round.ConnectionId, StringComparison.OrdinalIgnoreCase)) { return; } // send clear to everyone in this group await Clients.OthersInGroup(group).SendAsync("ReceiveClear"); } catch (Exception e) { await Clients.Group(group).SendAsync("ReceiveMessage", $"failed to clear: {e.Message}"); } }
public async Task SendLine(string group, double x1, double y1, double x2, double y2, string color, float diameter) { try { // ensure this person is the drawer GroupDetails.TryGetInRound(group, out bool inround, out bool atendofround, out RoundDetails round); // exit if this client is not allowed to draw across all the screens if (!inround || atendofround || !string.Equals(Context.ConnectionId, round.ConnectionId, StringComparison.OrdinalIgnoreCase)) { return; } // send the point to everyone (except the sender) in this group await Clients.OthersInGroup(group).SendAsync("ReceiveLine", x1, y1, x2, y2, color, diameter); } catch (Exception e) { await Clients.Group(group).SendAsync("ReceiveMessage", $"failed to send line: {e.Message}"); } }
public async Task SendJoin(string group, string username) { try { // associate username with group if (!GroupDetails.AddUser(group: group, connectionId: Context.ConnectionId, username)) { await Clients.Group(group).SendAsync("ReceiveMessage", $"failed to add {username}"); return; } // associate connection with group await Groups.AddToGroupAsync(Context.ConnectionId, group); // broadcast current players to everyone in the group await Clients.Group(group).SendAsync("ReceiveJoin", GetSortedUsers(GroupDetails.GetUsers(group))); // check if a round is in flight GroupDetails.TryGetInRound(group, out bool inround, out bool atendofround, out RoundDetails round); if (inround && !atendofround && round != null) { await Clients.Client(Context.ConnectionId).SendAsync("ReceiveNextRound", round.Username, round.Timeout, round.ObfuscatedWord, false /* candraw */); return; } // make sure the player get the game start notification if (GroupDetails.IsGroupStarted(group)) { // send the game start inidcator await Clients.Client(Context.ConnectionId).SendAsync("ReceiveStartGame"); } } catch (Exception e) { await Clients.Group(group).SendAsync("ReceiveMessage", $"failed to join game: {e.Message}"); } }