private Avatar HydrateOne(DbAvatar dbAvatar, DbLot dbLot)
        {
            var result = new Avatar();

            result.Avatar_Id          = dbAvatar.avatar_id;
            result.Avatar_Name        = dbAvatar.name;
            result.Avatar_IsOnline    = false;
            result.Avatar_Description = dbAvatar.description;
            result.Avatar_Appearance  = new AvatarAppearance
            {
                AvatarAppearance_BodyOutfitID = dbAvatar.body,
                AvatarAppearance_HeadOutfitID = dbAvatar.head,
                AvatarAppearance_SkinTone     = dbAvatar.skin_tone
            };
            var now = Epoch.Now;

            result.FetchTime     = now;
            result.Avatar_Age    = (uint)((now - dbAvatar.date) / ((long)60 * 60 * 24));
            result.Avatar_Skills = new AvatarSkills
            {
                AvatarSkills_Body              = dbAvatar.skill_body,
                AvatarSkills_LockLv_Body       = dbAvatar.lock_body,
                AvatarSkills_Charisma          = dbAvatar.skill_charisma,
                AvatarSkills_LockLv_Charisma   = dbAvatar.lock_charisma,
                AvatarSkills_Cooking           = dbAvatar.skill_cooking,
                AvatarSkills_LockLv_Cooking    = dbAvatar.lock_cooking,
                AvatarSkills_Creativity        = dbAvatar.skill_creativity,
                AvatarSkills_LockLv_Creativity = dbAvatar.lock_creativity,
                AvatarSkills_Logic             = dbAvatar.skill_logic,
                AvatarSkills_LockLv_Logic      = dbAvatar.lock_logic,
                AvatarSkills_Mechanical        = dbAvatar.skill_mechanical,
                AvatarSkills_LockLv_Mechanical = dbAvatar.lock_mechanical
            };
            result.Avatar_PrivacyMode      = dbAvatar.privacy_mode;
            result.Avatar_SkillsLockPoints = (ushort)(20 + result.Avatar_Age / 7);
            result.Avatar_ModerationLevel  = dbAvatar.moderation_level;
            result.Avatar_MayorNhood       = (uint)(dbAvatar.mayor_nhood ?? 0);

            result.JobLevelProvider  = JobLevelProvider;
            result.RatingProvider    = RatingProvider;
            result.AvgRatingProvider = AvgRatingProvider;
            result.Avatar_CurrentJob = dbAvatar.current_job;

            result.Avatar_Top100ListFilter = new Top100ListFilter()
            {
                Top100ListFilter_ResultsVec   = ImmutableList.Create <uint>(),
                Top100ListFilter_Top100ListID = 0,
            };

            result.RelationshipProvider = RelationshipProvider;

            if (dbLot != null)
            {
                result.Avatar_LotGridXY = dbLot.location;
            }

            result.BookmarkProvider = BookmarkProvider;

            return(result);
        }
Example #2
0
        public DbAvatar StateToDb(VMNetAvatarPersistState avatar)
        {
            var state = new DbAvatar();

            state.body           = avatar.DefaultSuits.Daywear.ID;
            state.body_sleepwear = avatar.DefaultSuits.Sleepwear.ID;
            state.body_swimwear  = avatar.DefaultSuits.Swimwear.ID;
            state.body_current   = avatar.BodyOutfit;

            state.skilllock       = (byte)avatar.SkillLock;
            state.lock_body       = (ushort)(avatar.SkillLockBody / 100);
            state.lock_charisma   = (ushort)(avatar.SkillLockCharisma / 100);
            state.lock_cooking    = (ushort)(avatar.SkillLockCooking / 100);
            state.lock_creativity = (ushort)(avatar.SkillLockCreativity / 100);
            state.lock_logic      = (ushort)(avatar.SkillLockLogic / 100);
            state.lock_mechanical = (ushort)(avatar.SkillLockMechanical / 100);

            state.skill_body       = (ushort)avatar.BodySkill;
            state.skill_charisma   = (ushort)avatar.CharismaSkill;
            state.skill_cooking    = (ushort)avatar.CookingSkill;
            state.skill_creativity = (ushort)avatar.CreativitySkill;
            state.skill_logic      = (ushort)avatar.LogicSkill;
            state.skill_mechanical = (ushort)avatar.MechanicalSkill;

            state.is_ghost = (ushort)avatar.IsGhost;

            state.ticker_death     = (ushort)avatar.DeathTicker;
            state.ticker_gardener  = (ushort)avatar.GardenerRehireTicker;
            state.ticker_maid      = (ushort)avatar.MaidRehireTicker;
            state.ticker_repairman = (ushort)avatar.RepairmanRehireTicker;

            state.current_job = (ushort)avatar.OnlineJobID;

            var motives = new byte[32];

            for (int i = 0; i < 16; i++)
            {
                var twoi = i + i;
                motives[twoi]     = (byte)(avatar.MotiveData[i] >> 8);
                motives[twoi + 1] = (byte)avatar.MotiveData[i];
            }
            state.motive_data = motives;

            return(state);
        }
Example #3
0
        private VMNetAvatarPersistState StateFromDB(DbAvatar avatar, List <DbRelationship> rels, List <DbJobLevel> jobs, List <DbRoommate> myRoomieLots, List <uint> ignored)
        {
            var state = new VMNetAvatarPersistState();

            state.Name                      = avatar.name;
            state.PersistID                 = avatar.avatar_id;
            state.DefaultSuits              = new SimAntics.VMAvatarDefaultSuits(avatar.gender == DbAvatarGender.female);
            state.DefaultSuits.Daywear.ID   = avatar.body;
            state.DefaultSuits.Swimwear.ID  = avatar.body_swimwear;
            state.DefaultSuits.Sleepwear.ID = avatar.body_sleepwear;
            state.BodyOutfit                = (avatar.body_current == 0)?avatar.body:avatar.body_current;
            state.HeadOutfit                = avatar.head;
            state.Gender                    = (short)avatar.gender;
            state.Budget                    = (uint)avatar.budget;
            state.SkinTone                  = avatar.skin_tone;

            var now = Epoch.Now;
            var age = (uint)((now - avatar.date) / ((long)60 * 60 * 24));

            state.SkillLock           = (short)(20 + age / 7);
            state.SkillLockBody       = (short)(avatar.lock_body * 100);
            state.SkillLockCharisma   = (short)(avatar.lock_charisma * 100);
            state.SkillLockCooking    = (short)(avatar.lock_cooking * 100);
            state.SkillLockCreativity = (short)(avatar.lock_creativity * 100);
            state.SkillLockLogic      = (short)(avatar.lock_logic * 100);
            state.SkillLockMechanical = (short)(avatar.lock_mechanical * 100);

            state.BodySkill       = (short)avatar.skill_body;
            state.CharismaSkill   = (short)avatar.skill_charisma;
            state.CookingSkill    = (short)avatar.skill_cooking;
            state.CreativitySkill = (short)avatar.skill_creativity;
            state.LogicSkill      = (short)avatar.skill_logic;
            state.MechanicalSkill = (short)avatar.skill_mechanical;

            state.IsGhost = (short)avatar.is_ghost;

            state.DeathTicker           = (short)avatar.ticker_death;
            state.GardenerRehireTicker  = (short)avatar.ticker_gardener;
            state.MaidRehireTicker      = (short)avatar.ticker_maid;
            state.RepairmanRehireTicker = (short)avatar.ticker_repairman;

            state.OnlineJobID    = (short)avatar.current_job;
            state.IgnoredAvatars = new HashSet <uint>(ignored);
            foreach (var job in jobs)
            {
                state.OnlineJobInfo[(short)job.job_type] = new VMTSOJobInfo()
                {
                    Experience  = (short)job.job_experience,
                    Level       = (short)job.job_level,
                    SickDays    = (short)job.job_sickdays,
                    StatusFlags = (short)job.job_statusflags
                };
            }

            if (myRoomieLots.Count == 0)
            {
                state.AvatarFlags |= VMTSOAvatarFlags.CanBeRoommate; //we're not roommate anywhere, so we can be here.
            }
            var roomieStatus = myRoomieLots.FindAll(x => x.lot_id == Context.DbId).FirstOrDefault();

            if (roomieStatus != null && roomieStatus.is_pending == 0)
            {
                switch (roomieStatus.permissions_level)
                {
                case 0:
                    state.Permissions = VMTSOAvatarPermissions.Roommate; break;

                case 1:
                    state.Permissions = VMTSOAvatarPermissions.BuildBuyRoommate; break;

                case 2:
                    state.Permissions = VMTSOAvatarPermissions.Owner; break;
                }
            }
            else
            {
                state.Permissions = VMTSOAvatarPermissions.Visitor;
            }

            if (avatar.moderation_level > 0)
            {
                state.Permissions = VMTSOAvatarPermissions.Admin;
            }

            var motives = new short[16];

            for (int i = 0; i < 16; i++)
            {
                var twoi = i + i;
                motives[i] = (short)((avatar.motive_data[twoi] << 8) | avatar.motive_data[twoi + 1]);
            }
            state.MotiveData = motives;

            var relDict = new Dictionary <uint, List <int> >();

            foreach (var rel in rels)
            {
                if (!relDict.ContainsKey(rel.to_id))
                {
                    relDict[rel.to_id] = new List <int>();
                }
                var list = relDict[rel.to_id];
                while (list.Count <= rel.index)
                {
                    list.Add(0);
                }
                list[(int)rel.index] = rel.value;
            }

            state.Relationships = new VMEntityPersistRelationshipMarshal[relDict.Count];
            for (int i = 0; i < relDict.Count; i++)
            {
                var dictItem = relDict.ElementAt(i);
                var marshal  = new VMEntityPersistRelationshipMarshal();
                marshal.Target         = dictItem.Key;
                marshal.Values         = dictItem.Value.ConvertAll(x => (short)x).ToArray();
                state.Relationships[i] = marshal;
            }

            return(state);
        }
Example #4
0
        /// <summary>
        /// Register a new avatar
        /// </summary>
        /// <param name="session"></param>
        /// <param name="packet"></param>
        public void Handle(IVoltronSession session, RSGZWrapperPDU packet)
        {
            PurchasableOutfit head = null;
            PurchasableOutfit body = null;

            switch (packet.Gender)
            {
            case Protocol.Voltron.Model.Gender.FEMALE:
                head = ValidFemaleOutfits[packet.HeadOutfitId];
                body = ValidFemaleOutfits[packet.BodyOutfitId];
                break;

            case Protocol.Voltron.Model.Gender.MALE:
                head = ValidMaleOutfits[packet.HeadOutfitId];
                body = ValidMaleOutfits[packet.BodyOutfitId];
                break;
            }

            if (head == null)
            {
                session.Write(new CreateASimResponse {
                    Status = CreateASimStatus.FAILED,
                    Reason = CreateASimFailureReason.HEAD_VALIDATION_ERROR
                });
                return;
            }

            if (body == null)
            {
                session.Write(new CreateASimResponse
                {
                    Status = CreateASimStatus.FAILED,
                    Reason = CreateASimFailureReason.BODY_VALIDATION_ERROR
                });
                return;
            }

            if (!NAME_VALIDATION.IsMatch(packet.Name))
            {
                session.Write(new CreateASimResponse
                {
                    Status = CreateASimStatus.FAILED,
                    Reason = CreateASimFailureReason.NAME_VALIDATION_ERROR
                });
                return;
            }

            if (!DESC_VALIDATION.IsMatch(packet.Description))
            {
                session.Write(new CreateASimResponse
                {
                    Status = CreateASimStatus.FAILED,
                    Reason = CreateASimFailureReason.DESC_VALIDATION_ERROR
                });
                return;
            }

            uint newId = 0;

            using (var db = DAFactory.Get)
            {
                var newAvatar = new DbAvatar
                {
                    shard_id    = Context.ShardId,
                    name        = packet.Name,
                    description = packet.Description,
                    date        = Epoch.Now,
                    head        = head.OutfitID,
                    body        = body.OutfitID,
                    skin_tone   = (byte)packet.SkinTone,
                    gender      = packet.Gender == Protocol.Voltron.Model.Gender.FEMALE ? DbAvatarGender.female : DbAvatarGender.male,
                    user_id     = session.UserId,
                    budget      = 0
                };

                if (packet.Gender == Protocol.Voltron.Model.Gender.MALE)
                {
                    newAvatar.body_swimwear  = 0x5470000000D;
                    newAvatar.body_sleepwear = 0x5440000000D;
                }
                else
                {
                    newAvatar.body_swimwear  = 0x620000000D;
                    newAvatar.body_sleepwear = 0x5150000000D;
                }

                var user = db.Users.GetById(session.UserId);
                if ((user?.is_moderator) ?? false)
                {
                    newAvatar.moderation_level = 1;
                }

                try
                {
                    newId = db.Avatars.Create(newAvatar);
                } catch (Exception e)
                {
                    //unique name error or avatar limit exceeded.
                    //todo: special error for avatar limit? exception is thrown from BEFORE INSERT trigger.
                    session.Write(new CreateASimResponse
                    {
                        Status = CreateASimStatus.FAILED,
                        Reason = CreateASimFailureReason.NAME_TAKEN
                    });
                    return;
                }

                //create clothes
                try
                {
                    db.Outfits.Create(new Database.DA.Outfits.DbOutfit {
                        avatar_owner   = newId,
                        asset_id       = newAvatar.body,
                        purchase_price = 0,
                        sale_price     = 0,
                        outfit_type    = (byte)VMPersonSuits.DefaultDaywear,
                        outfit_source  = Database.DA.Outfits.DbOutfitSource.cas
                    });

                    db.Outfits.Create(new Database.DA.Outfits.DbOutfit
                    {
                        avatar_owner   = newId,
                        asset_id       = newAvatar.body_sleepwear,
                        purchase_price = 0,
                        sale_price     = 0,
                        outfit_type    = (byte)VMPersonSuits.DefaultSleepwear,
                        outfit_source  = Database.DA.Outfits.DbOutfitSource.cas
                    });

                    db.Outfits.Create(new Database.DA.Outfits.DbOutfit
                    {
                        avatar_owner   = newId,
                        asset_id       = newAvatar.body_swimwear,
                        purchase_price = 0,
                        sale_price     = 0,
                        outfit_type    = (byte)VMPersonSuits.DefaultSwimwear,
                        outfit_source  = Database.DA.Outfits.DbOutfitSource.cas
                    });
                }
                catch (Exception e) {
                    session.Write(new CreateASimResponse
                    {
                        Status = CreateASimStatus.FAILED,
                        Reason = CreateASimFailureReason.NONE
                    });
                    return;
                }
            }

            ((VoltronSession)session).AvatarId = newId;

            session.Write(new CreateASimResponse {
                Status      = CreateASimStatus.SUCCESS,
                NewAvatarId = newId
            });
            session.Write(new TransmitCreateAvatarNotificationPDU {
            });
        }
Example #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));
            }
        }
Example #6
0
        private Avatar HydrateOne(DbAvatar dbAvatar, DbLot dbLot, List <DbJobLevel> levels, List <DbRelationship> rels, List <DbBookmark> bookmarks)
        {
            var result = new Avatar();

            result.Avatar_Id          = dbAvatar.avatar_id;
            result.Avatar_Name        = dbAvatar.name;
            result.Avatar_IsOnline    = false;
            result.Avatar_Description = dbAvatar.description;
            result.Avatar_Appearance  = new AvatarAppearance
            {
                AvatarAppearance_BodyOutfitID = dbAvatar.body,
                AvatarAppearance_HeadOutfitID = dbAvatar.head,
                AvatarAppearance_SkinTone     = dbAvatar.skin_tone
            };
            var now = Epoch.Now;

            result.FetchTime     = now;
            result.Avatar_Age    = (uint)((now - dbAvatar.date) / ((long)60 * 60 * 24));
            result.Avatar_Skills = new AvatarSkills
            {
                AvatarSkills_Body              = dbAvatar.skill_body,
                AvatarSkills_LockLv_Body       = dbAvatar.lock_body,
                AvatarSkills_Charisma          = dbAvatar.skill_charisma,
                AvatarSkills_LockLv_Charisma   = dbAvatar.lock_charisma,
                AvatarSkills_Cooking           = dbAvatar.skill_cooking,
                AvatarSkills_LockLv_Cooking    = dbAvatar.lock_cooking,
                AvatarSkills_Creativity        = dbAvatar.skill_creativity,
                AvatarSkills_LockLv_Creativity = dbAvatar.lock_creativity,
                AvatarSkills_Logic             = dbAvatar.skill_logic,
                AvatarSkills_LockLv_Logic      = dbAvatar.lock_logic,
                AvatarSkills_Mechanical        = dbAvatar.skill_mechanical,
                AvatarSkills_LockLv_Mechanical = dbAvatar.lock_mechanical
            };
            result.Avatar_PrivacyMode      = dbAvatar.privacy_mode;
            result.Avatar_SkillsLockPoints = (ushort)(20 + result.Avatar_Age / 7);

            var jobs = new List <JobLevel>();

            foreach (var level in levels)
            {
                jobs.Add(new JobLevel
                {
                    JobLevel_JobType       = level.job_type,
                    JobLevel_JobExperience = level.job_experience,
                    JobLevel_JobGrade      = level.job_level
                });
            }
            result.Avatar_JobLevelVec = ImmutableList.ToImmutableList(jobs);
            result.Avatar_CurrentJob  = dbAvatar.current_job;

            result.Avatar_Top100ListFilter = new Top100ListFilter()
            {
                Top100ListFilter_ResultsVec   = ImmutableList.Create <uint>(),
                Top100ListFilter_Top100ListID = 0,
            };

            var fvec = new Dictionary <Tuple <uint, bool>, Relationship>();

            foreach (var rel in rels)
            {
                bool outgoing = false;
                uint target   = 0;
                if (rel.from_id == dbAvatar.avatar_id)
                {
                    outgoing = true;
                    target   = rel.to_id;
                }
                else
                {
                    target = rel.from_id;
                }

                var          tuple  = new Tuple <uint, bool>(target, outgoing);
                Relationship relObj = null;
                if (!fvec.TryGetValue(tuple, out relObj))
                {
                    relObj = new Relationship
                    {
                        Relationship_IsOutgoing = outgoing,
                        Relationship_TargetID   = target,
                        Relationship_CommentID  = rel.comment_id ?? 0
                    };
                    fvec.Add(tuple, relObj);
                }

                if (rel.index == 0)
                {
                    relObj.Relationship_STR = (sbyte)rel.value;
                }
                else
                {
                    relObj.Relationship_LTR = (sbyte)rel.value;
                }
            }
            result.Avatar_FriendshipVec = ImmutableList.ToImmutableList(fvec.Values);

            if (dbLot != null)
            {
                result.Avatar_LotGridXY = dbLot.location;
            }

            result.Avatar_BookmarksVec = ImmutableList.ToImmutableList(bookmarks.Select(x =>
            {
                return(new Bookmark {
                    Bookmark_Type = x.type,
                    Bookmark_TargetID = x.target_id
                });
            }));

            return(result);
        }