/// <summary> /// Removes a vote that the client previously registered. /// </summary> /// <param name="c">The client whose vote to remove.</param> /// <returns>True on success, false otherwise.</returns> public bool UndoVote(Client c) { if (ActiveRound != null && ActiveRound.Votes.Where(v => v.EqualsClient(c)).Any()) { if (ActiveRound.Votes.Count >= Clients.Count) { return false; } else { ActiveRound.UndoVote(c); BroadcastGameState(); return true; } } else { return false; } }
/// <summary> /// Un-does a vote from a specific client. If the specified client didn't vote, this method does nothing. /// </summary> /// <param name="c">The client whose vote to remove.</param> public void UndoVote(Client c) { Votes.RemoveAll(v => v.EqualsClient(c)); }
/// <summary> /// Removes the specified client from the game, usually due to a disconnect. This also cleans up their votes and other game data. /// </summary> /// <param name="c">The client to remove.</param> public void RemoveClient(Client c) { // Remove this client's votes if they have any. if (ActiveRound != null) { ActiveRound.Votes.RemoveAll(v => v.ClientID == c.Info.ID && v.ClientName == c.Info.Name); } if (Admins.Contains(c)) { Admins.Remove(c); } // Some race case is going on here... we need to check if there's even anything to remove. if (Clients.Count > 0) { Clients.Remove(c); } c = null; if (Clients.All(cl => cl.Info.IsSpectator) && ActiveRound != null) { DiscardActiveRound(); BroadcastError(c, "RoundStopped", "There are no more non-spectator players, so the current round has been automatically discarded."); } // Check that every person hasn't already voted. CheckVoteCount(); }
/// <summary> /// Registers a new vote for the specified client, with the specified vote value. /// </summary> /// <param name="c">The client who voted.</param> /// <param name="vote">The value of the vote.</param> /// <returns>True if the vote was registered, false if a failure occurred (no active round, invalid vote value, client is spectator, client already voted).</returns> public bool RegisterVote(Client c, string vote) { if (ActiveRound == null || ActiveRound.Flipped) { return false; } if (!CardSet.Default.Cards.Contains(vote)) { return false; } if (c.Info.IsSpectator) { return false; } bool result = ActiveRound.RegisterVote(new Vote() { ClientID = c.Info.ID, ClientName = c.Info.Name, VoteValue = vote }); CheckVoteCount(); if(result) { // If successful, broadcast the new state to the clients. BroadcastGameState(); } return result; }
/// <summary> /// Attempts to register the specified client as an admin using the specified password. This checks against the server password, and will /// return true if the password was correct (and the client was elevated to an admin), otherwise it returns false. /// </summary> /// <param name="c">The client requesting administrative priveleges.</param> /// <param name="pass">The password that the client provided, to be checked against the actual password for the server.</param> /// <returns></returns> public bool RegisterAdmin(Client c, string pass) { if (pass == AdminPassword) { Admins.Add(c); return true; } else { return false; } }
/// <summary> /// Broadcasts a JSON message to all clients. If an origin is specified, the message is not re-broadcast back to the origin. /// </summary> /// <param name="origin">Optionally, a client origin which the message will not be broadcast back to. Set to <c>null</c> to broadcast to every client.</param> /// <param name="message">The message to broadcast.</param> /// <param name="parameters">An array of <see cref="JProperty" /> objects to include as parameters with the message.</param> public void BroadcastMessage(Client origin, string message, params JProperty[] parameters) { if (origin != null) { Clients.Where(c => !c.Equals(origin)).ToList().ForEach(c => c.SendMessage(message, parameters)); } else { Clients.ForEach(c => c.SendMessage(message, parameters)); } }
/// <summary> /// Broadcasts an error message to all clients. If an origin is specified, the message is not re-broadcast back to the origin. /// </summary> /// <param name="origin">Optionally, a client origin which the error will not be broadcast back to. Set to <c>null</c> to broadcast to every client.</param> /// <param name="source">The source of the error.</param> /// <param name="message">The error message to broadcast.</param> /// <param name="sendBack">Whether or not to send the error back to the origin client or not.</param> public void BroadcastError(Client origin, string source, string message, bool sendBack = false) { if (origin != null && !sendBack) { Clients.Where(c => !c.Equals(origin)).ToList().ForEach(c => c.SendError(source, message)); } else { Clients.ForEach(c => c.SendError(source, message)); } }