private static void ReloadSection() { _displayReloads = GUILayout.Toggle(_displayReloads, "Reload vessels", ToggleButtonStyle); if (_displayReloads) { if (GUILayout.Button("Reload own vessel")) { if (FlightGlobals.ActiveVessel != null) { FlightGlobals.ActiveVessel.protoVessel = FlightGlobals.ActiveVessel.BackupVessel(); VesselLoader.LoadVessel(FlightGlobals.ActiveVessel.protoVessel); } } if (GUILayout.Button("Reload other vessels")) { var vessels = FlightGlobals.Vessels.Where(v => v != null).ToList(); if (FlightGlobals.ActiveVessel != null) { foreach (var vessel in vessels) { if (FlightGlobals.ActiveVessel.id == vessel.id) { continue; } vessel.protoVessel = vessel.BackupVessel(); VesselLoader.LoadVessel(vessel.protoVessel); } } } } }
public void ProcessVesselUpdate() { var vessel = FlightGlobals.fetch.LmpFindVessel(VesselId); if (vessel == null) { return; } if (!VesselCommon.DoVesselChecks(vessel.id)) { return; } var previousSituation = vessel.situation; var previousStage = vessel.currentStage; UpdateVesselFields(vessel); UpdateProtoVesselValues(vessel.protoVessel); //Reload the vessel when the situation changes and vessel is unloaded. //This will also fix the Landed and Splashed fields if (!vessel.loaded && previousSituation != (Vessel.Situations)Enum.Parse(typeof(Vessel.Situations), Situation)) { VesselLoader.LoadVessel(vessel.protoVessel); } //Trigger a reload when staging! if (previousStage != Stage) { VesselLoader.LoadVessel(vessel.protoVessel); } }
protected override void PrintDisplay() { GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUILayout.Label(VesselName); GUILayout.FlexibleSpace(); if (GUILayout.Button("Reload")) { var vessel = FlightGlobals.FindVessel(VesselId); //Do not call BackupVessel() as that would overwrite the proto with the actual vessel values and mess up part syncs VesselLoader.LoadVessel(vessel.protoVessel, true); } GUILayout.EndHorizontal(); Data.Display = GUILayout.Toggle(Data.Display, nameof(Data), ButtonStyle); Data.Print(); Locks.Display = GUILayout.Toggle(Locks.Display, nameof(Locks), ButtonStyle); Locks.Print(); Orbit.Display = GUILayout.Toggle(Orbit.Display, nameof(Orbit), ButtonStyle); Orbit.Print(); Interpolation.Display = GUILayout.Toggle(Interpolation.Display, nameof(Interpolation), ButtonStyle); Interpolation.Print(); Position.Display = GUILayout.Toggle(Position.Display, nameof(Position), ButtonStyle); Position.Print(); Vectors.Display = GUILayout.Toggle(Vectors.Display, nameof(Vectors), ButtonStyle); Vectors.Print(); GUILayout.EndVertical(); }
/// <summary> /// Triggered when the vessel parts change. /// CAUTION!: When staging this method can be called a lot of times! /// Also, this method is called when docking/undocking and when reloading a vessel /// </summary> public void VesselPartCountChanged(Vessel vessel) { if (vessel == null) { return; } //The vessel is being created by the loader if (VesselLoader.CurrentlyLoadingVesselId == vessel.id) { return; } //When a vessel docks it's part count changes but we must not relay it as it's handled by the vessel dock system if (CurrentDockEvent.DominantVesselId == vessel.id || CurrentUndockEvent.UndockingVesselId == vessel.id) { return; } //This event is called when the vessel is being created and we don't want to send protos of vessels we don't own or while our vessel is not 100% loaded (FlightReady) if (vessel.vesselSpawning) { return; } //Vessel is scheduled to be killed so ignore this if (VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id)) { return; } //We are spectating and the vessel has been modified so trigger a reload if (VesselCommon.IsSpectating && FlightGlobals.ActiveVessel && FlightGlobals.ActiveVessel.id == vessel.id && vessel.protoVessel.protoPartSnapshots.Count != FlightGlobals.ActiveVessel.Parts.Count) { VesselLoader.LoadVessel(vessel.protoVessel); return; } if (!LockSystem.LockQuery.UpdateLockExists(vessel.id)) { LockSystem.Singleton.AcquireUpdateLock(vessel.id, true); LockSystem.Singleton.AcquireUnloadedUpdateLock(vessel.id, true); VesselProtoSystem.Singleton.MessageSender.SendVesselMessage(vessel); } if (LockSystem.LockQuery.UpdateLockBelongsToPlayer(vessel.id, SettingsSystem.CurrentSettings.PlayerName)) { //This method can be called a lot of times during staging (for every part that decouples) //For this reason we wait 0.5 seconds so we send all the changes at once. if (QueuedVessels.Contains(vessel.id)) { return; } QueuedVessels.Add(vessel.id); CoroutineUtil.StartDelayedRoutine("QueueVesselMessageAsPartsChanged", () => QueueNewVesselChange(vessel), 0.5f); VesselProtoSystem.Singleton.MessageSender.SendVesselMessage(vessel); } }
/// <summary> /// Check vessels that must be loaded /// </summary> public void CheckVesselsToLoad() { if (HighLogic.LoadedScene < GameScenes.SPACECENTER) { return; } try { foreach (var keyVal in VesselProtos) { if (keyVal.Value.TryPeek(out var vesselProto) && vesselProto.GameTime <= TimeSyncSystem.UniversalTime) { keyVal.Value.TryDequeue(out _); if (VesselRemoveSystem.VesselWillBeKilled(vesselProto.VesselId)) { continue; } var forceReload = vesselProto.ForceReload; var protoVessel = vesselProto.CreateProtoVessel(); keyVal.Value.Recycle(vesselProto); if (protoVessel == null || protoVessel.HasInvalidParts(!VesselsUnableToLoad.Contains(vesselProto.VesselId))) { VesselsUnableToLoad.Add(vesselProto.VesselId); continue; } VesselsUnableToLoad.Remove(vesselProto.VesselId); var existingVessel = FlightGlobals.FindVessel(vesselProto.VesselId); if (existingVessel == null) { if (VesselLoader.LoadVessel(protoVessel, forceReload)) { LunaLog.Log($"[LMP]: Vessel {protoVessel.vesselID} loaded"); VesselLoadEvent.onLmpVesselLoaded.Fire(protoVessel.vesselRef); } } else { if (VesselLoader.LoadVessel(protoVessel, forceReload)) { LunaLog.Log($"[LMP]: Vessel {protoVessel.vesselID} reloaded"); VesselReloadEvent.onLmpVesselReloaded.Fire(protoVessel.vesselRef); } } } } } catch (Exception e) { LunaLog.LogError($"[LMP]: Error in CheckVesselsToLoad {e}"); } }
public void HandleMessage(IServerMessageBase msg) { if (!(msg.Data is VesselDockMsgData msgData)) { return; } LunaLog.Log("Docking message received!"); //Add the new vessel data to the store VesselsProtoStore.HandleVesselProtoData(msgData.FinalVesselData, msgData.NumBytes, msgData.DominantVesselId); if (FlightGlobals.ActiveVessel?.id == msgData.WeakVesselId) { LunaLog.Log($"Docking NOT detected. We DON'T OWN the dominant vessel. Switching to {msgData.DominantVesselId}"); SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(FlightGlobals.ActiveVessel.id); SystemsContainer.Get <VesselSwitcherSystem>().SwitchToVessel(msgData.DominantVesselId); WarpSystem.WarpIfSubspaceIsMoreAdvanced(msgData.SubspaceId); } if (FlightGlobals.ActiveVessel?.id == msgData.DominantVesselId && !VesselCommon.IsSpectating) { var newProto = VesselSerializer.DeserializeVessel(msgData.FinalVesselData, msgData.NumBytes); /* This is a strange case were we didn't detect the docking on time and the weak vessel send the new definition... * Usually it happens when a vessel in a future subspace docks with a vessel in the past and the vessel in the past is the dominant vessel * The reason why is bad is because the ModuleDockingNode sent by the WEAK vessel will tell us that we are * NOT the dominant (because we received the vesselproto from the WEAK vessel) so we won't be able to undock properly... * This will be fixed if we go to the space center and reload again the vessel... */ LunaLog.Log("Docking NOT detected. We OWN the dominant vessel"); if (FlightGlobals.FindVessel(msgData.WeakVesselId) != null) { LunaLog.Log($"Weak vessel {msgData.WeakVesselId} still exists in our game. Removing it now"); SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(msgData.WeakVesselId); SystemsContainer.Get <VesselRemoveSystem>().KillVessel(msgData.WeakVesselId); } /* We own the dominant vessel and dind't detected the docking event so we need to reload our OWN vessel * so if we send our own protovessel later, we send the updated definition */ LunaLog.Log($"Creating the missing parts in our own vessel. Current: {FlightGlobals.ActiveVessel.parts.Count} Expected: {newProto.protoPartSnapshots.Count}"); //ProtoToVesselRefresh.CreateMissingPartsInCurrentProtoVessel(FlightGlobals.ActiveVessel, newProto); VesselLoader.ReloadVessel(newProto); LunaLog.Log("Force sending the new proto vessel"); SystemsContainer.Get <VesselProtoSystem>().MessageSender.SendVesselMessage(FlightGlobals.ActiveVessel, true); WarpSystem.WarpIfSubspaceIsMoreAdvanced(msgData.SubspaceId); return; } //Some other 2 players docked so just remove the weak vessel. SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(msgData.WeakVesselId); }
/// <summary> /// Check vessels that must be loaded /// </summary> private void CheckVesselsToLoad() { if (HighLogic.LoadedScene < GameScenes.SPACECENTER) { return; } try { foreach (var keyVal in VesselProtos) { if (keyVal.Value.TryPeek(out var vesselProto) && vesselProto.GameTime <= TimeSyncSystem.UniversalTime) { keyVal.Value.TryDequeue(out _); if (VesselRemoveSystem.VesselWillBeKilled(vesselProto.VesselId)) { continue; } var protoVessel = vesselProto.CreateProtoVessel(); keyVal.Value.Recycle(vesselProto); if (protoVessel == null) { return; } var existingVessel = FlightGlobals.fetch.LmpFindVessel(vesselProto.VesselId); if (existingVessel == null) { LunaLog.Log($"[LMP]: Loading vessel {vesselProto.VesselId}"); if (VesselLoader.LoadVessel(protoVessel)) { LunaLog.Log($"[LMP]: Vessel {protoVessel.vesselID} loaded"); VesselLoadEvent.onLmpVesselLoaded.Fire(protoVessel.vesselRef); } } else { LunaLog.Log($"[LMP]: Reloading vessel {vesselProto.VesselId}"); if (VesselLoader.LoadVessel(protoVessel)) { LunaLog.Log($"[LMP]: Vessel {protoVessel.vesselID} reloaded"); VesselReloadEvent.onLmpVesselReloaded.Fire(protoVessel.vesselRef); } } } } } catch (Exception e) { LunaLog.LogError($"[LMP]: Error in CheckVesselsToLoad {e}"); } }
public void DrawContent(int windowId) { GUILayout.BeginVertical(); GUI.DragWindow(MoveRect); DisplayFast = GUILayout.Toggle(DisplayFast, "Fast debug update", ButtonStyle); DisplayVectors = GUILayout.Toggle(DisplayVectors, "Display vessel vectors", ButtonStyle); if (DisplayVectors) { GUILayout.Label(VectorText, LabelStyle); } DisplayOrbit = GUILayout.Toggle(DisplayOrbit, "Display orbit info", ButtonStyle); if (DisplayOrbit) { GUILayout.Label(OrbitText, LabelStyle); } DisplayVesselStoreData = GUILayout.Toggle(DisplayVesselStoreData, "Display vessel store data", ButtonStyle); if (DisplayVesselStoreData) { GUILayout.Label(VesselStoreText, LabelStyle); } DisplayNtp = GUILayout.Toggle(DisplayNtp, "Display NTP/Subspace statistics", ButtonStyle); if (DisplayNtp) { GUILayout.Label(NtpText, LabelStyle); } DisplayConnectionQueue = GUILayout.Toggle(DisplayConnectionQueue, "Display connection statistics", ButtonStyle); if (DisplayConnectionQueue) { GUILayout.Label(ConnectionText, LabelStyle); } if (GUILayout.Button("Reload all vessels", ButtonStyle)) { var protos = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.ProtoVessel); foreach (var proto in protos) { VesselLoader.ReloadVessel(proto); } } GUILayout.EndVertical(); }
private static void HandleLoad(QuicksaveLoadReplyMsgData data) { // Make sure that the quicksave corresponds to current vessel if (data.QuicksaveInfo.VesselId != FlightGlobals.ActiveVessel.id) { LunaScreenMsg.PostScreenMessage("Got quicksave for wrong vessel!", 5, ScreenMessageStyle.UPPER_CENTER); LunaLog.LogError( $"[LMP]: Got quicksave for wrong vessel. Got id: {data.QuicksaveInfo.VesselId}. Current vessel id: {FlightGlobals.ActiveVessel.id}"); return; } // Construct the ProtoVessel using the loaded byte data var vesselProto = new VesselProto { GameTime = data.QuicksaveInfo.GameTime, VesselId = data.QuicksaveInfo.VesselId, NumBytes = data.QuicksaveInfo.NumBytes, ForceReload = true, RawData = new byte[data.QuicksaveInfo.NumBytes] }; Array.Copy(data.QuicksaveInfo.Data, vesselProto.RawData, data.QuicksaveInfo.NumBytes); var protoVessel = vesselProto.CreateProtoVessel(); // Try to reload the vessel if (VesselLoader.LoadVessel(protoVessel, true)) { // Create a new subspace with the loaded vessel's time TimeSyncSystem.Singleton.SetGameTime(protoVessel.launchTime + protoVessel.missionTime); WarpSystem.Singleton.WaitingSubspaceIdFromServer = true; WarpSystem.Singleton.MessageSender.SendNewSubspace(); LunaScreenMsg.PostScreenMessage($"Loaded {data.QuicksaveInfo.Name}!", 5, ScreenMessageStyle.UPPER_CENTER); } else { LunaScreenMsg.PostScreenMessage("Could not load quicksave!", 5, ScreenMessageStyle.UPPER_CENTER); LunaLog.LogError( $"[LMP]: Could not load quicksave {data.QuicksaveInfo.Name} for {data.QuicksaveInfo.VesselId}"); } }
public void DisplaySavedVessels() { DirectoryInfo directoryInfo = new DirectoryInfo(SaveSystem.SESSION_SAVE_DIRECTORY); FileInfo[] saveFiles = directoryInfo.GetFiles("*.rekt"); Utility.DestroyChildObjects(_layout.transform); foreach (FileInfo fileInfo in saveFiles) { if (fileInfo != null) { string saveString = File.ReadAllText(fileInfo.FullName); VesselLoader vessel = Instantiate(_vesselLoaderPrefab, _layout.transform); SessionDataContainer data = JsonUtility.FromJson <SessionDataContainer>(saveString); vessel.vesselName.text = data.VesselName; } } }
public void HandleMessage(IServerMessageBase msg) { if (!(msg.Data is VesselDockMsgData msgData)) { return; } LunaLog.Log("Docking message received!"); if (msgData.WeakVesselId == CurrentDockEvent.WeakVesselId && msgData.DominantVesselId == CurrentDockEvent.DominantVesselId && (LunaNetworkTime.UtcNow - CurrentDockEvent.DockingTime) < TimeSpan.FromSeconds(5)) { LunaLog.Log("Docking message received was detected so ignore it"); return; } var dominantProto = VesselSerializer.DeserializeVessel(msgData.FinalVesselData, msgData.NumBytes); VesselLoader.LoadVessel(dominantProto); WarpSystem.WarpIfSubspaceIsMoreAdvanced(msgData.SubspaceId); if (FlightGlobals.ActiveVessel && FlightGlobals.ActiveVessel.id == msgData.WeakVesselId) { LunaLog.Log($"Docking NOT detected. We DON'T OWN the dominant vessel. Switching to {msgData.DominantVesselId}"); if (dominantProto.vesselRef != null) { dominantProto.vesselRef.Load(); dominantProto.vesselRef.GoOffRails(); FlightGlobals.ForceSetActiveVessel(dominantProto.vesselRef); } } else if (FlightGlobals.ActiveVessel && FlightGlobals.ActiveVessel.id == msgData.DominantVesselId) { LunaLog.Log("Docking NOT detected. We OWN the dominant vessel"); } VesselRemoveSystem.Singleton.KillVessel(msgData.WeakVesselId, "Killing weak (active) vessel during a docking that was not detected"); CurrentDockEvent.Reset(); }
public void ProcessVesselUpdate() { var vessel = FlightGlobals.fetch.LmpFindVessel(VesselId); if (vessel == null) { return; } if (!VesselCommon.DoVesselChecks(vessel.id)) { return; } var previousStage = vessel.currentStage; UpdateVesselFields(vessel); UpdateProtoVesselValues(vessel.protoVessel); if (vessel.orbitDriver && !vessel.loaded) { if (vessel.situation < Vessel.Situations.FLYING && vessel.orbitDriver.updateMode != OrbitDriver.UpdateMode.IDLE) { vessel.orbitDriver.SetOrbitMode(OrbitDriver.UpdateMode.IDLE); } else if (vessel.situation >= Vessel.Situations.FLYING && vessel.orbitDriver.updateMode != OrbitDriver.UpdateMode.UPDATE) { vessel.orbitDriver.SetOrbitMode(OrbitDriver.UpdateMode.UPDATE); } } //Trigger a reload when staging! if (previousStage != Stage) { VesselLoader.LoadVessel(vessel.protoVessel); } }
private void ReloadSection() { _displayReloads = GUILayout.Toggle(_displayReloads, "Reload vessels", ButtonStyle); if (_displayReloads) { if (GUILayout.Button("Reload own vessel", ButtonStyle)) { VesselLoader.ReloadVessel(FlightGlobals.ActiveVessel?.protoVessel); } if (GUILayout.Button("Reload other vessels", ButtonStyle)) { var protos = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.ProtoVessel); foreach (var proto in protos) { if (FlightGlobals.ActiveVessel?.id == proto.vesselID) { continue; } VesselLoader.ReloadVessel(proto); } } } }
public void DrawContent(int windowId) { GUILayout.BeginVertical(); GUI.DragWindow(MoveRect); DisplayFast = GUILayout.Toggle(DisplayFast, "Fast debug update", ButtonStyle); DisplayVectors = GUILayout.Toggle(DisplayVectors, "Display vessel vectors", ButtonStyle); if (DisplayVectors) { GUILayout.Label(VectorText, LabelStyle); } DisplayOrbit = GUILayout.Toggle(DisplayOrbit, "Display orbit info", ButtonStyle); if (DisplayOrbit) { GUILayout.Label(OrbitText, LabelStyle); } DisplayVesselStoreData = GUILayout.Toggle(DisplayVesselStoreData, "Display vessel store data", ButtonStyle); if (DisplayVesselStoreData) { GUILayout.Label(VesselStoreText, LabelStyle); } DisplayNtp = GUILayout.Toggle(DisplayNtp, "Display NTP/Subspace statistics", ButtonStyle); if (DisplayNtp) { GUILayout.Label(NtpText, LabelStyle); } DisplayConnectionQueue = GUILayout.Toggle(DisplayConnectionQueue, "Display connection statistics", ButtonStyle); if (DisplayConnectionQueue) { GUILayout.Label(ConnectionText, LabelStyle); } if (GUILayout.Button("Reload all vessels", ButtonStyle)) { var protos = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.ProtoVessel); foreach (var proto in protos) { if (FlightGlobals.ActiveVessel?.id == proto.vesselID) { continue; } VesselLoader.ReloadVessel(proto); } } if (GUILayout.Button("Pack all vessels", ButtonStyle)) { var vessels = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.Vessel).Where(v => v != null); foreach (var vessel in vessels) { if (FlightGlobals.ActiveVessel?.id == vessel.id) { continue; } vessel.vesselRanges = DebugUtils.PackRanges; } } if (GUILayout.Button("Unpack all vessels", ButtonStyle)) { var vessels = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.Vessel).Where(v => v != null); foreach (var vessel in vessels) { if (FlightGlobals.ActiveVessel?.id == vessel.id) { continue; } vessel.vesselRanges = DebugUtils.UnPackRanges; } } if (GUILayout.Button("Reset ranges", ButtonStyle)) { var vessels = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.Vessel).Where(v => v != null); foreach (var vessel in vessels) { if (FlightGlobals.ActiveVessel?.id == vessel.id) { continue; } vessel.vesselRanges = PhysicsGlobals.Instance.VesselRangesDefault; } } GUILayout.EndVertical(); }
public override void DrawWindowContent(int windowId) { GUILayout.BeginVertical(); GUI.DragWindow(MoveRect); var newVal = GUILayout.Toggle(_saveCurrentOrbitData, "Save orbit data to file", ButtonStyle); if (newVal != _saveCurrentOrbitData) { _saveCurrentOrbitData = newVal; if (newVal) { CreateNewOrbitDataFile(); } } if (GUILayout.Button("Force time sync", ButtonStyle)) { TimeSyncerSystem.Singleton.ForceTimeSync(); } if (GUILayout.Button("Reload own vessel", ButtonStyle)) { VesselLoader.ReloadVessel(FlightGlobals.ActiveVessel?.protoVessel); } if (GUILayout.Button("Reload other vessels", ButtonStyle)) { var protos = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.ProtoVessel); foreach (var proto in protos) { if (FlightGlobals.ActiveVessel?.id == proto.vesselID) { continue; } VesselLoader.ReloadVessel(proto); } } if (GUILayout.Button("Pack all vessels", ButtonStyle)) { var vessels = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.Vessel).Where(v => v != null); foreach (var vessel in vessels) { if (FlightGlobals.ActiveVessel?.id == vessel.id) { continue; } vessel.vesselRanges = ToolsUtils.PackRanges; } } if (GUILayout.Button("Unpack all vessels", ButtonStyle)) { var vessels = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.Vessel).Where(v => v != null); foreach (var vessel in vessels) { if (FlightGlobals.ActiveVessel?.id == vessel.id) { continue; } vessel.vesselRanges = ToolsUtils.UnPackRanges; } } if (GUILayout.Button("Reset ranges", ButtonStyle)) { var vessels = VesselsProtoStore.AllPlayerVessels.Values.Select(v => v.Vessel).Where(v => v != null); foreach (var vessel in vessels) { if (FlightGlobals.ActiveVessel?.id == vessel.id) { continue; } vessel.vesselRanges = PhysicsGlobals.Instance.VesselRangesDefault; } } GUILayout.EndVertical(); }