Пример #1
0
 public NhoodRequest GetRunRequest(NhoodRequest req)
 {
     return(new NhoodRequest()
     {
         Type = NhoodRequestType.NOMINATION_RUN,
         Message = Edit.CurrentText,
         TargetNHood = req.TargetNHood
     });
 }
Пример #2
0
 public NhoodRequest MakeRequest(NhoodRequest request)
 {
     return new NhoodRequest()
     {
         Type = NhoodRequestType.VOTE,
         TargetAvatar = SelectedID,
         TargetNHood = request.TargetNHood
     };
 }
Пример #3
0
 public NhoodRequest GetRequest(NhoodRequest req)
 {
     return(new NhoodRequest()
     {
         Type = NhoodRequestType.RATE,
         Message = Edit.CurrentText,
         Value = (uint)Rating.HalfStars,
         TargetAvatar = req.TargetAvatar,
         TargetNHood = req.TargetNHood
     });
 }
 public NhoodRequest GetRequest(NhoodRequest initial)
 {
     if (SelectedCandidate == null)
     {
         return(null);
     }
     return(new NhoodRequest()
     {
         Type = NhoodRequestType.NOMINATE,
         TargetNHood = initial.TargetNHood,
         TargetAvatar = SelectedCandidate.ID
     });
 }
Пример #5
0
        public async void Handle(IVoltronSession session, NhoodRequest packet)
        {
            if (session.IsAnonymous) //CAS users can't do this.
            {
                return;
            }

            var config       = Context.Config.Neighborhoods;
            var moveTime     = config.Election_Move_Penalty * 24 * 60 * 60; //24 * 60 * 60 * 30; //must live in an nhood 30 days before participating in an election
            var rateMoveTime = config.Rating_Move_Penalty * 24 * 60 * 60;   //24 * 60 * 60 * 30; //must live in an nhood 30 days before participating in an election
            var mail         = Kernel.Get <MailHandler>();

            try
            {
                using (var da = DA.Get())
                {
                    var myAva = da.Avatars.Get(session.AvatarId);
                    if (myAva == null)
                    {
                        Code(NhoodResponseCode.UNKNOWN_ERROR);
                    }

                    if (packet.Type >= NhoodRequestType.DELETE_RATE)
                    {
                        if (myAva.moderation_level == 0)
                        {
                            session.Write(Code(NhoodResponseCode.NOT_MODERATOR));
                            return;
                        }
                    }

                    //are we nhood gameplay banned?

                    var ban = da.Neighborhoods.GetNhoodBan(myAva.user_id);
                    if (ban != null)
                    {
                        session.Write(new NhoodResponse
                        {
                            Code       = NhoodResponseCode.NHOOD_GAMEPLAY_BAN,
                            Message    = ban.ban_reason,
                            BanEndDate = ban.end_date
                        });
                        return;
                    }

                    //common info used by most requests
                    var myLotID = da.Roommates.GetAvatarsLots(session.AvatarId).FirstOrDefault();
                    var myLot   = (myLotID == null) ? null : da.Lots.Get(myLotID.lot_id);

                    var freeVote  = da.Elections.GetFreeVote(session.AvatarId);
                    var freeNhood = (int)(myLot?.neighborhood_id ?? 0);
                    var voteValue = (freeVote == null) ? config.Vote_Normal_Value : config.Vote_Free_Value;
                    if (freeVote != null)
                    {
                        freeNhood = freeVote.neighborhood_id;
                    }

                    switch (packet.Type)
                    {
                    //user requests
                    case NhoodRequestType.CAN_RATE:
                    case NhoodRequestType.RATE:
                    {
                        if (packet.Value > 10 || packet.Value < 0 || packet.Message == null || packet.Message.Length > 200)
                        {
                            session.Write(Code(NhoodResponseCode.INVALID_RATING));
                            return;
                        }
                        if (myLot == null || myLot.neighborhood_id != packet.TargetNHood)
                        {
                            session.Write(Code(NhoodResponseCode.NOT_IN_NHOOD));
                            return;
                        }
                        if (session.AvatarId == packet.TargetAvatar)
                        {
                            session.Write(Code(NhoodResponseCode.CANT_RATE_AVATAR));         //you can't rate yourself...
                            return;
                        }
                        if (Epoch.Now - myAva.move_date < rateMoveTime)
                        {
                            session.Write(Code(NhoodResponseCode.YOU_MOVED_RECENTLY)); return;
                        }
                        //verify the target avatar is the current mayor
                        var rateNhood = da.Neighborhoods.Get(packet.TargetNHood);
                        //user check: ratings are technically towards individual avatars, but are shared between the same user.
                        var avaFrom = da.Avatars.Get(session.AvatarId);
                        var avaTo   = da.Avatars.Get(packet.TargetAvatar);
                        if (rateNhood == null || avaFrom == null || avaTo == null)
                        {
                            session.Write(Code(NhoodResponseCode.UNKNOWN_ERROR));         //shouldn't happen, but just in case
                            return;
                        }
                        if (rateNhood.mayor_id != packet.TargetAvatar)
                        {
                            session.Write(Code(NhoodResponseCode.NOT_YOUR_MAYOR));         //you can't rate yourself...
                            return;
                        }

                        if (packet.Type == NhoodRequestType.RATE)
                        {
                            //insert or replace rating
                            var id = da.Elections.SetRating(new DbMayorRating()
                                {
                                    from_avatar_id = avaFrom.avatar_id,
                                    to_avatar_id   = avaTo.avatar_id,
                                    from_user_id   = avaFrom.user_id,
                                    to_user_id     = avaTo.user_id,
                                    comment        = packet.Message,
                                    rating         = packet.Value,
                                    neighborhood   = packet.TargetNHood,
                                    date           = Epoch.Now,
                                    anonymous      = 1,
                                });

                            var ds = Kernel.Get <IDataService>();
                            if (id != 0)
                            {
                                ds.Invalidate <MayorRating>(id);        //update this rating in data service
                            }
                            ds.Invalidate <Avatar>(packet.TargetAvatar);
                        }

                        session.Write(Code(NhoodResponseCode.SUCCESS)); return;
                    }

                    case NhoodRequestType.CAN_NOMINATE:
                    case NhoodRequestType.NOMINATE:
                    case NhoodRequestType.CAN_VOTE:
                    case NhoodRequestType.VOTE:
                    {
                        if (freeVote != null)
                        {
                            packet.TargetNHood = (uint)freeNhood;
                        }
                        if (myLot == null || freeNhood != packet.TargetNHood)
                        {
                            session.Write(Code(NhoodResponseCode.NOT_IN_NHOOD)); return;
                        }

                        var now = Epoch.Now;
                        if (now - myAva.move_date < moveTime)
                        {
                            session.Write(Code(NhoodResponseCode.YOU_MOVED_RECENTLY)); return;
                        }

                        //check if voting cycle in correct state
                        var nhood = da.Neighborhoods.Get(packet.TargetNHood);
                        if (nhood == null)
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY)); return;
                        }
                        var cycle = (nhood.election_cycle_id == null) ? null : da.Elections.GetCycle(nhood.election_cycle_id.Value);
                        if (cycle == null)
                        {
                            session.Write(Code(NhoodResponseCode.ELECTION_OVER)); return;
                        }

                        var nominations = packet.Type == NhoodRequestType.CAN_NOMINATE || packet.Type == NhoodRequestType.NOMINATE;
                        if ((nominations && cycle.current_state != DbElectionCycleState.nomination) ||
                            (!nominations && cycle.current_state != DbElectionCycleState.election))
                        {
                            session.Write(Code(NhoodResponseCode.BAD_STATE)); return;
                        }

                        DbAvatar targetAva = null;
                        if (packet.Type != NhoodRequestType.CAN_NOMINATE && packet.Type != NhoodRequestType.CAN_VOTE)
                        {
                            //when we are actually nominating or voting, we have a target avatar in mind.

                            targetAva = da.Avatars.Get(packet.TargetAvatar);
                            if (targetAva == null)
                            {
                                session.Write(Code(NhoodResponseCode.INVALID_AVATAR)); return;
                            }
                            var targLotID = da.Roommates.GetAvatarsLots(packet.TargetAvatar).FirstOrDefault();
                            var targLot   = (targLotID == null) ? null : da.Lots.Get(targLotID.lot_id);

                            if (targLot == null || targLot.neighborhood_id != packet.TargetNHood)
                            {
                                session.Write(Code(NhoodResponseCode.CANDIDATE_NOT_IN_NHOOD)); return;
                            }

                            var targBan = da.Neighborhoods.GetNhoodBan(targetAva.user_id);
                            if (targBan != null)
                            {
                                session.Write(Code(NhoodResponseCode.CANDIDATE_NHOOD_GAMEPLAY_BAN)); return;
                            }

                            if (now - targetAva.move_date < moveTime)
                            {
                                session.Write(Code(NhoodResponseCode.CANDIDATE_MOVED_RECENTLY)); return;
                            }
                        }

                        //ok, we're all good.

                        if (!nominations)
                        {
                            //have we already voted?
                            //note: this should be double checked with a BEFORE INSERT on the table.
                            //just in case there's some kind of race condition due to this request being duplicated.
                            //this check is therefore just to get a better voting error message.
                            DbElectionVote existing = da.Elections.GetMyVote(session.AvatarId, cycle.cycle_id, DbElectionVoteType.vote);

                            if (existing != null)
                            {
                                if (existing.from_avatar_id != session.AvatarId)
                                {
                                    session.Write(Code(NhoodResponseCode.ALREADY_VOTED_SAME_IP));         //couldn't vote due to relation
                                }
                                else
                                {
                                    session.Write(Code(NhoodResponseCode.ALREADY_VOTED));
                                }
                            }

                            if (packet.Type == NhoodRequestType.CAN_VOTE)
                            {
                                //we are allowed to vote

                                //send back the candidate list


                                var sims   = da.Elections.GetCandidates(cycle.cycle_id);
                                var result = new List <NhoodCandidate>();

                                foreach (var x in sims)
                                {
                                    if (x.state != DbCandidateState.running)
                                    {
                                        continue;
                                    }
                                    var ava = (await DataService.Get <Avatar>(x.candidate_avatar_id));
                                    if (ava == null)
                                    {
                                        continue;
                                    }

                                    var win = da.Elections.FindLastWin(x.candidate_avatar_id);
                                    result.Add(new NhoodCandidate()
                                        {
                                            ID            = x.candidate_avatar_id,
                                            Name          = ava.Avatar_Name,
                                            Rating        = ava.Avatar_MayorRatingHundredth,
                                            Message       = x.comment,
                                            LastNhoodName = win?.nhood_name ?? "",
                                            LastNhoodID   = win?.nhood_id ?? 0,
                                            TermNumber    = (uint)((nhood.mayor_id == x.candidate_avatar_id) ? GetTermsSince(nhood.mayor_elected_date) : 0)
                                        });
                                }

                                session.Write(new NhoodCandidateList()
                                    {
                                        NominationMode = false,
                                        Candidates     = result.ToList()
                                    });

                                session.Write(Code(NhoodResponseCode.SUCCESS)); return;
                            }

                            //extra checks. has the target user been nominated?
                            if (!da.Elections.GetCandidates(cycle.cycle_id, DbCandidateState.running).Any(x => x.candidate_avatar_id == packet.TargetAvatar))
                            {
                                session.Write(Code(NhoodResponseCode.CANDIDATE_NOT_NOMINATED)); return;
                            }

                            //put our vote through! democracy is great.
                            var success = da.Elections.CreateVote(new DbElectionVote()
                                {
                                    date = Epoch.Now,
                                    election_cycle_id = cycle.cycle_id,
                                    from_avatar_id    = session.AvatarId,
                                    target_avatar_id  = packet.TargetAvatar,
                                    type  = DbElectionVoteType.vote,
                                    value = voteValue
                                });
                            if (!success)
                            {
                                session.Write(Code(NhoodResponseCode.ALREADY_VOTED));
                                return;
                            }

                            mail.SendSystemEmail("f116", (int)NeighMailStrings.VoteCountedSubject, (int)NeighMailStrings.VoteCounted,
                                                 1, MessageSpecialType.Normal, cycle.end_date, session.AvatarId, targetAva.name, nhood.name);
                            session.Write(Code(NhoodResponseCode.SUCCESS));
                        }
                        else
                        {
                            //have we already nominated?
                            DbElectionVote existing = da.Elections.GetMyVote(session.AvatarId, cycle.cycle_id, DbElectionVoteType.nomination);

                            if (existing != null)
                            {
                                if (existing.from_avatar_id != session.AvatarId)
                                {
                                    session.Write(Code(NhoodResponseCode.ALREADY_VOTED_SAME_IP));         //couldn't nominate due to relation
                                }
                                else
                                {
                                    session.Write(Code(NhoodResponseCode.ALREADY_VOTED));
                                }
                            }

                            if (packet.Type == NhoodRequestType.CAN_NOMINATE)
                            {
                                //we are allowed to nominate.

                                //send back the list of sims in nhood
                                var sims   = da.Avatars.GetPossibleCandidatesNhood((uint)packet.TargetNHood);
                                var result = sims.Select(x => new NhoodCandidate()
                                    {
                                        ID     = x.avatar_id,
                                        Name   = x.name,
                                        Rating = (x.rating == null) ? uint.MaxValue : (uint)((x.rating / 2) * 100)
                                    });

                                session.Write(new NhoodCandidateList()
                                    {
                                        NominationMode = true,
                                        Candidates     = result.ToList()
                                    });

                                session.Write(Code(NhoodResponseCode.SUCCESS)); return;
                            }

                            //do the nomination.
                            var success = da.Elections.CreateVote(new DbElectionVote()
                                {
                                    date = Epoch.Now,
                                    election_cycle_id = cycle.cycle_id,
                                    from_avatar_id    = session.AvatarId,
                                    target_avatar_id  = packet.TargetAvatar,
                                    type  = DbElectionVoteType.nomination,
                                    value = voteValue
                                });
                            if (!success)
                            {
                                session.Write(Code(NhoodResponseCode.ALREADY_VOTED));
                                return;
                            }

                            //if >= 3 nominations, allow the player to run for election.
                            var noms = da.Elections.GetCycleVotesForAvatar(packet.TargetAvatar, cycle.cycle_id, DbElectionVoteType.nomination);
                            if (noms.Count() >= config.Min_Nominations)
                            {
                                var created = da.Elections.CreateCandidate(new DbElectionCandidate()
                                    {
                                        candidate_avatar_id = packet.TargetAvatar,
                                        election_cycle_id   = cycle.cycle_id,
                                        comment             = packet.Message,
                                        state = DbCandidateState.informed
                                    });
                                //only send the mail if they have not accepted.
                                if (created)
                                {
                                    mail.SendSystemEmail("f116", (int)NeighMailStrings.NominationQuerySubject, (int)NeighMailStrings.NominationQuery,
                                                         1, MessageSpecialType.AcceptNomination, cycle.end_date, packet.TargetAvatar, nhood.name, cycle.end_date.ToString());
                                }
                            }

                            mail.SendSystemEmail("f116", (int)NeighMailStrings.NominationCountedSubject, (int)NeighMailStrings.NominationCounted,
                                                 1, MessageSpecialType.Normal, cycle.end_date, session.AvatarId, targetAva.name, nhood.name);

                            session.Write(Code(NhoodResponseCode.SUCCESS));
                        }

                        break;
                    }

                    case NhoodRequestType.NOMINATION_RUN:
                    case NhoodRequestType.CAN_RUN:
                    {
                        //if a user has been nominated 3 or more times, they will be asked if they would like to run for mayor by email.
                        //the email will contain a button that lets the user accept the nomination.
                        //this doesn't immediately get them running for mayor, it means that they are a valid selection from
                        //the top nominated candidates when the nominations are finalized.

                        //first check if we have the three required nominations
                        if (myLot == null || myLot.neighborhood_id != packet.TargetNHood)
                        {
                            session.Write(Code(NhoodResponseCode.NOT_IN_NHOOD)); return;
                        }

                        var nhood = da.Neighborhoods.Get(packet.TargetNHood);
                        if (nhood == null)
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY)); return;
                        }
                        var cycle = (nhood.election_cycle_id == null) ? null : da.Elections.GetCycle(nhood.election_cycle_id.Value);
                        if (cycle == null)
                        {
                            session.Write(Code(NhoodResponseCode.ELECTION_OVER)); return;
                        }

                        if (cycle.current_state != DbElectionCycleState.nomination)
                        {
                            session.Write(Code(NhoodResponseCode.BAD_STATE)); return;
                        }

                        //have we been nominated the minimum number of times? (3)
                        var noms = da.Elections.GetCycleVotesForAvatar(session.AvatarId, cycle.cycle_id, DbElectionVoteType.nomination);
                        if (noms.Count < config.Min_Nominations)
                        {
                            session.Write(Code(NhoodResponseCode.NOBODY_NOMINATED_YOU_IDIOT)); return;
                        }

                        if (packet.Type == NhoodRequestType.CAN_RUN)
                        {
                            if (da.Elections.GetCandidate(session.AvatarId, cycle.cycle_id, DbCandidateState.informed) == null)
                            {
                                session.Write(Code(NhoodResponseCode.ALREADY_RUNNING));
                            }
                            else
                            {
                                session.Write(Code(NhoodResponseCode.SUCCESS));
                            }
                        }
                        else
                        {
                            var success = da.Elections.SetCandidateState(new DbElectionCandidate()
                                {
                                    candidate_avatar_id = session.AvatarId,
                                    election_cycle_id   = cycle.cycle_id,
                                    comment             = packet.Message,
                                    state = DbCandidateState.running
                                });

                            if (success)
                            {
                                mail.SendSystemEmail("f116", (int)NeighMailStrings.NominationAcceptedSubject, (int)NeighMailStrings.NominationAccepted,
                                                     1, MessageSpecialType.Normal, cycle.end_date, session.AvatarId, nhood.name, cycle.end_date.ToString());

                                session.Write(Code(NhoodResponseCode.SUCCESS));
                            }
                            else
                            {
                                session.Write(Code(NhoodResponseCode.ALREADY_RUNNING));
                            }
                        }
                        return;
                    }

                    case NhoodRequestType.CAN_FREE_VOTE:
                    case NhoodRequestType.FREE_VOTE:
                    {
                        //should live somewhere:
                        if (myLot == null)
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY)); return;
                        }

                        //we shouldn't already be enrolled
                        if (freeNhood != myLot.neighborhood_id)
                        {
                            session.Write(Code(NhoodResponseCode.ALREADY_ENROLLED_FOR_FREE_VOTE)); return;
                        }

                        //our nhood needs to be ineligible
                        var ourNhood = da.Neighborhoods.Get(myLot.neighborhood_id);
                        if (ourNhood == null)
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY)); return;
                        }

                        var cycle = (ourNhood.election_cycle_id == null) ? null : da.Elections.GetCycle(ourNhood.election_cycle_id.Value);
                        if (cycle != null && cycle.current_state != DbElectionCycleState.shutdown)
                        {
                            session.Write(Code(NhoodResponseCode.FREE_VOTE_ALREADY_ELIGIBLE)); return;
                        }

                        //get eligible nhoods
                        var eligible = da.Elections.GetActiveCycles(Context.ShardId);

                        if (eligible.Count == 0)
                        {
                            session.Write(Code(NhoodResponseCode.FREE_VOTE_ELECTION_OVER)); return;
                        }

                        //our last move needs to have been before the nhood cycle started
                        var now = Epoch.Now;
                        if (eligible.All(x => x.start_date < myAva.move_date))
                        {
                            session.Write(Code(NhoodResponseCode.FREE_VOTE_MOVE_DATE)); return;
                        }

                        if (packet.Type == NhoodRequestType.CAN_FREE_VOTE)
                        {
                            //send the eligible nhoods
                            var result = eligible.Select(x => new NhoodCandidate()
                                {
                                    ID     = (uint)x.nhood_id,
                                    Name   = x.name,
                                    Rating = uint.MaxValue
                                });

                            session.Write(new NhoodCandidateList()
                                {
                                    NominationMode = true,
                                    Candidates     = result.ToList()
                                });

                            session.Write(Code(NhoodResponseCode.SUCCESS));
                            return;
                        }

                        //the target nhood needs to be eligible, and have an ongoing election
                        var targ = da.Neighborhoods.Get(packet.TargetNHood);
                        if (targ == null || targ.election_cycle_id == null)
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY));
                            return;
                        }

                        var targCycle = da.Elections.GetCycle((uint)targ.election_cycle_id);
                        if (targCycle == null || targCycle.current_state == DbElectionCycleState.shutdown)
                        {
                            session.Write(Code(NhoodResponseCode.NHOOD_NO_ELECTION));
                            return;
                        }

                        var fVote = new DbElectionFreeVote()
                        {
                            avatar_id       = session.AvatarId,
                            cycle_id        = targCycle.cycle_id,
                            neighborhood_id = targ.neighborhood_id,
                            date            = Epoch.Now,
                            expire_date     = targCycle.end_date
                        };
                        if (!da.Elections.EnrollFreeVote(fVote))
                        {
                            session.Write(Code(NhoodResponseCode.ALREADY_ENROLLED_FOR_FREE_VOTE));
                            return;
                        }

                        mail.SendSystemEmail("f116", (int)NeighMailStrings.FreeVoteConfirmationSubject, (int)NeighMailStrings.FreeVoteConfirmation,
                                             1, MessageSpecialType.Normal, targCycle.end_date, session.AvatarId, targ.name);

                        Nhoods.SendStateEmail(da, mail, targ, targCycle, session.AvatarId);

                        session.Write(Code(NhoodResponseCode.SUCCESS));
                        return;
                    }

                    // ======= management =======
                    case NhoodRequestType.DELETE_RATE:
                        var beforeDelete = da.Elections.GetRating(packet.Value);
                        if (da.Elections.DeleteRating(packet.Value))
                        {
                            var ds = Kernel.Get <IDataService>();
                            try
                            {
                                ds.Invalidate <Avatar>(beforeDelete.from_avatar_id);
                                ds.Invalidate <MayorRating>(packet.Value);    //update this rating in data service
                            } catch (Exception)
                            {
                            }

                            session.Write(new NhoodResponse()
                            {
                                Code    = NhoodResponseCode.SUCCESS,
                                Message = (beforeDelete?.from_avatar_id ?? 0).ToString()
                            });
                        }
                        else
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY));
                        }
                        return;

                    case NhoodRequestType.FORCE_MAYOR:
                        //set the mayor.
                        await Nhoods.SetMayor(da, packet.TargetAvatar, packet.TargetNHood);

                        session.Write(Code(NhoodResponseCode.SUCCESS));
                        return;

                    case NhoodRequestType.ADD_CANDIDATE:
                        //check if voting cycle in correct state
                    {
                        var nhood = da.Neighborhoods.Get(packet.TargetNHood);
                        if (nhood == null)
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY)); return;
                        }
                        var cycle = (nhood.election_cycle_id == null) ? null : da.Elections.GetCycle(nhood.election_cycle_id.Value);
                        if (cycle == null)
                        {
                            session.Write(Code(NhoodResponseCode.ELECTION_OVER)); return;
                        }
                        //while candidates DO have a use in nominations, adding them is largely pointless before the elections have begun
                        //(because they will likely be removed when choosing the top 5 anyways)
                        if (cycle.current_state != DbElectionCycleState.election)
                        {
                            session.Write(Code(NhoodResponseCode.BAD_STATE)); return;
                        }
                    }
                    break;

                    case NhoodRequestType.REMOVE_CANDIDATE:
                        //get current cycle
                    {
                        var nhood = da.Neighborhoods.Get(packet.TargetNHood);
                        if (nhood == null)
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY)); return;
                        }
                        var cycle = (nhood.election_cycle_id == null) ? null : da.Elections.GetCycle(nhood.election_cycle_id.Value);
                        if (cycle == null)
                        {
                            session.Write(Code(NhoodResponseCode.ELECTION_OVER)); return;
                        }

                        if (da.Elections.DeleteCandidate(cycle.cycle_id, packet.TargetAvatar))
                        {
                            session.Write(Code(NhoodResponseCode.SUCCESS));
                        }
                        else
                        {
                            session.Write(Code(NhoodResponseCode.INVALID_AVATAR));
                        }
                    }
                    break;

                    case NhoodRequestType.TEST_ELECTION:
                        //create an election cycle
                    {
                        var nhood = da.Neighborhoods.Get(packet.TargetNHood);
                        if (nhood == null)
                        {
                            session.Write(Code(NhoodResponseCode.MISSING_ENTITY)); return;
                        }

                        var cycle = new DbElectionCycle()
                        {
                            current_state = DbElectionCycleState.nomination,
                            election_type = DbElectionCycleType.election,
                            start_date    = Epoch.Now,
                            end_date      = packet.Value
                        };
                        var cycleID = da.Elections.CreateCycle(cycle);
                        if (cycleID == 0)
                        {
                            session.Write(Code(NhoodResponseCode.UNKNOWN_ERROR));
                            return;
                        }
                        cycle.cycle_id          = cycleID;
                        nhood.election_cycle_id = cycleID;
                        da.Neighborhoods.UpdateCycle((uint)nhood.neighborhood_id, cycleID);

                        await Nhoods.ChangeElectionState(da, nhood, cycle, (DbElectionCycleState)packet.TargetAvatar);

                        session.Write(Code(NhoodResponseCode.SUCCESS));
                        return;
                    }

                    case NhoodRequestType.PRETEND_DATE:
                        try
                        {
                            uint day = 60 * 60 * 24;
                            Nhoods.SaveCheatOffset((((packet.Value - Epoch.Now) + day - 1) / day) * day);
                            await Nhoods.TickNeighborhoods(Epoch.ToDate(packet.Value));

                            session.Write(Code(NhoodResponseCode.SUCCESS));
                        }
                        catch (Exception e)
                        {
                            session.Write(new NhoodResponse()
                            {
                                Code    = NhoodResponseCode.UNKNOWN_ERROR,
                                Message = e.ToString()
                            });
                        }
                        return;

                    case NhoodRequestType.NHOOD_GAMEPLAY_BAN:
                    {
                        var targetAva = da.Avatars.Get(packet.TargetAvatar);
                        if (targetAva == null)
                        {
                            session.Write(Code(NhoodResponseCode.INVALID_AVATAR));
                        }
                        var success = da.Neighborhoods.AddNhoodBan(new DbNhoodBan()
                            {
                                user_id    = targetAva.user_id,
                                ban_reason = packet.Message,
                                end_date   = packet.Value
                            });
                        if (success)
                        {
                            mail.SendSystemEmail("f116", (int)NeighMailStrings.NeighGameplayBanSubject, (int)NeighMailStrings.NeighGameplayBan,
                                                 1, MessageSpecialType.Normal, packet.Value, packet.TargetAvatar, packet.Message, packet.Value.ToString());
                        }
                        session.Write(Code(NhoodResponseCode.SUCCESS));
                        return;
                    }

                    default:
                        session.Write(Code(NhoodResponseCode.UNKNOWN_ERROR)); return;
                    }
                }
            } catch (Exception e)
            {
                LOG.Error(e.ToString());
                session?.Write(Code(NhoodResponseCode.UNKNOWN_ERROR));
            }
        }