public bool AttemptLoadRing() { //first let's try load our adjacent lots. int attempts = 0; var lotStr = LotPersist.lot_id.ToString("x8"); while (++attempts < Config.RingBufferSize) { LOG.Info("Checking ring " + attempts + " for lot with dbid = " + Context.DbId); try { var path = Path.Combine(Config.SimNFS, "Lots/" + lotStr + "/state_" + LotPersist.ring_backup_num.ToString() + ".fsov"); using (var file = new BinaryReader(File.OpenRead(path))) { var marshal = new VMMarshal(); marshal.Deserialize(file); if (LotPersist.move_flags > 0) { //must rotate lot to face its new road direction! var oldDir = ((VMTSOLotState)marshal.PlatformState).Size >> 16; var newDir = VMLotTerrainRestoreTools.PickRoadDir(Terrain.Roads[1, 1]); var rotate = new VMLotRotate(marshal); rotate.Rotate(((newDir - oldDir) + 4) % 4); } Lot.Load(marshal); CleanLot(); Lot.Reset(); } using (var db = DAFactory.Get()) db.Lots.UpdateRingBackup(LotPersist.lot_id, LotPersist.ring_backup_num); return(true); } catch (Exception e) { LOG.Info("Ring load failed with exception: " + e.ToString() + " for lot with dbid = " + Context.DbId); LotPersist.ring_backup_num--; if (LotPersist.ring_backup_num < 0) { LotPersist.ring_backup_num += (sbyte)Config.RingBufferSize; } } } LOG.Error("FAILED to load all backups for lot with dbid = " + Context.DbId + "! Forcing lot close"); var backupPath = Path.Combine(Config.SimNFS, "Lots/" + lotStr + "/failedRestore" + (DateTime.Now.ToBinary().ToString()) + "/"); Directory.CreateDirectory(backupPath); foreach (var file in Directory.EnumerateFiles(Path.Combine(Config.SimNFS, "Lots/" + lotStr + "/"))) { File.Copy(file, backupPath + Path.GetFileName(file)); } throw new Exception("failed to load lot!"); return(false); }
public override bool Execute(VM vm) { #if VM_DESYNC_DEBUG if (Trace != null) { vm.Trace.CompareFirstError(Trace); } #endif vm.Load(State); if (VM.UseWorld && vm.Context.Blueprint.SubWorlds.Count == 0) { VMLotTerrainRestoreTools.RestoreSurroundings(vm, vm.HollowAdj); } return(true); }
public override bool Execute(VM vm) { if (Traces != null && vm.Driver.DesyncTick != 0) { vm.Trace.CompareFirstError(Traces.FirstOrDefault(x => x.TickID == vm.Driver.DesyncTick)); } vm.Driver.DesyncTick = 0; if (!Run) { return(true); } if (vm.FSOVDoAsyncLoad) { vm.FSOVDoAsyncLoad = false; vm.FSOVAsyncLoading = true; Task.Run(() => { vm.FSOVClientJoin = (vm.Context.Architecture == null); vm.LoadAsync(State); if (VM.UseWorld && vm.Context.Blueprint.SubWorlds.Count == 0) { VMLotTerrainRestoreTools.RestoreSurroundings(vm, vm.HollowAdj); } GameThread.InUpdate(() => { vm.LoadComplete(); }); }); } else { vm.Load(State); if (VM.UseWorld && vm.Context.Blueprint.SubWorlds.Count == 0) { VMLotTerrainRestoreTools.RestoreSurroundings(vm, vm.HollowAdj); } } return(true); }
public void ResetVM() { LOG.Info("Resetting VM for lot with dbid = " + Context.DbId); VMGlobalLink = Kernel.Get <LotServerGlobalLink>(); VMDriver = new VMServerDriver(VMGlobalLink); VMDriver.OnTickBroadcast += TickBroadcast; VMDriver.OnDirectMessage += DirectMessage; VMDriver.OnDropClient += DropClient; Lot = new VM(new VMContext(null), VMDriver, new VMNullHeadlineProvider()); Lot.Init(); bool isNew = false; bool isMoved = (LotPersist.move_flags > 0); LoadAdj(); if (!JobLot && LotPersist.ring_backup_num > -1 && AttemptLoadRing()) { LOG.Info("Successfully loaded and cleaned fsov for dbid = " + Context.DbId); } else { isNew = true; BlueprintReset(); } Lot.TSOState.Terrain = Terrain; Lot.TSOState.Name = LotPersist.name; Lot.TSOState.OwnerID = LotPersist.owner_id; Lot.TSOState.Roommates = new HashSet <uint>(); Lot.TSOState.BuildRoommates = new HashSet <uint>(); Lot.TSOState.PropertyCategory = (byte)LotPersist.category; foreach (var roomie in LotRoommates) { if (roomie.is_pending > 0) { continue; } Lot.TSOState.Roommates.Add(roomie.avatar_id); if (roomie.permissions_level > 0) { Lot.TSOState.BuildRoommates.Add(roomie.avatar_id); } if (roomie.permissions_level > 1) { Lot.TSOState.OwnerID = roomie.avatar_id; } } var time = DateTime.UtcNow; var tsoTime = TSOTime.FromUTC(time); Lot.Context.UpdateTSOBuildableArea(); Lot.MyUID = uint.MaxValue - 1; if ((LotPersist.move_flags & 2) > 0) { isNew = true; } ReturnInvalidObjects(); if (!JobLot) { ReturnOOWObjects(); } if (isMoved || isNew) { VMLotTerrainRestoreTools.RestoreTerrain(Lot); } if (isNew) { VMLotTerrainRestoreTools.PopulateBlankTerrain(Lot); } Lot.Context.Clock.Hours = tsoTime.Item1; Lot.Context.Clock.Minutes = tsoTime.Item2; Lot.Context.UpdateTSOBuildableArea(); var entClone = new List <VMEntity>(Lot.Entities); foreach (var ent in entClone) { if (ent is VMGameObject) { ((VMGameObject)ent).Disabled &= ~VMGameObjectDisableFlags.TransactionIncomplete; ((VMGameObject)ent).DisableIfTSOCategoryWrong(Lot.Context); if (ent.GetFlag(VMEntityFlags.Occupied)) { ent.ResetData(); ent.Init(Lot.Context); //objects should not be occupied when we join the lot... } { ent.ExecuteEntryPoint(2, Lot.Context, true); } } } LotActive.Set(); ActiveYet = true; }
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; }