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); } }
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); } } } } }
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}"); } }
/// <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}"); } }
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 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); } }