예제 #1
0
 public override void Deserialize(BinaryReader reader)
 {
     base.Deserialize(reader);
     Version     = reader.ReadUInt16();
     AvatarState = new VMNetAvatarPersistState();
     AvatarState.Deserialize(reader);
 }
예제 #2
0
        public void MessageReceived(IoSession session, object message)
        {
            if (message is VMNetMessage)
            {
                GameThread.NextUpdate(x =>
                {
                    var nmsg = (VMNetMessage)message;
                    var cli  = (VMNetClient)session.GetAttribute('c');
                    if (cli.AvatarState == null)
                    {
                        //we're still waiting for the avatar state so the user can join
                        if (nmsg.Type == VMNetMessageType.AvatarData)
                        {
                            var state = new VMNetAvatarPersistState();
                            try
                            {
                                state.Deserialize(new System.IO.BinaryReader(new MemoryStream(nmsg.Data)));
                            }
                            catch (Exception)
                            {
                                return;
                            }
                            cli.PersistID   = state.PersistID;
                            cli.AvatarState = state;

                            OnConnect(cli);
                        }
                    }
                    else
                    {
                        OnMessage(cli, nmsg);
                    }
                });
            }
        }
예제 #3
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);
        }
예제 #4
0
        public void SaveAvatar(VMAvatar avatar)
        {
            var statevm = new VMNetAvatarPersistState();

            statevm.Save(avatar);
            foreach (var relsID in avatar.ChangedRels)
            {
                int i = 0;
                if (!avatar.MeToPersist.ContainsKey(relsID))
                {
                    continue;
                }
                var rels = avatar.MeToPersist[relsID];
                foreach (var value in rels)
                {
                    RelationshipsToSave.Add(new DbRelationship
                    {
                        from_id = avatar.PersistID,
                        to_id   = relsID,
                        index   = (uint)(i++),
                        value   = (int)value
                    });
                }
            }
            avatar.ChangedRels.Clear();
            var dbState = StateToDb(statevm);

            dbState.avatar_id = avatar.PersistID;
            var pid = avatar.PersistID;

            DbJobLevel jobLevel = null;

            if (dbState.current_job > 0)
            {
                VMTSOJobInfo info = null;
                ((VMTSOAvatarState)avatar.TSOState).JobInfo.TryGetValue((short)dbState.current_job, out info);
                if (info != null)
                {
                    jobLevel = new DbJobLevel()
                    {
                        avatar_id       = pid,
                        job_type        = dbState.current_job,
                        job_experience  = (ushort)info.Experience,
                        job_level       = (ushort)info.Level,
                        job_sickdays    = (ushort)info.SickDays,
                        job_statusflags = (ushort)info.StatusFlags
                    };
                }
            }

            Host.InBackground(() =>
            {
                using (var db = DAFactory.Get())
                {
                    db.Avatars.UpdateAvatarLotSave(pid, dbState);
                    if (jobLevel != null)
                    {
                        db.Avatars.UpdateAvatarJobLevel(jobLevel);
                    }
                }
            });
        }
예제 #5
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);
        }
예제 #6
0
        public void InitializeLot(string lotName, bool external)
        {
            if (lotName == "")
            {
                return;
            }
            var recording = lotName.ToLowerInvariant().EndsWith(".fsor");

            CleanupLastWorld();

            Content.Content.Get().Upgrades.LoadJSONTuning();

            if (FSOEnvironment.Enable3D)
            {
                var rc = new LotView.RC.WorldRC(GameFacade.GraphicsDevice);
                World = rc;
            }
            else
            {
                World = new World(GameFacade.GraphicsDevice);
            }
            World.Opacity = 1;
            GameFacade.Scenes.Add(World);

            var settings = GlobalSettings.Default;
            var myState  = new VMNetAvatarPersistState()
            {
                Name         = settings.LastUser,
                DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender),
                BodyOutfit   = settings.DebugBody,
                HeadOutfit   = settings.DebugHead,
                PersistID    = (uint)(new Random()).Next(),
                SkinTone     = (byte)settings.DebugSkin,
                Gender       = (short)(settings.DebugGender ? 0 : 1),
                Permissions  = SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
                //CustomGUID = 0x396CD3D1,
                Budget = 1000000,
            };

            if (recording)
            {
                var stream = new FileStream(lotName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                var rd     = new VMFSORDriver(stream);
                Driver = rd;
            }
            else if (external)
            {
                var cd = new VMClientDriver(ClientStateChange);
                SandCli             = new FSOSandboxClient();
                cd.OnClientCommand += (msg) => { SandCli.Write(new VMNetMessage(VMNetMessageType.Command, msg)); };
                cd.OnShutdown      += (reason) => SandCli.Disconnect();
                SandCli.OnMessage  += cd.ServerMessage;
                SandCli.Connect(lotName);
                Driver = cd;

                var dat = new MemoryStream();
                var str = new BinaryWriter(dat);
                myState.SerializeInto(str);
                var ava = new VMNetMessage(VMNetMessageType.AvatarData, dat.ToArray());
                dat.Close();
                SandCli.OnConnectComplete += () =>
                {
                    SandCli.Write(ava);
                };
            }
            else
            {
                var globalLink = new VMTSOGlobalLinkStub();
                globalLink.Database = new SimAntics.Engine.TSOGlobalLink.VMTSOStandaloneDatabase();
                var sd = new VMServerDriver(globalLink);
                SandServer = new FSOSandboxServer();

                Driver                   = sd;
                sd.OnDropClient         += SandServer.ForceDisconnect;
                sd.OnTickBroadcast      += SandServer.Broadcast;
                sd.OnDirectMessage      += SandServer.SendMessage;
                SandServer.OnConnect    += sd.ConnectClient;
                SandServer.OnDisconnect += sd.DisconnectClient;
                SandServer.OnMessage    += sd.HandleMessage;

                SandServer.Start((ushort)37564);
            }

            //Driver.OnClientCommand += VMSendCommand;
            //Driver.OnShutdown += VMShutdown;

            vm = new VM(new VMContext(World), Driver, new UIHeadlineRendererProvider());
            vm.ListenBHAVChanges();
            vm.Init();

            LotControl = new UILotControl(vm, World);
            this.AddAt(0, LotControl);

            var time    = DateTime.UtcNow;
            var tsoTime = TSOTime.FromUTC(time);

            vm.Context.Clock.Hours   = tsoTime.Item1;
            vm.Context.Clock.Minutes = tsoTime.Item2;
            if (m_ZoomLevel > 3)
            {
                World.Visible      = false;
                LotControl.Visible = false;
            }

            if (IDEHook.IDE != null)
            {
                IDEHook.IDE.StartIDE(vm);
            }

            vm.OnFullRefresh      += VMRefreshed;
            vm.OnChatEvent        += Vm_OnChatEvent;
            vm.OnEODMessage       += LotControl.EODs.OnEODMessage;
            vm.OnRequestLotSwitch += VMLotSwitch;
            vm.OnGenericVMEvent   += Vm_OnGenericVMEvent;

            if (!external && !recording)
            {
                if (!Downtown && ActiveFamily != null)
                {
                    ActiveFamily.SelectWholeFamily();
                    vm.TS1State.ActivateFamily(vm, ActiveFamily);
                }
                BlueprintReset(lotName);

                var experimentalTuning = new Common.Model.DynamicTuning(new List <Common.Model.DynTuningEntry> {
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 15, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 5, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 6, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 7, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 8, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "overfill", tuning_table = 255, tuning_index = 9, value = 200
                    },
                    new Common.Model.DynTuningEntry()
                    {
                        tuning_type = "feature", tuning_table = 0, tuning_index = 0, value = 1
                    },                                                                                                            //ts1/tso engine animation timings (1.2x faster)
                });
                vm.ForwardCommand(new VMNetTuningCmd {
                    Tuning = experimentalTuning
                });

                vm.TSOState.PropertyCategory = 255; //11 is community
                vm.TSOState.ActivateValidator(vm);
                vm.Context.Clock.Hours = 0;
                vm.TSOState.Size      &= unchecked ((int)0xFFFF0000);
                vm.TSOState.Size      |= (10) | (3 << 8);
                vm.Context.UpdateTSOBuildableArea();

                if (vm.GetGlobalValue(11) > -1)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int x = 0; x < 3; x++)
                        {
                            vm.TSOState.Terrain.Roads[x, y] = 0xF; //crossroads everywhere
                        }
                    }
                    VMLotTerrainRestoreTools.RestoreTerrain(vm);
                }

                var myClient = new VMNetClient
                {
                    PersistID   = myState.PersistID,
                    RemoteIP    = "local",
                    AvatarState = myState
                };

                var server = (VMServerDriver)Driver;
                server.ConnectClient(myClient);

                GameFacade.Cursor.SetCursor(CursorType.Normal);
                ZoomLevel = 1;
            }
            vm.MyUID  = myState.PersistID;
            ZoomLevel = 1;
        }
예제 #7
0
        public void InitializeLot(string lotName, bool external)
        {
            if (lotName == "")
            {
                return;
            }
            var recording = lotName.ToLowerInvariant().EndsWith(".fsor");

            CleanupLastWorld();

            if (FSOEnvironment.Enable3D)
            {
                var rc = new LotView.RC.WorldRC(GameFacade.GraphicsDevice);
                World = rc;
            }
            else
            {
                World = new World(GameFacade.GraphicsDevice);
            }
            World.Opacity = 1;
            GameFacade.Scenes.Add(World);

            var settings = GlobalSettings.Default;
            var myState  = new VMNetAvatarPersistState()
            {
                Name         = settings.LastUser,
                DefaultSuits = new VMAvatarDefaultSuits(settings.DebugGender),
                BodyOutfit   = settings.DebugBody,
                HeadOutfit   = settings.DebugHead,
                PersistID    = (uint)(new Random()).Next(),
                SkinTone     = (byte)settings.DebugSkin,
                Gender       = (short)(settings.DebugGender ? 0 : 1),
                Permissions  = SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
                Budget       = 1000000,
            };

            if (recording)
            {
                var stream = new FileStream(lotName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                var rd     = new VMFSORDriver(stream);
                Driver = rd;
            }
            else if (external)
            {
                var cd = new VMClientDriver(ClientStateChange);
                SandCli             = new FSOSandboxClient();
                cd.OnClientCommand += (msg) => { SandCli.Write(new VMNetMessage(VMNetMessageType.Command, msg)); };
                cd.OnShutdown      += (reason) => SandCli.Disconnect();
                SandCli.OnMessage  += cd.ServerMessage;
                SandCli.Connect(lotName);
                Driver = cd;

                var dat = new MemoryStream();
                var str = new BinaryWriter(dat);
                myState.SerializeInto(str);
                var ava = new VMNetMessage(VMNetMessageType.AvatarData, dat.ToArray());
                dat.Close();
                SandCli.OnConnectComplete += () =>
                {
                    SandCli.Write(ava);
                };
            }
            else
            {
                var globalLink = new VMTSOGlobalLinkStub();
                var sd         = new VMServerDriver(globalLink);
                SandServer = new FSOSandboxServer();

                Driver                   = sd;
                sd.OnDropClient         += SandServer.ForceDisconnect;
                sd.OnTickBroadcast      += SandServer.Broadcast;
                sd.OnDirectMessage      += SandServer.SendMessage;
                SandServer.OnConnect    += sd.ConnectClient;
                SandServer.OnDisconnect += sd.DisconnectClient;
                SandServer.OnMessage    += sd.HandleMessage;

                SandServer.Start((ushort)37564);
            }

            //Driver.OnClientCommand += VMSendCommand;
            //Driver.OnShutdown += VMShutdown;

            vm = new VM(new VMContext(World), Driver, new UIHeadlineRendererProvider());
            vm.ListenBHAVChanges();
            vm.Init();

            LotControl = new UILotControl(vm, World);
            this.AddAt(0, LotControl);

            var time    = DateTime.UtcNow;
            var tsoTime = TSOTime.FromUTC(time);

            vm.Context.Clock.Hours   = tsoTime.Item1;
            vm.Context.Clock.Minutes = tsoTime.Item2;
            if (m_ZoomLevel > 3)
            {
                World.Visible      = false;
                LotControl.Visible = false;
            }

            if (IDEHook.IDE != null)
            {
                IDEHook.IDE.StartIDE(vm);
            }

            vm.OnFullRefresh      += VMRefreshed;
            vm.OnChatEvent        += Vm_OnChatEvent;
            vm.OnEODMessage       += LotControl.EODs.OnEODMessage;
            vm.OnRequestLotSwitch += VMLotSwitch;
            vm.OnGenericVMEvent   += Vm_OnGenericVMEvent;

            if (!external && !recording)
            {
                if (!Downtown && ActiveFamily != null)
                {
                    ActiveFamily.SelectWholeFamily();
                    vm.ActivateFamily(ActiveFamily);
                }
                BlueprintReset(lotName);

                vm.TSOState.PropertyCategory = 255;
                vm.Context.Clock.Hours       = 0;
                vm.TSOState.Size             = (10) | (3 << 8);
                vm.Context.UpdateTSOBuildableArea();
                var myClient = new VMNetClient
                {
                    PersistID   = myState.PersistID,
                    RemoteIP    = "local",
                    AvatarState = myState
                };

                var server = (VMServerDriver)Driver;
                server.ConnectClient(myClient);

                GameFacade.Cursor.SetCursor(CursorType.Normal);
                ZoomLevel = 1;
            }
            vm.MyUID  = myState.PersistID;
            ZoomLevel = 1;
        }