public bool StateHasEmail(DbElectionCycleState state) { return(state == DbElectionCycleState.nomination || state == DbElectionCycleState.election || state == DbElectionCycleState.ended || state == DbElectionCycleState.failsafe || (state == DbElectionCycleState.shutdown && Context.Config.Neighborhoods.Election_Free_Vote)); }
public async Task ChangeElectionState(IDA da, DbNeighborhood nhood, DbElectionCycle cycle, DbElectionCycleState state) { var now = Epoch.Now; var mail = Kernel.Get <MailHandler>(); switch (state) { case DbElectionCycleState.nomination: //start nominations for this cycle. var endDate = cycle.end_date - 60 * 60 * 24 * 3; //nomination ends 3 days before end of cycle SendBulletinPost(da, nhood.neighborhood_id, "f123", (int)NeighBulletinStrings.NominateSubject, (int)NeighBulletinStrings.Nominate, endDate, nhood.name, endDate.ToString()); break; case DbElectionCycleState.election: //end nominations. choose the candidate sims. var cycleNoms = da.Elections.GetCycleVotes(cycle.cycle_id, DbElectionVoteType.nomination); var toRemove = da.Elections.GetCandidates(cycle.cycle_id).ToDictionary(x => x.candidate_avatar_id); if (cycleNoms.Count > 0) { var grouped = cycleNoms.GroupBy(x => x.target_avatar_id).OrderByDescending(x => x.Sum(y => y.value)); var selected = 0; var candidates = new List <IGrouping <uint, DbElectionVote> >(); foreach (var winner in grouped) { //verify the winners are still alive and still in this neighborhood string name = null; DbElectionCandidate cand; if (toRemove.TryGetValue(winner.Key, out cand) && VerifyCanBeMayor(da, winner.Key, (uint)nhood.neighborhood_id, now, ref name)) { if (cand.state != DbCandidateState.running) { continue; //user must have accepted their nomination } toRemove.Remove(winner.Key); mail.SendSystemEmail("f116", (int)NeighMailStrings.RunningForMayorSubject, (int)NeighMailStrings.RunningForMayor, 1, MessageSpecialType.Normal, cycle.end_date, winner.Key, nhood.name, cand.comment, cycle.end_date.ToString()); candidates.Add(winner); if (++selected >= 5) { break; } } } foreach (var remove in toRemove) { da.Elections.DeleteCandidate(remove.Value.election_cycle_id, remove.Value.candidate_avatar_id); if (remove.Value.state == DbCandidateState.running) { mail.SendSystemEmail("f116", (int)NeighMailStrings.TooFewNominationsSubject, (int)NeighMailStrings.TooFewNominations, 1, MessageSpecialType.Normal, cycle.end_date, remove.Key, nhood.name, cycle.end_date.ToString()); } else { mail.SendSystemEmail("f116", (int)NeighMailStrings.NominationNotAcceptedSubject, (int)NeighMailStrings.NominationNotAccepted, 1, MessageSpecialType.Normal, cycle.end_date, remove.Key, nhood.name, cycle.end_date.ToString()); } } if (selected == 0) { state = DbElectionCycleState.failsafe; break; } //email will be sent by event system. make a bulletin post too SendBulletinPost(da, nhood.neighborhood_id, "f123", (int)NeighBulletinStrings.VoteSubject, (int)NeighBulletinStrings.Vote, cycle.end_date, nhood.name, string.Join("\n", candidates.Select(x => "- " + (da.Avatars.Get(x.Key)?.name ?? "(unknown)"))), cycle.end_date.ToString()); } else { state = DbElectionCycleState.failsafe; } break; case DbElectionCycleState.ended: //end election. if there are any candidates, set the mayor to the one that recieved the most votes. var cycleVotes = da.Elections.GetCycleVotes(cycle.cycle_id, DbElectionVoteType.vote); if (cycleVotes.Count > 0) { var grouped = cycleVotes.GroupBy(x => x.target_avatar_id).OrderByDescending(x => x.Sum(y => y.value)).ToList(); //verify the winner is still alive and still in this neighborhood string name = ""; while (grouped.Count > 0 && !VerifyCanBeMayor(da, grouped[0].Key, (uint)nhood.neighborhood_id, now, ref name)) { grouped.RemoveAt(0); } if (grouped.Count == 0) { state = DbElectionCycleState.failsafe; if (nhood.mayor_id != null) { await SetMayor(da, 0, (uint)nhood.neighborhood_id); } break; } var winner = grouped[0]; //we have a winner da.Elections.SetCandidateState(new DbElectionCandidate() { election_cycle_id = cycle.cycle_id, candidate_avatar_id = winner.Key, state = DbCandidateState.won }); await SetMayor(da, winner.Key, (uint)nhood.neighborhood_id); mail.SendSystemEmail("f116", (int)NeighMailStrings.YouWinSubject, (int)NeighMailStrings.YouWin, 1, MessageSpecialType.Normal, 0, winner.Key, nhood.name, winner.Count().ToString()); //tell the losers they lost grouped.RemoveAt(0); var placement = 2; foreach (var loser in grouped) { da.Elections.SetCandidateState(new DbElectionCandidate() { election_cycle_id = cycle.cycle_id, candidate_avatar_id = loser.Key, state = DbCandidateState.lost }); placement++; } int runnerI = 2; SendBulletinPost(da, nhood.neighborhood_id, "f123", (int)NeighBulletinStrings.ElectionOverSubject, (int)NeighBulletinStrings.ElectionOver, cycle.end_date, (da.Avatars.Get(winner.Key)?.name ?? "(unknown)"), nhood.name, string.Join("\n", grouped.Select(x => (runnerI++).ToString() + ". " + (da.Avatars.Get(x.Key)?.name ?? "(unknown)")))); } else { state = DbElectionCycleState.failsafe; if (nhood.mayor_id != null) { await SetMayor(da, 0, (uint)nhood.neighborhood_id); } } break; } da.Elections.UpdateCycleState(cycle.cycle_id, state); if (state == DbElectionCycleState.failsafe && state != cycle.current_state) { SendBulletinPost(da, nhood.neighborhood_id, "f123", (int)NeighBulletinStrings.FailsafeSubject, (int)NeighBulletinStrings.Failsafe, 0, nhood.name); } cycle.current_state = state; if (StateHasEmail(state)) { BroadcastNhoodState(da, mail, nhood, cycle); } }
public void UpdateCycleState(uint cycle_id, DbElectionCycleState state) { Context.Connection.Query <DbElectionVote>("UPDATE fso_election_cycles SET current_state = @state WHERE cycle_id = @cycle_id", new { cycle_id = cycle_id, state = state.ToString() }).ToList(); }